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 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 current_program_(0), | 441 current_program_(0), |
441 bound_array_buffer_id_(0), | 442 bound_array_buffer_id_(0), |
442 bound_element_array_buffer_id_(0), | 443 bound_element_array_buffer_id_(0), |
444 bound_pixel_unpack_transfer_buffer_id_(0), | |
443 client_side_array_id_(0), | 445 client_side_array_id_(0), |
444 client_side_element_array_id_(0), | 446 client_side_element_array_id_(0), |
445 bound_vertex_array_id_(0), | 447 bound_vertex_array_id_(0), |
446 error_bits_(0), | 448 error_bits_(0), |
447 debug_(false), | 449 debug_(false), |
448 use_count_(0), | 450 use_count_(0), |
449 current_query_(NULL), | 451 current_query_(NULL), |
450 error_message_callback_(NULL) { | 452 error_message_callback_(NULL) { |
451 GPU_DCHECK(helper); | 453 GPU_DCHECK(helper); |
452 GPU_DCHECK(transfer_buffer); | 454 GPU_DCHECK(transfer_buffer); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
510 util_.set_num_compressed_texture_formats( | 512 util_.set_num_compressed_texture_formats( |
511 static_state_.int_state.num_compressed_texture_formats); | 513 static_state_.int_state.num_compressed_texture_formats); |
512 util_.set_num_shader_binary_formats( | 514 util_.set_num_shader_binary_formats( |
513 static_state_.int_state.num_shader_binary_formats); | 515 static_state_.int_state.num_shader_binary_formats); |
514 | 516 |
515 texture_units_.reset( | 517 texture_units_.reset( |
516 new TextureUnit[ | 518 new TextureUnit[ |
517 static_state_.int_state.max_combined_texture_image_units]); | 519 static_state_.int_state.max_combined_texture_image_units]); |
518 | 520 |
519 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 521 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
522 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); | |
520 | 523 |
521 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 524 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
522 GetIdHandler(id_namespaces::kBuffers)->MakeIds( | 525 GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
523 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); | 526 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); |
524 | 527 |
525 client_side_buffer_helper_.reset(new ClientSideBufferHelper( | 528 client_side_buffer_helper_.reset(new ClientSideBufferHelper( |
526 static_state_.int_state.max_vertex_attribs, | 529 static_state_.int_state.max_vertex_attribs, |
527 reserved_ids_[0], | 530 reserved_ids_[0], |
528 reserved_ids_[1])); | 531 reserved_ids_[1])); |
529 #endif | 532 #endif |
530 | 533 |
531 return true; | 534 return true; |
532 } | 535 } |
533 | 536 |
534 GLES2Implementation::~GLES2Implementation() { | 537 GLES2Implementation::~GLES2Implementation() { |
535 // Make sure the queries are finished otherwise we'll delete the | 538 // Make sure the queries are finished otherwise we'll delete the |
536 // shared memory (mapped_memory_) which will free the memory used | 539 // shared memory (mapped_memory_) which will free the memory used |
537 // by the queries. The GPU process when validating that memory is still | 540 // by the queries. The GPU process when validating that memory is still |
538 // shared will fail and abort (ie, it will stop running). | 541 // shared will fail and abort (ie, it will stop running). |
539 Finish(); | 542 Finish(); |
540 query_tracker_.reset(); | 543 query_tracker_.reset(); |
541 | 544 |
542 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 545 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
543 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); | 546 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); |
544 #endif | 547 #endif |
548 buffer_tracker_.reset(); | |
549 | |
545 // The share group needs to be able to use a command buffer to talk | 550 // The share group needs to be able to use a command buffer to talk |
546 // to service if it's destroyed so set one for it then release the reference. | 551 // to service if it's destroyed so set one for it then release the reference. |
547 // If it's destroyed it will use this GLES2Implemenation. | 552 // If it's destroyed it will use this GLES2Implemenation. |
548 share_group_->SetGLES2ImplementationForDestruction(this); | 553 share_group_->SetGLES2ImplementationForDestruction(this); |
549 share_group_ = NULL; | 554 share_group_ = NULL; |
550 // Make sure the commands make it the service. | 555 // Make sure the commands make it the service. |
551 Finish(); | 556 Finish(); |
552 } | 557 } |
553 | 558 |
554 GLES2CmdHelper* GLES2Implementation::helper() const { | 559 GLES2CmdHelper* GLES2Implementation::helper() const { |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
896 *params = bound_array_buffer_id_; | 901 *params = bound_array_buffer_id_; |
897 return true; | 902 return true; |
898 } | 903 } |
899 return false; | 904 return false; |
900 case GL_ELEMENT_ARRAY_BUFFER_BINDING: | 905 case GL_ELEMENT_ARRAY_BUFFER_BINDING: |
901 if (share_group_->bind_generates_resource()) { | 906 if (share_group_->bind_generates_resource()) { |
902 *params = bound_element_array_buffer_id_; | 907 *params = bound_element_array_buffer_id_; |
903 return true; | 908 return true; |
904 } | 909 } |
905 return false; | 910 return false; |
911 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: | |
912 *params = bound_pixel_unpack_transfer_buffer_id_; | |
913 return true; | |
906 case GL_ACTIVE_TEXTURE: | 914 case GL_ACTIVE_TEXTURE: |
907 *params = active_texture_unit_ + GL_TEXTURE0; | 915 *params = active_texture_unit_ + GL_TEXTURE0; |
908 return true; | 916 return true; |
909 case GL_TEXTURE_BINDING_2D: | 917 case GL_TEXTURE_BINDING_2D: |
910 if (share_group_->bind_generates_resource()) { | 918 if (share_group_->bind_generates_resource()) { |
911 *params = texture_units_[active_texture_unit_].bound_texture_2d; | 919 *params = texture_units_[active_texture_unit_].bound_texture_2d; |
912 return true; | 920 return true; |
913 } | 921 } |
914 return false; | 922 return false; |
915 case GL_TEXTURE_BINDING_CUBE_MAP: | 923 case GL_TEXTURE_BINDING_CUBE_MAP: |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1560 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { | 1568 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { |
1561 if (size == 0) { | 1569 if (size == 0) { |
1562 return; | 1570 return; |
1563 } | 1571 } |
1564 | 1572 |
1565 if (size < 0) { | 1573 if (size < 0) { |
1566 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); | 1574 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); |
1567 return; | 1575 return; |
1568 } | 1576 } |
1569 | 1577 |
1578 if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | |
1579 GLuint buffer_id = bound_pixel_unpack_transfer_buffer_id_; | |
1580 if (!buffer_id) { | |
1581 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); | |
1582 return; | |
1583 } | |
1584 | |
1585 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | |
1586 if (buffer) { | |
1587 // Free buffer memory, pending the passage of a token. | |
1588 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | |
1589 | |
1590 // Remove old buffer. | |
1591 buffer_tracker_->RemoveBuffer(buffer_id); | |
1592 } | |
1593 | |
1594 // Create new buffer. | |
1595 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); | |
1596 GPU_DCHECK(buffer); | |
1597 if (data) | |
1598 memcpy(buffer->address(), data, size); | |
1599 return; | |
1600 } | |
1601 | |
1570 // If there is no data just send BufferData | 1602 // If there is no data just send BufferData |
1571 if (!data) { | 1603 if (!data) { |
1572 helper_->BufferData(target, size, 0, 0, usage); | 1604 helper_->BufferData(target, size, 0, 0, usage); |
1573 return; | 1605 return; |
1574 } | 1606 } |
1575 | 1607 |
1576 // See if we can send all at once. | 1608 // See if we can send all at once. |
1577 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); | 1609 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
1578 if (!buffer.valid()) { | 1610 if (!buffer.valid()) { |
1579 return; | 1611 return; |
(...skipping 30 matching lines...) Expand all Loading... | |
1610 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1642 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
1611 if (size == 0) { | 1643 if (size == 0) { |
1612 return; | 1644 return; |
1613 } | 1645 } |
1614 | 1646 |
1615 if (size < 0) { | 1647 if (size < 0) { |
1616 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "size < 0"); | 1648 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "size < 0"); |
1617 return; | 1649 return; |
1618 } | 1650 } |
1619 | 1651 |
1652 if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | |
1653 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | |
1654 bound_pixel_unpack_transfer_buffer_id_); | |
1655 if (!buffer) { | |
1656 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer"); | |
1657 return; | |
1658 } | |
1659 | |
1660 int32 end = 0; | |
1661 int32 buffer_size = buffer->size(); | |
1662 if (!SafeAddInt32(offset, size, &end) || end > buffer_size) { | |
greggman
2012/11/20 18:57:42
technically you don't need safeadd on the renderer
reveman
2012/11/20 23:24:30
Ok, makes sense.
| |
1663 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); | |
1664 return; | |
1665 } | |
1666 | |
1667 if (data) | |
1668 memcpy(static_cast<uint8_t*>(buffer->address()) + offset, data, size); | |
1669 return; | |
1670 } | |
1671 | |
1620 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); | 1672 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
1621 BufferSubDataHelperImpl(target, offset, size, data, &buffer); | 1673 BufferSubDataHelperImpl(target, offset, size, data, &buffer); |
1622 } | 1674 } |
1623 | 1675 |
1624 void GLES2Implementation::BufferSubDataHelperImpl( | 1676 void GLES2Implementation::BufferSubDataHelperImpl( |
1625 GLenum target, GLintptr offset, GLsizeiptr size, const void* data, | 1677 GLenum target, GLintptr offset, GLsizeiptr size, const void* data, |
1626 ScopedTransferBufferPtr* buffer) { | 1678 ScopedTransferBufferPtr* buffer) { |
1627 GPU_DCHECK(buffer); | 1679 GPU_DCHECK(buffer); |
1628 GPU_DCHECK_GT(size, 0); | 1680 GPU_DCHECK_GT(size, 0); |
1629 | 1681 |
(...skipping 18 matching lines...) Expand all Loading... | |
1648 void GLES2Implementation::BufferSubData( | 1700 void GLES2Implementation::BufferSubData( |
1649 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1701 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
1650 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1702 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1651 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" | 1703 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" |
1652 << GLES2Util::GetStringBufferTarget(target) << ", " | 1704 << GLES2Util::GetStringBufferTarget(target) << ", " |
1653 << offset << ", " << size << ", " | 1705 << offset << ", " << size << ", " |
1654 << static_cast<const void*>(data) << ")"); | 1706 << static_cast<const void*>(data) << ")"); |
1655 BufferSubDataHelper(target, offset, size, data); | 1707 BufferSubDataHelper(target, offset, size, data); |
1656 } | 1708 } |
1657 | 1709 |
1710 BufferTracker::Buffer* | |
1711 GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid( | |
1712 const char* function_name, GLuint offset, GLsizei size) | |
1713 { | |
1714 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | |
1715 bound_pixel_unpack_transfer_buffer_id_); | |
1716 if (!buffer) { | |
1717 SetGLError(GL_INVALID_VALUE, function_name, "invalid buffer"); | |
greggman
2012/11/20 18:57:42
INVALID_OPERATION
reveman
2012/11/20 23:24:30
Done.
| |
1718 return NULL; | |
1719 } | |
1720 if (buffer->mapped()) { | |
1721 SetGLError(GL_INVALID_VALUE, function_name, "buffer mapped"); | |
greggman
2012/11/20 18:57:42
GL_INVALID_OPERATION
reveman
2012/11/20 23:24:30
Done.
| |
1722 return NULL; | |
1723 } | |
1724 if ((buffer->size() - offset) < static_cast<GLuint>(size)) { | |
1725 SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large"); | |
1726 return NULL; | |
1727 } | |
1728 return buffer; | |
1729 } | |
1730 | |
1658 void GLES2Implementation::CompressedTexImage2D( | 1731 void GLES2Implementation::CompressedTexImage2D( |
1659 GLenum target, GLint level, GLenum internalformat, GLsizei width, | 1732 GLenum target, GLint level, GLenum internalformat, GLsizei width, |
1660 GLsizei height, GLint border, GLsizei image_size, const void* data) { | 1733 GLsizei height, GLint border, GLsizei image_size, const void* data) { |
1661 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1734 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1662 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexImage2D(" | 1735 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexImage2D(" |
1663 << GLES2Util::GetStringTextureTarget(target) << ", " | 1736 << GLES2Util::GetStringTextureTarget(target) << ", " |
1664 << level << ", " | 1737 << level << ", " |
1665 << GLES2Util::GetStringCompressedTextureFormat(internalformat) << ", " | 1738 << GLES2Util::GetStringCompressedTextureFormat(internalformat) << ", " |
1666 << width << ", " << height << ", " << border << ", " | 1739 << width << ", " << height << ", " << border << ", " |
1667 << image_size << ", " | 1740 << image_size << ", " |
1668 << static_cast<const void*>(data) << ")"); | 1741 << static_cast<const void*>(data) << ")"); |
1669 if (width < 0 || height < 0 || level < 0) { | 1742 if (width < 0 || height < 0 || level < 0) { |
1670 SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "dimension < 0"); | 1743 SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "dimension < 0"); |
1671 return; | 1744 return; |
1672 } | 1745 } |
1673 if (height == 0 || width == 0) { | 1746 if (height == 0 || width == 0) { |
1674 return; | 1747 return; |
1675 } | 1748 } |
1749 // If there's a pixel unpack buffer bound use it when issuing | |
1750 // CompressedTexImage2D. | |
1751 if (bound_pixel_unpack_transfer_buffer_id_) { | |
1752 GLuint offset = ToGLuint(data); | |
1753 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | |
1754 "glCompressedTexImage2D", offset, image_size); | |
1755 if (buffer) | |
1756 helper_->CompressedTexImage2D( | |
1757 target, level, internalformat, width, height, border, image_size, | |
1758 buffer->shm_id(), buffer->shm_offset() + offset); | |
1759 return; | |
1760 } | |
1676 SetBucketContents(kResultBucketId, data, image_size); | 1761 SetBucketContents(kResultBucketId, data, image_size); |
1677 helper_->CompressedTexImage2DBucket( | 1762 helper_->CompressedTexImage2DBucket( |
1678 target, level, internalformat, width, height, border, kResultBucketId); | 1763 target, level, internalformat, width, height, border, kResultBucketId); |
1679 // Free the bucket. This is not required but it does free up the memory. | 1764 // Free the bucket. This is not required but it does free up the memory. |
1680 // and we don't have to wait for the result so from the client's perspective | 1765 // and we don't have to wait for the result so from the client's perspective |
1681 // it's cheap. | 1766 // it's cheap. |
1682 helper_->SetBucketSize(kResultBucketId, 0); | 1767 helper_->SetBucketSize(kResultBucketId, 0); |
1683 } | 1768 } |
1684 | 1769 |
1685 void GLES2Implementation::CompressedTexSubImage2D( | 1770 void GLES2Implementation::CompressedTexSubImage2D( |
1686 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 1771 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
1687 GLsizei height, GLenum format, GLsizei image_size, const void* data) { | 1772 GLsizei height, GLenum format, GLsizei image_size, const void* data) { |
1688 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1773 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1689 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexSubImage2D(" | 1774 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexSubImage2D(" |
1690 << GLES2Util::GetStringTextureTarget(target) << ", " | 1775 << GLES2Util::GetStringTextureTarget(target) << ", " |
1691 << level << ", " | 1776 << level << ", " |
1692 << xoffset << ", " << yoffset << ", " | 1777 << xoffset << ", " << yoffset << ", " |
1693 << width << ", " << height << ", " | 1778 << width << ", " << height << ", " |
1694 << GLES2Util::GetStringCompressedTextureFormat(format) << ", " | 1779 << GLES2Util::GetStringCompressedTextureFormat(format) << ", " |
1695 << image_size << ", " | 1780 << image_size << ", " |
1696 << static_cast<const void*>(data) << ")"); | 1781 << static_cast<const void*>(data) << ")"); |
1697 if (width < 0 || height < 0 || level < 0) { | 1782 if (width < 0 || height < 0 || level < 0) { |
1698 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); | 1783 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); |
1699 return; | 1784 return; |
1700 } | 1785 } |
1786 // If there's a pixel unpack buffer bound use it when issuing | |
1787 // CompressedTexSubImage2D. | |
1788 if (bound_pixel_unpack_transfer_buffer_id_) { | |
1789 GLuint offset = ToGLuint(data); | |
1790 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | |
1791 "glCompressedTexSubImage2D", offset, image_size); | |
1792 if (buffer) | |
1793 helper_->CompressedTexSubImage2D( | |
1794 target, level, xoffset, yoffset, width, height, format, image_size, | |
1795 buffer->shm_id(), buffer->shm_offset() + offset); | |
1796 return; | |
1797 } | |
1701 SetBucketContents(kResultBucketId, data, image_size); | 1798 SetBucketContents(kResultBucketId, data, image_size); |
1702 helper_->CompressedTexSubImage2DBucket( | 1799 helper_->CompressedTexSubImage2DBucket( |
1703 target, level, xoffset, yoffset, width, height, format, kResultBucketId); | 1800 target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
1704 // Free the bucket. This is not required but it does free up the memory. | 1801 // Free the bucket. This is not required but it does free up the memory. |
1705 // and we don't have to wait for the result so from the client's perspective | 1802 // and we don't have to wait for the result so from the client's perspective |
1706 // it's cheap. | 1803 // it's cheap. |
1707 helper_->SetBucketSize(kResultBucketId, 0); | 1804 helper_->SetBucketSize(kResultBucketId, 0); |
1708 } | 1805 } |
1709 | 1806 |
1710 namespace { | 1807 namespace { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1762 uint32 size; | 1859 uint32 size; |
1763 uint32 unpadded_row_size; | 1860 uint32 unpadded_row_size; |
1764 uint32 padded_row_size; | 1861 uint32 padded_row_size; |
1765 if (!GLES2Util::ComputeImageDataSizes( | 1862 if (!GLES2Util::ComputeImageDataSizes( |
1766 width, height, format, type, unpack_alignment_, &size, | 1863 width, height, format, type, unpack_alignment_, &size, |
1767 &unpadded_row_size, &padded_row_size)) { | 1864 &unpadded_row_size, &padded_row_size)) { |
1768 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); | 1865 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
1769 return; | 1866 return; |
1770 } | 1867 } |
1771 | 1868 |
1869 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. | |
1870 if (bound_pixel_unpack_transfer_buffer_id_) { | |
1871 GLuint offset = ToGLuint(pixels); | |
1872 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | |
1873 "glTexImage2D", offset, size); | |
1874 if (buffer) | |
1875 helper_->TexImage2D( | |
1876 target, level, internalformat, width, height, border, format, type, | |
1877 buffer->shm_id(), buffer->shm_offset() + offset); | |
1878 return; | |
1879 } | |
1880 | |
1772 // If there's no data just issue TexImage2D | 1881 // If there's no data just issue TexImage2D |
1773 if (!pixels) { | 1882 if (!pixels) { |
1774 helper_->TexImage2D( | 1883 helper_->TexImage2D( |
1775 target, level, internalformat, width, height, border, format, type, | 1884 target, level, internalformat, width, height, border, format, type, |
1776 0, 0); | 1885 0, 0); |
1777 return; | 1886 return; |
1778 } | 1887 } |
1779 | 1888 |
1780 // compute the advance bytes per row for the src pixels | 1889 // compute the advance bytes per row for the src pixels |
1781 uint32 src_padded_row_size; | 1890 uint32 src_padded_row_size; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1849 uint32 temp_size; | 1958 uint32 temp_size; |
1850 uint32 unpadded_row_size; | 1959 uint32 unpadded_row_size; |
1851 uint32 padded_row_size; | 1960 uint32 padded_row_size; |
1852 if (!GLES2Util::ComputeImageDataSizes( | 1961 if (!GLES2Util::ComputeImageDataSizes( |
1853 width, height, format, type, unpack_alignment_, &temp_size, | 1962 width, height, format, type, unpack_alignment_, &temp_size, |
1854 &unpadded_row_size, &padded_row_size)) { | 1963 &unpadded_row_size, &padded_row_size)) { |
1855 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); | 1964 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); |
1856 return; | 1965 return; |
1857 } | 1966 } |
1858 | 1967 |
1968 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | |
1969 if (bound_pixel_unpack_transfer_buffer_id_) { | |
1970 GLuint offset = ToGLuint(pixels); | |
1971 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | |
1972 "glTexSubImage2D", offset, temp_size); | |
1973 if (buffer) | |
1974 helper_->TexSubImage2D( | |
1975 target, level, xoffset, yoffset, width, height, format, type, | |
1976 buffer->shm_id(), buffer->shm_offset() + offset, false); | |
1977 return; | |
1978 } | |
1979 | |
1859 // compute the advance bytes per row for the src pixels | 1980 // compute the advance bytes per row for the src pixels |
1860 uint32 src_padded_row_size; | 1981 uint32 src_padded_row_size; |
1861 if (unpack_row_length_ > 0) { | 1982 if (unpack_row_length_ > 0) { |
1862 if (!GLES2Util::ComputeImagePaddedRowSize( | 1983 if (!GLES2Util::ComputeImagePaddedRowSize( |
1863 unpack_row_length_, format, type, unpack_alignment_, | 1984 unpack_row_length_, format, type, unpack_alignment_, |
1864 &src_padded_row_size)) { | 1985 &src_padded_row_size)) { |
1865 SetGLError( | 1986 SetGLError( |
1866 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); | 1987 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); |
1867 return; | 1988 return; |
1868 } | 1989 } |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2372 bound_array_buffer_id_ = buffer; | 2493 bound_array_buffer_id_ = buffer; |
2373 changed = true; | 2494 changed = true; |
2374 } | 2495 } |
2375 break; | 2496 break; |
2376 case GL_ELEMENT_ARRAY_BUFFER: | 2497 case GL_ELEMENT_ARRAY_BUFFER: |
2377 if (bound_element_array_buffer_id_ != buffer) { | 2498 if (bound_element_array_buffer_id_ != buffer) { |
2378 bound_element_array_buffer_id_ = buffer; | 2499 bound_element_array_buffer_id_ = buffer; |
2379 changed = true; | 2500 changed = true; |
2380 } | 2501 } |
2381 break; | 2502 break; |
2503 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | |
2504 bound_pixel_unpack_transfer_buffer_id_ = buffer; | |
2505 break; | |
2382 default: | 2506 default: |
2383 changed = true; | 2507 changed = true; |
2384 break; | 2508 break; |
2385 } | 2509 } |
2386 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2510 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
2387 // used even though it's marked it as used here. | 2511 // used even though it's marked it as used here. |
2388 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2512 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); |
2389 return changed; | 2513 return changed; |
2390 } | 2514 } |
2391 | 2515 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2493 "glDeleteBuffers", "id not created by this context."); | 2617 "glDeleteBuffers", "id not created by this context."); |
2494 return; | 2618 return; |
2495 } | 2619 } |
2496 for (GLsizei ii = 0; ii < n; ++ii) { | 2620 for (GLsizei ii = 0; ii < n; ++ii) { |
2497 if (buffers[ii] == bound_array_buffer_id_) { | 2621 if (buffers[ii] == bound_array_buffer_id_) { |
2498 bound_array_buffer_id_ = 0; | 2622 bound_array_buffer_id_ = 0; |
2499 } | 2623 } |
2500 if (buffers[ii] == bound_element_array_buffer_id_) { | 2624 if (buffers[ii] == bound_element_array_buffer_id_) { |
2501 bound_element_array_buffer_id_ = 0; | 2625 bound_element_array_buffer_id_ = 0; |
2502 } | 2626 } |
2627 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { | |
2628 bound_pixel_unpack_transfer_buffer_id_ = 0; | |
2629 } | |
2630 | |
2631 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); | |
2632 if (buffer) { | |
2633 // Free buffer memory, pending the passage of a token. | |
2634 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | |
2635 // Remove buffer. | |
2636 buffer_tracker_->RemoveBuffer(buffers[ii]); | |
2637 } | |
2503 } | 2638 } |
2504 } | 2639 } |
2505 | 2640 |
2506 void GLES2Implementation::DeleteBuffersStub( | 2641 void GLES2Implementation::DeleteBuffersStub( |
2507 GLsizei n, const GLuint* buffers) { | 2642 GLsizei n, const GLuint* buffers) { |
2508 helper_->DeleteBuffersImmediate(n, buffers); | 2643 helper_->DeleteBuffersImmediate(n, buffers); |
2509 } | 2644 } |
2510 | 2645 |
2511 | 2646 |
2512 void GLES2Implementation::DeleteFramebuffersHelper( | 2647 void GLES2Implementation::DeleteFramebuffersHelper( |
(...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3462 void GLES2Implementation::TraceBeginCHROMIUM(const char* name) { | 3597 void GLES2Implementation::TraceBeginCHROMIUM(const char* name) { |
3463 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3598 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
3464 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceBeginCHROMIUM(" | 3599 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceBeginCHROMIUM(" |
3465 << name << ")"); | 3600 << name << ")"); |
3466 | 3601 |
3467 SetBucketAsCString(kResultBucketId, name); | 3602 SetBucketAsCString(kResultBucketId, name); |
3468 helper_->TraceBeginCHROMIUM(kResultBucketId); | 3603 helper_->TraceBeginCHROMIUM(kResultBucketId); |
3469 helper_->SetBucketSize(kResultBucketId, 0); | 3604 helper_->SetBucketSize(kResultBucketId, 0); |
3470 } | 3605 } |
3471 | 3606 |
3607 void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { | |
3608 GPU_CLIENT_SINGLE_THREAD_CHECK(); | |
3609 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferCHROMIUM(" | |
3610 << target << ", " << GLES2Util::GetStringEnum(access) << ")"); | |
3611 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | |
3612 SetGLError( | |
3613 GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target"); | |
3614 return NULL; | |
3615 } | |
3616 if (access != GL_WRITE_ONLY) { | |
3617 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); | |
3618 return NULL; | |
3619 } | |
3620 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | |
3621 bound_pixel_unpack_transfer_buffer_id_); | |
3622 if (!buffer) { | |
3623 SetGLError(GL_INVALID_VALUE, "glMapBufferCHROMIUM", "invalid buffer"); | |
greggman
2012/11/20 18:57:42
GL_INVALID_OPERATION
reveman
2012/11/20 23:24:30
Done.
| |
3624 return NULL; | |
3625 } | |
3626 if (buffer->mapped()) { | |
3627 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "already mapped"); | |
greggman
2012/11/20 18:57:42
GL_INVALID_OPERATION
reveman
2012/11/20 23:24:30
Done.
| |
3628 return NULL; | |
3629 } | |
3630 buffer->set_mapped(true); | |
3631 | |
3632 GPU_DCHECK(buffer->address()); | |
3633 GPU_CLIENT_LOG(" returned " << buffer->address()); | |
3634 return buffer->address(); | |
3635 } | |
3636 | |
3637 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { | |
3638 GPU_CLIENT_SINGLE_THREAD_CHECK(); | |
3639 GPU_CLIENT_LOG( | |
3640 "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); | |
3641 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | |
3642 SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); | |
3643 return false; | |
3644 } | |
3645 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | |
3646 bound_pixel_unpack_transfer_buffer_id_); | |
3647 if (!buffer) { | |
3648 SetGLError(GL_INVALID_VALUE, "glMapBufferCHROMIUM", "invalid buffer"); | |
greggman
2012/11/20 18:57:42
GL_INVALID_OPERATION
reveman
2012/11/20 23:24:30
Done.
| |
3649 return false; | |
3650 } | |
3651 if (!buffer->mapped()) { | |
3652 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "not mapped"); | |
greggman
2012/11/20 18:57:42
GL_INVALID_OPERATION
reveman
2012/11/20 23:24:30
Done.
| |
3653 return false; | |
3654 } | |
3655 buffer->set_mapped(false); | |
3656 | |
3657 return true; | |
3658 } | |
3659 | |
3472 // Include the auto-generated part of this file. We split this because it means | 3660 // Include the auto-generated part of this file. We split this because it means |
3473 // we can easily edit the non-auto generated parts right here in this file | 3661 // we can easily edit the non-auto generated parts right here in this file |
3474 // instead of having to edit some template or the code generator. | 3662 // instead of having to edit some template or the code generator. |
3475 #include "../client/gles2_implementation_impl_autogen.h" | 3663 #include "../client/gles2_implementation_impl_autogen.h" |
3476 | 3664 |
3477 } // namespace gles2 | 3665 } // namespace gles2 |
3478 } // namespace gpu | 3666 } // namespace gpu |
OLD | NEW |