| 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 if (share_group_->bind_generates_resource()) { |
| 970 *params = bound_pixel_unpack_transfer_buffer_id_; |
| 971 return true; |
| 972 } |
| 973 return false; |
| 963 case GL_ACTIVE_TEXTURE: | 974 case GL_ACTIVE_TEXTURE: |
| 964 *params = active_texture_unit_ + GL_TEXTURE0; | 975 *params = active_texture_unit_ + GL_TEXTURE0; |
| 965 return true; | 976 return true; |
| 966 case GL_TEXTURE_BINDING_2D: | 977 case GL_TEXTURE_BINDING_2D: |
| 967 if (share_group_->bind_generates_resource()) { | 978 if (share_group_->bind_generates_resource()) { |
| 968 *params = texture_units_[active_texture_unit_].bound_texture_2d; | 979 *params = texture_units_[active_texture_unit_].bound_texture_2d; |
| 969 return true; | 980 return true; |
| 970 } | 981 } |
| 971 return false; | 982 return false; |
| 972 case GL_TEXTURE_BINDING_CUBE_MAP: | 983 case GL_TEXTURE_BINDING_CUBE_MAP: |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 void GLES2Implementation::BindAttribLocation( | 1269 void GLES2Implementation::BindAttribLocation( |
| 1259 GLuint program, GLuint index, const char* name) { | 1270 GLuint program, GLuint index, const char* name) { |
| 1260 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1271 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1261 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindAttribLocation(" | 1272 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindAttribLocation(" |
| 1262 << program << ", " << index << ", " << name << ")"); | 1273 << program << ", " << index << ", " << name << ")"); |
| 1263 SetBucketAsString(kResultBucketId, name); | 1274 SetBucketAsString(kResultBucketId, name); |
| 1264 helper_->BindAttribLocationBucket(program, index, kResultBucketId); | 1275 helper_->BindAttribLocationBucket(program, index, kResultBucketId); |
| 1265 helper_->SetBucketSize(kResultBucketId, 0); | 1276 helper_->SetBucketSize(kResultBucketId, 0); |
| 1266 } | 1277 } |
| 1267 | 1278 |
| 1279 void GLES2Implementation::BindBuffer(GLenum target, GLuint buffer) { |
| 1280 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1281 GPU_CLIENT_LOG("[" << this << "] glBindBuffer(" << |
| 1282 GLES2Util::GetStringBufferTarget(target) << ", " << buffer << ")"); |
| 1283 if (IsBufferReservedId(buffer)) { |
| 1284 SetGLError(GL_INVALID_OPERATION, "BindBuffer", "buffer reserved id"); |
| 1285 return; |
| 1286 } |
| 1287 BindBufferHelper(target, buffer); |
| 1288 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) |
| 1289 helper_->BindBuffer(target, buffer); |
| 1290 } |
| 1291 |
| 1268 void GLES2Implementation::BindUniformLocationCHROMIUM( | 1292 void GLES2Implementation::BindUniformLocationCHROMIUM( |
| 1269 GLuint program, GLint location, const char* name) { | 1293 GLuint program, GLint location, const char* name) { |
| 1270 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1294 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1271 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindUniformLocationCHROMIUM(" | 1295 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindUniformLocationCHROMIUM(" |
| 1272 << program << ", " << location << ", " << name << ")"); | 1296 << program << ", " << location << ", " << name << ")"); |
| 1273 SetBucketAsString(kResultBucketId, name); | 1297 SetBucketAsString(kResultBucketId, name); |
| 1274 helper_->BindUniformLocationCHROMIUMBucket( | 1298 helper_->BindUniformLocationCHROMIUMBucket( |
| 1275 program, location, kResultBucketId); | 1299 program, location, kResultBucketId); |
| 1276 helper_->SetBucketSize(kResultBucketId, 0); | 1300 helper_->SetBucketSize(kResultBucketId, 0); |
| 1277 } | 1301 } |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { | 1629 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { |
| 1606 if (size == 0) { | 1630 if (size == 0) { |
| 1607 return; | 1631 return; |
| 1608 } | 1632 } |
| 1609 | 1633 |
| 1610 if (size < 0) { | 1634 if (size < 0) { |
| 1611 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); | 1635 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); |
| 1612 return; | 1636 return; |
| 1613 } | 1637 } |
| 1614 | 1638 |
| 1639 if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
| 1640 GLuint buffer_id = bound_pixel_unpack_transfer_buffer_id_; |
| 1641 if (!buffer_id) { |
| 1642 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); |
| 1643 return; |
| 1644 } |
| 1645 |
| 1646 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 1647 if (buffer) { |
| 1648 // Free buffer memory, pending the passage of a token. |
| 1649 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
| 1650 |
| 1651 // Remove old buffer. |
| 1652 buffer_tracker_->RemoveBuffer(buffer_id); |
| 1653 } |
| 1654 |
| 1655 // Create new buffer. |
| 1656 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); |
| 1657 GPU_DCHECK(buffer); |
| 1658 if (data) |
| 1659 memcpy(buffer->address(), data, size); |
| 1660 return; |
| 1661 } |
| 1662 |
| 1615 // If there is no data just send BufferData | 1663 // If there is no data just send BufferData |
| 1616 if (!data) { | 1664 if (!data) { |
| 1617 helper_->BufferData(target, size, 0, 0, usage); | 1665 helper_->BufferData(target, size, 0, 0, usage); |
| 1618 return; | 1666 return; |
| 1619 } | 1667 } |
| 1620 | 1668 |
| 1621 // See if we can send all at once. | 1669 // See if we can send all at once. |
| 1622 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); | 1670 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
| 1623 if (!buffer.valid()) { | 1671 if (!buffer.valid()) { |
| 1624 return; | 1672 return; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1711 << width << ", " << height << ", " << border << ", " | 1759 << width << ", " << height << ", " << border << ", " |
| 1712 << image_size << ", " | 1760 << image_size << ", " |
| 1713 << static_cast<const void*>(data) << ")"); | 1761 << static_cast<const void*>(data) << ")"); |
| 1714 if (width < 0 || height < 0 || level < 0) { | 1762 if (width < 0 || height < 0 || level < 0) { |
| 1715 SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "dimension < 0"); | 1763 SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "dimension < 0"); |
| 1716 return; | 1764 return; |
| 1717 } | 1765 } |
| 1718 if (height == 0 || width == 0) { | 1766 if (height == 0 || width == 0) { |
| 1719 return; | 1767 return; |
| 1720 } | 1768 } |
| 1769 // If there's a pixel unpack buffer bound use it when issuing |
| 1770 // CompressedTexImage2D. |
| 1771 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1772 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 1773 bound_pixel_unpack_transfer_buffer_id_); |
| 1774 if (!buffer) { |
| 1775 SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "invalid buffer"); |
| 1776 return; |
| 1777 } |
| 1778 GLuint offset = ToGLuint(data); |
| 1779 if ((buffer->size() - offset) < static_cast<GLuint>(image_size)) { |
| 1780 SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", |
| 1781 "unpack size to large"); |
| 1782 return; |
| 1783 } |
| 1784 helper_->CompressedTexImage2D( |
| 1785 target, level, internalformat, width, height, border, image_size, |
| 1786 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1787 return; |
| 1788 } |
| 1721 SetBucketContents(kResultBucketId, data, image_size); | 1789 SetBucketContents(kResultBucketId, data, image_size); |
| 1722 helper_->CompressedTexImage2DBucket( | 1790 helper_->CompressedTexImage2DBucket( |
| 1723 target, level, internalformat, width, height, border, kResultBucketId); | 1791 target, level, internalformat, width, height, border, kResultBucketId); |
| 1724 // Free the bucket. This is not required but it does free up the memory. | 1792 // 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 | 1793 // and we don't have to wait for the result so from the client's perspective |
| 1726 // it's cheap. | 1794 // it's cheap. |
| 1727 helper_->SetBucketSize(kResultBucketId, 0); | 1795 helper_->SetBucketSize(kResultBucketId, 0); |
| 1728 } | 1796 } |
| 1729 | 1797 |
| 1730 void GLES2Implementation::CompressedTexSubImage2D( | 1798 void GLES2Implementation::CompressedTexSubImage2D( |
| 1731 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 1799 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
| 1732 GLsizei height, GLenum format, GLsizei image_size, const void* data) { | 1800 GLsizei height, GLenum format, GLsizei image_size, const void* data) { |
| 1733 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1801 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1734 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexSubImage2D(" | 1802 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexSubImage2D(" |
| 1735 << GLES2Util::GetStringTextureTarget(target) << ", " | 1803 << GLES2Util::GetStringTextureTarget(target) << ", " |
| 1736 << level << ", " | 1804 << level << ", " |
| 1737 << xoffset << ", " << yoffset << ", " | 1805 << xoffset << ", " << yoffset << ", " |
| 1738 << width << ", " << height << ", " | 1806 << width << ", " << height << ", " |
| 1739 << GLES2Util::GetStringCompressedTextureFormat(format) << ", " | 1807 << GLES2Util::GetStringCompressedTextureFormat(format) << ", " |
| 1740 << image_size << ", " | 1808 << image_size << ", " |
| 1741 << static_cast<const void*>(data) << ")"); | 1809 << static_cast<const void*>(data) << ")"); |
| 1742 if (width < 0 || height < 0 || level < 0) { | 1810 if (width < 0 || height < 0 || level < 0) { |
| 1743 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); | 1811 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); |
| 1744 return; | 1812 return; |
| 1745 } | 1813 } |
| 1814 // If there's a pixel unpack buffer bound use it when issuing |
| 1815 // CompressedTexSubImage2D. |
| 1816 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1817 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 1818 bound_pixel_unpack_transfer_buffer_id_); |
| 1819 if (!buffer) { |
| 1820 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", |
| 1821 "invalid buffer"); |
| 1822 return; |
| 1823 } |
| 1824 GLuint offset = ToGLuint(data); |
| 1825 if ((buffer->size() - offset) < static_cast<GLuint>(image_size)) { |
| 1826 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", |
| 1827 "unpack size to large"); |
| 1828 return; |
| 1829 } |
| 1830 helper_->CompressedTexSubImage2D( |
| 1831 target, level, xoffset, yoffset, width, height, format, image_size, |
| 1832 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1833 return; |
| 1834 } |
| 1746 SetBucketContents(kResultBucketId, data, image_size); | 1835 SetBucketContents(kResultBucketId, data, image_size); |
| 1747 helper_->CompressedTexSubImage2DBucket( | 1836 helper_->CompressedTexSubImage2DBucket( |
| 1748 target, level, xoffset, yoffset, width, height, format, kResultBucketId); | 1837 target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
| 1749 // Free the bucket. This is not required but it does free up the memory. | 1838 // 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 | 1839 // and we don't have to wait for the result so from the client's perspective |
| 1751 // it's cheap. | 1840 // it's cheap. |
| 1752 helper_->SetBucketSize(kResultBucketId, 0); | 1841 helper_->SetBucketSize(kResultBucketId, 0); |
| 1753 } | 1842 } |
| 1754 | 1843 |
| 1755 namespace { | 1844 namespace { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 uint32 size; | 1896 uint32 size; |
| 1808 uint32 unpadded_row_size; | 1897 uint32 unpadded_row_size; |
| 1809 uint32 padded_row_size; | 1898 uint32 padded_row_size; |
| 1810 if (!GLES2Util::ComputeImageDataSizes( | 1899 if (!GLES2Util::ComputeImageDataSizes( |
| 1811 width, height, format, type, unpack_alignment_, &size, | 1900 width, height, format, type, unpack_alignment_, &size, |
| 1812 &unpadded_row_size, &padded_row_size)) { | 1901 &unpadded_row_size, &padded_row_size)) { |
| 1813 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); | 1902 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
| 1814 return; | 1903 return; |
| 1815 } | 1904 } |
| 1816 | 1905 |
| 1906 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
| 1907 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1908 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 1909 bound_pixel_unpack_transfer_buffer_id_); |
| 1910 if (!buffer) { |
| 1911 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "invalid buffer"); |
| 1912 return; |
| 1913 } |
| 1914 GLuint offset = ToGLuint(pixels); |
| 1915 if ((buffer->size() - offset) < size) { |
| 1916 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "unpack size to large"); |
| 1917 return; |
| 1918 } |
| 1919 helper_->TexImage2D( |
| 1920 target, level, internalformat, width, height, border, format, type, |
| 1921 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1922 return; |
| 1923 } |
| 1924 |
| 1817 // If there's no data just issue TexImage2D | 1925 // If there's no data just issue TexImage2D |
| 1818 if (!pixels) { | 1926 if (!pixels) { |
| 1819 helper_->TexImage2D( | 1927 helper_->TexImage2D( |
| 1820 target, level, internalformat, width, height, border, format, type, | 1928 target, level, internalformat, width, height, border, format, type, |
| 1821 0, 0); | 1929 0, 0); |
| 1822 return; | 1930 return; |
| 1823 } | 1931 } |
| 1824 | 1932 |
| 1825 // compute the advance bytes per row for the src pixels | 1933 // compute the advance bytes per row for the src pixels |
| 1826 uint32 src_padded_row_size; | 1934 uint32 src_padded_row_size; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1894 uint32 temp_size; | 2002 uint32 temp_size; |
| 1895 uint32 unpadded_row_size; | 2003 uint32 unpadded_row_size; |
| 1896 uint32 padded_row_size; | 2004 uint32 padded_row_size; |
| 1897 if (!GLES2Util::ComputeImageDataSizes( | 2005 if (!GLES2Util::ComputeImageDataSizes( |
| 1898 width, height, format, type, unpack_alignment_, &temp_size, | 2006 width, height, format, type, unpack_alignment_, &temp_size, |
| 1899 &unpadded_row_size, &padded_row_size)) { | 2007 &unpadded_row_size, &padded_row_size)) { |
| 1900 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); | 2008 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); |
| 1901 return; | 2009 return; |
| 1902 } | 2010 } |
| 1903 | 2011 |
| 2012 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
| 2013 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2014 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 2015 bound_pixel_unpack_transfer_buffer_id_); |
| 2016 if (!buffer) { |
| 2017 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "invalid buffer"); |
| 2018 return; |
| 2019 } |
| 2020 GLuint offset = ToGLuint(pixels); |
| 2021 if ((buffer->size() - offset) < temp_size) { |
| 2022 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "unpack size to large"); |
| 2023 return; |
| 2024 } |
| 2025 helper_->TexSubImage2D( |
| 2026 target, level, xoffset, yoffset, width, height, format, type, |
| 2027 buffer->shm_id(), buffer->shm_offset() + offset, false); |
| 2028 return; |
| 2029 } |
| 2030 |
| 1904 // compute the advance bytes per row for the src pixels | 2031 // compute the advance bytes per row for the src pixels |
| 1905 uint32 src_padded_row_size; | 2032 uint32 src_padded_row_size; |
| 1906 if (unpack_row_length_ > 0) { | 2033 if (unpack_row_length_ > 0) { |
| 1907 if (!GLES2Util::ComputeImagePaddedRowSize( | 2034 if (!GLES2Util::ComputeImagePaddedRowSize( |
| 1908 unpack_row_length_, format, type, unpack_alignment_, | 2035 unpack_row_length_, format, type, unpack_alignment_, |
| 1909 &src_padded_row_size)) { | 2036 &src_padded_row_size)) { |
| 1910 SetGLError( | 2037 SetGLError( |
| 1911 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); | 2038 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); |
| 1912 return; | 2039 return; |
| 1913 } | 2040 } |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2410 void GLES2Implementation::BindBufferHelper( | 2537 void GLES2Implementation::BindBufferHelper( |
| 2411 GLenum target, GLuint buffer) { | 2538 GLenum target, GLuint buffer) { |
| 2412 // TODO(gman): See note #1 above. | 2539 // TODO(gman): See note #1 above. |
| 2413 switch (target) { | 2540 switch (target) { |
| 2414 case GL_ARRAY_BUFFER: | 2541 case GL_ARRAY_BUFFER: |
| 2415 bound_array_buffer_id_ = buffer; | 2542 bound_array_buffer_id_ = buffer; |
| 2416 break; | 2543 break; |
| 2417 case GL_ELEMENT_ARRAY_BUFFER: | 2544 case GL_ELEMENT_ARRAY_BUFFER: |
| 2418 bound_element_array_buffer_id_ = buffer; | 2545 bound_element_array_buffer_id_ = buffer; |
| 2419 break; | 2546 break; |
| 2547 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| 2548 bound_pixel_unpack_transfer_buffer_id_ = buffer; |
| 2549 break; |
| 2420 default: | 2550 default: |
| 2421 break; | 2551 break; |
| 2422 } | 2552 } |
| 2423 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2553 // 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. | 2554 // used even though it's marked it as used here. |
| 2425 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2555 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); |
| 2426 } | 2556 } |
| 2427 | 2557 |
| 2428 void GLES2Implementation::BindFramebufferHelper( | 2558 void GLES2Implementation::BindFramebufferHelper( |
| 2429 GLenum target, GLuint framebuffer) { | 2559 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."); | 2634 "glDeleteBuffers", "id not created by this context."); |
| 2505 return; | 2635 return; |
| 2506 } | 2636 } |
| 2507 for (GLsizei ii = 0; ii < n; ++ii) { | 2637 for (GLsizei ii = 0; ii < n; ++ii) { |
| 2508 if (buffers[ii] == bound_array_buffer_id_) { | 2638 if (buffers[ii] == bound_array_buffer_id_) { |
| 2509 bound_array_buffer_id_ = 0; | 2639 bound_array_buffer_id_ = 0; |
| 2510 } | 2640 } |
| 2511 if (buffers[ii] == bound_element_array_buffer_id_) { | 2641 if (buffers[ii] == bound_element_array_buffer_id_) { |
| 2512 bound_element_array_buffer_id_ = 0; | 2642 bound_element_array_buffer_id_ = 0; |
| 2513 } | 2643 } |
| 2644 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
| 2645 bound_pixel_unpack_transfer_buffer_id_ = 0; |
| 2646 } |
| 2647 |
| 2648 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
| 2649 if (buffer) { |
| 2650 // Free buffer memory, pending the passage of a token. |
| 2651 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
| 2652 // Remove buffer. |
| 2653 buffer_tracker_->RemoveBuffer(buffers[ii]); |
| 2654 } |
| 2514 } | 2655 } |
| 2515 } | 2656 } |
| 2516 | 2657 |
| 2517 void GLES2Implementation::DeleteBuffersStub( | 2658 void GLES2Implementation::DeleteBuffersStub( |
| 2518 GLsizei n, const GLuint* buffers) { | 2659 GLsizei n, const GLuint* buffers) { |
| 2519 helper_->DeleteBuffersImmediate(n, buffers); | 2660 helper_->DeleteBuffersImmediate(n, buffers); |
| 2520 } | 2661 } |
| 2521 | 2662 |
| 2522 | 2663 |
| 2523 void GLES2Implementation::DeleteFramebuffersHelper( | 2664 void GLES2Implementation::DeleteFramebuffersHelper( |
| (...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3463 length ? std::string(marker, length) : std::string(marker)); | 3604 length ? std::string(marker, length) : std::string(marker)); |
| 3464 } | 3605 } |
| 3465 | 3606 |
| 3466 void GLES2Implementation::PopGroupMarkerEXT() { | 3607 void GLES2Implementation::PopGroupMarkerEXT() { |
| 3467 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3608 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3468 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPopGroupMarkerEXT()"); | 3609 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPopGroupMarkerEXT()"); |
| 3469 helper_->PopGroupMarkerEXT(); | 3610 helper_->PopGroupMarkerEXT(); |
| 3470 debug_marker_manager_.PopGroup(); | 3611 debug_marker_manager_.PopGroup(); |
| 3471 } | 3612 } |
| 3472 | 3613 |
| 3614 void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { |
| 3615 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3616 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferCHROMIUM(" |
| 3617 << target << ", " << GLES2Util::GetStringEnum(access) << ")"); |
| 3618 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
| 3619 SetGLError( |
| 3620 GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target"); |
| 3621 return NULL; |
| 3622 } |
| 3623 if (access != GL_WRITE_ONLY) { |
| 3624 SetGLError( |
| 3625 GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); |
| 3626 return NULL; |
| 3627 } |
| 3628 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 3629 bound_pixel_unpack_transfer_buffer_id_); |
| 3630 if (!buffer) { |
| 3631 SetGLError( |
| 3632 GL_INVALID_VALUE, "glMapBufferCHROMIUM", "invalid buffer"); |
| 3633 return NULL; |
| 3634 } |
| 3635 |
| 3636 GPU_DCHECK(buffer->address()); |
| 3637 GPU_CLIENT_LOG(" returned " << buffer->address()); |
| 3638 return buffer->address(); |
| 3639 } |
| 3640 |
| 3641 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
| 3642 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3643 GPU_CLIENT_LOG( |
| 3644 "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); |
| 3645 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
| 3646 SetGLError( |
| 3647 GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); |
| 3648 return false; |
| 3649 } |
| 3650 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 3651 bound_pixel_unpack_transfer_buffer_id_); |
| 3652 if (!buffer) { |
| 3653 SetGLError( |
| 3654 GL_INVALID_VALUE, "glMapBufferCHROMIUM", "invalid buffer"); |
| 3655 return false; |
| 3656 } |
| 3657 |
| 3658 return true; |
| 3659 } |
| 3660 |
| 3473 // Include the auto-generated part of this file. We split this because it means | 3661 // Include the auto-generated part of this file. We split this because it means |
| 3474 // we can easily edit the non-auto generated parts right here in this file | 3662 // we can easily edit the non-auto generated parts right here in this file |
| 3475 // instead of having to edit some template or the code generator. | 3663 // instead of having to edit some template or the code generator. |
| 3476 #include "../client/gles2_implementation_impl_autogen.h" | 3664 #include "../client/gles2_implementation_impl_autogen.h" |
| 3477 | 3665 |
| 3478 } // namespace gles2 | 3666 } // namespace gles2 |
| 3479 } // namespace gpu | 3667 } // namespace gpu |
| OLD | NEW |