Chromium Code Reviews| 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 "gpu/command_buffer/client/gles2_implementation.h" | 7 #include "gpu/command_buffer/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 <GLES2/gl2extchromium.h> | 17 #include <GLES2/gl2extchromium.h> |
| 18 #include "base/bind.h" | |
| 18 #include "gpu/command_buffer/client/buffer_tracker.h" | 19 #include "gpu/command_buffer/client/buffer_tracker.h" |
| 19 #include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h" | 20 #include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h" |
| 20 #include "gpu/command_buffer/client/program_info_manager.h" | 21 #include "gpu/command_buffer/client/program_info_manager.h" |
| 21 #include "gpu/command_buffer/client/query_tracker.h" | 22 #include "gpu/command_buffer/client/query_tracker.h" |
| 22 #include "gpu/command_buffer/client/transfer_buffer.h" | 23 #include "gpu/command_buffer/client/transfer_buffer.h" |
| 23 #include "gpu/command_buffer/client/vertex_array_object_manager.h" | 24 #include "gpu/command_buffer/client/vertex_array_object_manager.h" |
| 24 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 25 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 25 #include "gpu/command_buffer/common/gpu_control.h" | 26 #include "gpu/command_buffer/common/gpu_control.h" |
| 26 #include "gpu/command_buffer/common/trace_event.h" | 27 #include "gpu/command_buffer/common/trace_event.h" |
| 27 #include "ui/gfx/gpu_memory_buffer.h" | 28 #include "ui/gfx/gpu_memory_buffer.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 unpack_skip_pixels_(0), | 101 unpack_skip_pixels_(0), |
| 101 pack_reverse_row_order_(false), | 102 pack_reverse_row_order_(false), |
| 102 active_texture_unit_(0), | 103 active_texture_unit_(0), |
| 103 bound_framebuffer_(0), | 104 bound_framebuffer_(0), |
| 104 bound_read_framebuffer_(0), | 105 bound_read_framebuffer_(0), |
| 105 bound_renderbuffer_(0), | 106 bound_renderbuffer_(0), |
| 106 current_program_(0), | 107 current_program_(0), |
| 107 bound_array_buffer_id_(0), | 108 bound_array_buffer_id_(0), |
| 108 bound_pixel_pack_transfer_buffer_id_(0), | 109 bound_pixel_pack_transfer_buffer_id_(0), |
| 109 bound_pixel_unpack_transfer_buffer_id_(0), | 110 bound_pixel_unpack_transfer_buffer_id_(0), |
| 111 async_upload_sync_(NULL), | |
|
piman
2014/02/07 22:58:20
Also need initializers for async_upload_token_, a
jadahl
2014/02/19 14:06:20
async_upload_token_ is needed indeed, but shm_id a
piman
2014/02/20 01:52:37
Per style guide ( http://google-styleguide.googlec
| |
| 110 error_bits_(0), | 112 error_bits_(0), |
| 111 debug_(false), | 113 debug_(false), |
| 112 use_count_(0), | 114 use_count_(0), |
| 113 error_message_callback_(NULL), | 115 error_message_callback_(NULL), |
| 114 gpu_control_(gpu_control), | 116 gpu_control_(gpu_control), |
| 115 surface_visible_(true), | 117 surface_visible_(true), |
| 116 free_everything_when_invisible_(free_everything_when_invisible), | 118 free_everything_when_invisible_(free_everything_when_invisible), |
| 117 capabilities_(gpu_control->GetCapabilities()), | 119 capabilities_(gpu_control->GetCapabilities()), |
| 118 weak_ptr_factory_(this) { | 120 weak_ptr_factory_(this) { |
| 119 DCHECK(helper); | 121 DCHECK(helper); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 147 if (!transfer_buffer_->Initialize( | 149 if (!transfer_buffer_->Initialize( |
| 148 starting_transfer_buffer_size, | 150 starting_transfer_buffer_size, |
| 149 kStartingOffset, | 151 kStartingOffset, |
| 150 min_transfer_buffer_size, | 152 min_transfer_buffer_size, |
| 151 max_transfer_buffer_size, | 153 max_transfer_buffer_size, |
| 152 kAlignment, | 154 kAlignment, |
| 153 kSizeToFlush)) { | 155 kSizeToFlush)) { |
| 154 return false; | 156 return false; |
| 155 } | 157 } |
| 156 | 158 |
| 157 mapped_memory_.reset(new MappedMemoryManager(helper_, mapped_memory_limit)); | 159 mapped_memory_.reset( |
| 160 new MappedMemoryManager(helper_, | |
| 161 base::Bind(&GLES2Implementation::PollAsyncUploads, | |
| 162 base::Unretained(this), | |
|
epennerAtGoogle
2014/02/07 20:43:58
Nit: Maybe overkill in this case, but it never hur
| |
| 163 false), | |
| 164 mapped_memory_limit)); | |
| 158 | 165 |
| 159 unsigned chunk_size = 2 * 1024 * 1024; | 166 unsigned chunk_size = 2 * 1024 * 1024; |
| 160 if (mapped_memory_limit != kNoLimit) { | 167 if (mapped_memory_limit != kNoLimit) { |
| 161 // Use smaller chunks if the client is very memory conscientious. | 168 // Use smaller chunks if the client is very memory conscientious. |
| 162 chunk_size = std::min(mapped_memory_limit / 4, chunk_size); | 169 chunk_size = std::min(mapped_memory_limit / 4, chunk_size); |
| 163 } | 170 } |
| 164 mapped_memory_->set_chunk_size_multiple(chunk_size); | 171 mapped_memory_->set_chunk_size_multiple(chunk_size); |
| 165 | 172 |
| 166 if (!QueryAndCacheStaticState()) | 173 if (!QueryAndCacheStaticState()) |
| 167 return false; | 174 return false; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 // by the queries. The GPU process when validating that memory is still | 277 // by the queries. The GPU process when validating that memory is still |
| 271 // shared will fail and abort (ie, it will stop running). | 278 // shared will fail and abort (ie, it will stop running). |
| 272 WaitForCmd(); | 279 WaitForCmd(); |
| 273 query_tracker_.reset(); | 280 query_tracker_.reset(); |
| 274 | 281 |
| 275 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 282 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 276 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); | 283 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); |
| 277 #endif | 284 #endif |
| 278 buffer_tracker_.reset(); | 285 buffer_tracker_.reset(); |
| 279 | 286 |
| 287 // Wait for all async uploads to finish so we can free their buffers. | |
| 288 PollAsyncUploads(true); | |
| 289 | |
| 290 if (async_upload_sync_) { | |
| 291 mapped_memory_->Free(static_cast<void*>(async_upload_sync_)); | |
|
piman
2014/02/07 22:58:20
nit: static_cast isn't needed.
| |
| 292 async_upload_sync_ = NULL; | |
| 293 } | |
| 294 | |
| 280 // Make sure the commands make it the service. | 295 // Make sure the commands make it the service. |
| 281 WaitForCmd(); | 296 WaitForCmd(); |
| 282 } | 297 } |
| 283 | 298 |
| 284 GLES2CmdHelper* GLES2Implementation::helper() const { | 299 GLES2CmdHelper* GLES2Implementation::helper() const { |
| 285 return helper_; | 300 return helper_; |
| 286 } | 301 } |
| 287 | 302 |
| 288 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { | 303 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { |
| 289 return share_group_->GetIdHandler(namespace_id); | 304 return share_group_->GetIdHandler(namespace_id); |
| (...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1371 return; | 1386 return; |
| 1372 } | 1387 } |
| 1373 | 1388 |
| 1374 GLuint buffer_id; | 1389 GLuint buffer_id; |
| 1375 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { | 1390 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { |
| 1376 if (!buffer_id) { | 1391 if (!buffer_id) { |
| 1377 return; | 1392 return; |
| 1378 } | 1393 } |
| 1379 | 1394 |
| 1380 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | 1395 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 1381 if (buffer) { | 1396 if (buffer) |
| 1382 // Free buffer memory, pending the passage of a token. | 1397 RemoveTransferBuffer(buffer); |
| 1383 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | |
| 1384 | |
| 1385 // Remove old buffer. | |
| 1386 buffer_tracker_->RemoveBuffer(buffer_id); | |
| 1387 } | |
| 1388 | 1398 |
| 1389 // Create new buffer. | 1399 // Create new buffer. |
| 1390 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); | 1400 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); |
| 1391 DCHECK(buffer); | 1401 DCHECK(buffer); |
| 1392 if (buffer->address() && data) | 1402 if (buffer->address() && data) |
| 1393 memcpy(buffer->address(), data, size); | 1403 memcpy(buffer->address(), data, size); |
| 1394 return; | 1404 return; |
| 1395 } | 1405 } |
| 1396 | 1406 |
| 1397 if (size == 0) { | 1407 if (size == 0) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1505 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1515 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
| 1506 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1516 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1507 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" | 1517 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" |
| 1508 << GLES2Util::GetStringBufferTarget(target) << ", " | 1518 << GLES2Util::GetStringBufferTarget(target) << ", " |
| 1509 << offset << ", " << size << ", " | 1519 << offset << ", " << size << ", " |
| 1510 << static_cast<const void*>(data) << ")"); | 1520 << static_cast<const void*>(data) << ")"); |
| 1511 BufferSubDataHelper(target, offset, size, data); | 1521 BufferSubDataHelper(target, offset, size, data); |
| 1512 CheckGLError(); | 1522 CheckGLError(); |
| 1513 } | 1523 } |
| 1514 | 1524 |
| 1525 void GLES2Implementation::RemoveTransferBuffer(BufferTracker::Buffer* buffer) { | |
| 1526 int32 token = buffer->last_usage_token(); | |
| 1527 uint32 async_token = buffer->async_token(); | |
| 1528 | |
| 1529 base::subtle::MemoryBarrier(); | |
|
epennerAtGoogle
2014/02/07 20:43:58
See nit on other MemoryBarrier. This one also seem
| |
| 1530 | |
| 1531 if (async_token) { | |
| 1532 if (HasAsyncUploadTokenPassed(async_token)) { | |
| 1533 buffer_tracker_->Free(buffer); | |
| 1534 } else { | |
| 1535 detached_async_upload_memory_.push_back( | |
| 1536 std::make_pair(buffer->address(), async_token)); | |
| 1537 buffer_tracker_->Unmanage(buffer); | |
| 1538 } | |
| 1539 } else if (token) { | |
| 1540 if (helper_->HasTokenPassed(token)) | |
| 1541 buffer_tracker_->Free(buffer); | |
| 1542 else | |
| 1543 buffer_tracker_->FreePendingToken(buffer, token); | |
| 1544 } else { | |
| 1545 buffer_tracker_->Free(buffer); | |
| 1546 } | |
| 1547 | |
| 1548 buffer_tracker_->RemoveBuffer(buffer->id()); | |
| 1549 } | |
| 1550 | |
| 1515 bool GLES2Implementation::GetBoundPixelTransferBuffer( | 1551 bool GLES2Implementation::GetBoundPixelTransferBuffer( |
| 1516 GLenum target, | 1552 GLenum target, |
| 1517 const char* function_name, | 1553 const char* function_name, |
| 1518 GLuint* buffer_id) { | 1554 GLuint* buffer_id) { |
| 1519 *buffer_id = 0; | 1555 *buffer_id = 0; |
| 1520 | 1556 |
| 1521 switch (target) { | 1557 switch (target) { |
| 1522 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | 1558 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| 1523 *buffer_id = bound_pixel_pack_transfer_buffer_id_; | 1559 *buffer_id = bound_pixel_pack_transfer_buffer_id_; |
| 1524 break; | 1560 break; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1580 // CompressedTexImage2D. | 1616 // CompressedTexImage2D. |
| 1581 if (bound_pixel_unpack_transfer_buffer_id_) { | 1617 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1582 GLuint offset = ToGLuint(data); | 1618 GLuint offset = ToGLuint(data); |
| 1583 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1619 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1584 bound_pixel_unpack_transfer_buffer_id_, | 1620 bound_pixel_unpack_transfer_buffer_id_, |
| 1585 "glCompressedTexImage2D", offset, image_size); | 1621 "glCompressedTexImage2D", offset, image_size); |
| 1586 if (buffer && buffer->shm_id() != -1) { | 1622 if (buffer && buffer->shm_id() != -1) { |
| 1587 helper_->CompressedTexImage2D( | 1623 helper_->CompressedTexImage2D( |
| 1588 target, level, internalformat, width, height, border, image_size, | 1624 target, level, internalformat, width, height, border, image_size, |
| 1589 buffer->shm_id(), buffer->shm_offset() + offset); | 1625 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1590 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1626 buffer->set_last_usage_token(helper_->InsertToken()); |
| 1591 } | 1627 } |
| 1592 return; | 1628 return; |
| 1593 } | 1629 } |
| 1594 SetBucketContents(kResultBucketId, data, image_size); | 1630 SetBucketContents(kResultBucketId, data, image_size); |
| 1595 helper_->CompressedTexImage2DBucket( | 1631 helper_->CompressedTexImage2DBucket( |
| 1596 target, level, internalformat, width, height, border, kResultBucketId); | 1632 target, level, internalformat, width, height, border, kResultBucketId); |
| 1597 // Free the bucket. This is not required but it does free up the memory. | 1633 // Free the bucket. This is not required but it does free up the memory. |
| 1598 // and we don't have to wait for the result so from the client's perspective | 1634 // and we don't have to wait for the result so from the client's perspective |
| 1599 // it's cheap. | 1635 // it's cheap. |
| 1600 helper_->SetBucketSize(kResultBucketId, 0); | 1636 helper_->SetBucketSize(kResultBucketId, 0); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1621 // CompressedTexSubImage2D. | 1657 // CompressedTexSubImage2D. |
| 1622 if (bound_pixel_unpack_transfer_buffer_id_) { | 1658 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1623 GLuint offset = ToGLuint(data); | 1659 GLuint offset = ToGLuint(data); |
| 1624 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1660 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1625 bound_pixel_unpack_transfer_buffer_id_, | 1661 bound_pixel_unpack_transfer_buffer_id_, |
| 1626 "glCompressedTexSubImage2D", offset, image_size); | 1662 "glCompressedTexSubImage2D", offset, image_size); |
| 1627 if (buffer && buffer->shm_id() != -1) { | 1663 if (buffer && buffer->shm_id() != -1) { |
| 1628 helper_->CompressedTexSubImage2D( | 1664 helper_->CompressedTexSubImage2D( |
| 1629 target, level, xoffset, yoffset, width, height, format, image_size, | 1665 target, level, xoffset, yoffset, width, height, format, image_size, |
| 1630 buffer->shm_id(), buffer->shm_offset() + offset); | 1666 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1631 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1667 buffer->set_last_usage_token(helper_->InsertToken()); |
| 1632 CheckGLError(); | 1668 CheckGLError(); |
| 1633 } | 1669 } |
| 1634 return; | 1670 return; |
| 1635 } | 1671 } |
| 1636 SetBucketContents(kResultBucketId, data, image_size); | 1672 SetBucketContents(kResultBucketId, data, image_size); |
| 1637 helper_->CompressedTexSubImage2DBucket( | 1673 helper_->CompressedTexSubImage2DBucket( |
| 1638 target, level, xoffset, yoffset, width, height, format, kResultBucketId); | 1674 target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
| 1639 // Free the bucket. This is not required but it does free up the memory. | 1675 // Free the bucket. This is not required but it does free up the memory. |
| 1640 // and we don't have to wait for the result so from the client's perspective | 1676 // and we don't have to wait for the result so from the client's perspective |
| 1641 // it's cheap. | 1677 // it's cheap. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1708 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. | 1744 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
| 1709 if (bound_pixel_unpack_transfer_buffer_id_) { | 1745 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1710 GLuint offset = ToGLuint(pixels); | 1746 GLuint offset = ToGLuint(pixels); |
| 1711 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1747 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1712 bound_pixel_unpack_transfer_buffer_id_, | 1748 bound_pixel_unpack_transfer_buffer_id_, |
| 1713 "glTexImage2D", offset, size); | 1749 "glTexImage2D", offset, size); |
| 1714 if (buffer && buffer->shm_id() != -1) { | 1750 if (buffer && buffer->shm_id() != -1) { |
| 1715 helper_->TexImage2D( | 1751 helper_->TexImage2D( |
| 1716 target, level, internalformat, width, height, border, format, type, | 1752 target, level, internalformat, width, height, border, format, type, |
| 1717 buffer->shm_id(), buffer->shm_offset() + offset); | 1753 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1718 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1754 buffer->set_last_usage_token(helper_->InsertToken()); |
| 1719 CheckGLError(); | 1755 CheckGLError(); |
| 1720 } | 1756 } |
| 1721 return; | 1757 return; |
| 1722 } | 1758 } |
| 1723 | 1759 |
| 1724 // If there's no data just issue TexImage2D | 1760 // If there's no data just issue TexImage2D |
| 1725 if (!pixels) { | 1761 if (!pixels) { |
| 1726 helper_->TexImage2D( | 1762 helper_->TexImage2D( |
| 1727 target, level, internalformat, width, height, border, format, type, | 1763 target, level, internalformat, width, height, border, format, type, |
| 1728 0, 0); | 1764 0, 0); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1814 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | 1850 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
| 1815 if (bound_pixel_unpack_transfer_buffer_id_) { | 1851 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1816 GLuint offset = ToGLuint(pixels); | 1852 GLuint offset = ToGLuint(pixels); |
| 1817 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1853 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1818 bound_pixel_unpack_transfer_buffer_id_, | 1854 bound_pixel_unpack_transfer_buffer_id_, |
| 1819 "glTexSubImage2D", offset, temp_size); | 1855 "glTexSubImage2D", offset, temp_size); |
| 1820 if (buffer && buffer->shm_id() != -1) { | 1856 if (buffer && buffer->shm_id() != -1) { |
| 1821 helper_->TexSubImage2D( | 1857 helper_->TexSubImage2D( |
| 1822 target, level, xoffset, yoffset, width, height, format, type, | 1858 target, level, xoffset, yoffset, width, height, format, type, |
| 1823 buffer->shm_id(), buffer->shm_offset() + offset, false); | 1859 buffer->shm_id(), buffer->shm_offset() + offset, false); |
| 1824 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1860 buffer->set_last_usage_token(helper_->InsertToken()); |
| 1825 CheckGLError(); | 1861 CheckGLError(); |
| 1826 } | 1862 } |
| 1827 return; | 1863 return; |
| 1828 } | 1864 } |
| 1829 | 1865 |
| 1830 // compute the advance bytes per row for the src pixels | 1866 // compute the advance bytes per row for the src pixels |
| 1831 uint32 src_padded_row_size; | 1867 uint32 src_padded_row_size; |
| 1832 if (unpack_row_length_ > 0) { | 1868 if (unpack_row_length_ > 0) { |
| 1833 if (!GLES2Util::ComputeImagePaddedRowSize( | 1869 if (!GLES2Util::ComputeImagePaddedRowSize( |
| 1834 unpack_row_length_, format, type, unpack_alignment_, | 1870 unpack_row_length_, format, type, unpack_alignment_, |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2397 } | 2433 } |
| 2398 | 2434 |
| 2399 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id | 2435 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id |
| 2400 // generates a new resource. On newer versions of OpenGL they don't. The code | 2436 // generates a new resource. On newer versions of OpenGL they don't. The code |
| 2401 // related to binding below will need to change if we switch to the new OpenGL | 2437 // related to binding below will need to change if we switch to the new OpenGL |
| 2402 // model. Specifically it assumes a bind will succeed which is always true in | 2438 // model. Specifically it assumes a bind will succeed which is always true in |
| 2403 // the old model but possibly not true in the new model if another context has | 2439 // the old model but possibly not true in the new model if another context has |
| 2404 // deleted the resource. | 2440 // deleted the resource. |
| 2405 | 2441 |
| 2406 bool GLES2Implementation::BindBufferHelper( | 2442 bool GLES2Implementation::BindBufferHelper( |
| 2407 GLenum target, GLuint buffer) { | 2443 GLenum target, GLuint buffer_id) { |
| 2408 // TODO(gman): See note #1 above. | 2444 // TODO(gman): See note #1 above. |
| 2409 bool changed = false; | 2445 bool changed = false; |
| 2410 switch (target) { | 2446 switch (target) { |
| 2411 case GL_ARRAY_BUFFER: | 2447 case GL_ARRAY_BUFFER: |
| 2412 if (bound_array_buffer_id_ != buffer) { | 2448 if (bound_array_buffer_id_ != buffer_id) { |
| 2413 bound_array_buffer_id_ = buffer; | 2449 bound_array_buffer_id_ = buffer_id; |
| 2414 changed = true; | 2450 changed = true; |
| 2415 } | 2451 } |
| 2416 break; | 2452 break; |
| 2417 case GL_ELEMENT_ARRAY_BUFFER: | 2453 case GL_ELEMENT_ARRAY_BUFFER: |
| 2418 changed = vertex_array_object_manager_->BindElementArray(buffer); | 2454 changed = vertex_array_object_manager_->BindElementArray(buffer_id); |
| 2419 break; | 2455 break; |
| 2420 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | 2456 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| 2421 bound_pixel_pack_transfer_buffer_id_ = buffer; | 2457 bound_pixel_pack_transfer_buffer_id_ = buffer_id; |
| 2422 break; | 2458 break; |
| 2423 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | 2459 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| 2424 bound_pixel_unpack_transfer_buffer_id_ = buffer; | 2460 bound_pixel_unpack_transfer_buffer_id_ = buffer_id; |
| 2425 break; | 2461 break; |
| 2426 default: | 2462 default: |
| 2427 changed = true; | 2463 changed = true; |
| 2428 break; | 2464 break; |
| 2429 } | 2465 } |
| 2430 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2466 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
| 2431 // used even though it's marked it as used here. | 2467 // used even though it's marked it as used here. |
| 2432 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2468 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer_id); |
| 2433 return changed; | 2469 return changed; |
| 2434 } | 2470 } |
| 2435 | 2471 |
| 2436 bool GLES2Implementation::BindFramebufferHelper( | 2472 bool GLES2Implementation::BindFramebufferHelper( |
| 2437 GLenum target, GLuint framebuffer) { | 2473 GLenum target, GLuint framebuffer) { |
| 2438 // TODO(gman): See note #1 above. | 2474 // TODO(gman): See note #1 above. |
| 2439 bool changed = false; | 2475 bool changed = false; |
| 2440 switch (target) { | 2476 switch (target) { |
| 2441 case GL_FRAMEBUFFER: | 2477 case GL_FRAMEBUFFER: |
| 2442 if (bound_framebuffer_ != framebuffer || | 2478 if (bound_framebuffer_ != framebuffer || |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2556 SetGLError( | 2592 SetGLError( |
| 2557 GL_INVALID_VALUE, | 2593 GL_INVALID_VALUE, |
| 2558 "glDeleteBuffers", "id not created by this context."); | 2594 "glDeleteBuffers", "id not created by this context."); |
| 2559 return; | 2595 return; |
| 2560 } | 2596 } |
| 2561 for (GLsizei ii = 0; ii < n; ++ii) { | 2597 for (GLsizei ii = 0; ii < n; ++ii) { |
| 2562 if (buffers[ii] == bound_array_buffer_id_) { | 2598 if (buffers[ii] == bound_array_buffer_id_) { |
| 2563 bound_array_buffer_id_ = 0; | 2599 bound_array_buffer_id_ = 0; |
| 2564 } | 2600 } |
| 2565 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); | 2601 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); |
| 2602 | |
| 2566 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); | 2603 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
| 2567 if (buffer) { | 2604 if (buffer) |
| 2568 // Free buffer memory, pending the passage of a token. | 2605 RemoveTransferBuffer(buffer); |
| 2569 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | 2606 |
| 2570 // Remove buffer. | |
| 2571 buffer_tracker_->RemoveBuffer(buffers[ii]); | |
| 2572 } | |
| 2573 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { | 2607 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
| 2574 bound_pixel_unpack_transfer_buffer_id_ = 0; | 2608 bound_pixel_unpack_transfer_buffer_id_ = 0; |
| 2575 } | 2609 } |
| 2576 } | 2610 } |
| 2577 } | 2611 } |
| 2578 | 2612 |
| 2579 void GLES2Implementation::DeleteBuffersStub( | 2613 void GLES2Implementation::DeleteBuffersStub( |
| 2580 GLsizei n, const GLuint* buffers) { | 2614 GLsizei n, const GLuint* buffers) { |
| 2581 helper_->DeleteBuffersImmediate(n, buffers); | 2615 helper_->DeleteBuffersImmediate(n, buffers); |
| 2582 } | 2616 } |
| (...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3584 } | 3618 } |
| 3585 if (buffer->mapped()) { | 3619 if (buffer->mapped()) { |
| 3586 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); | 3620 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); |
| 3587 return NULL; | 3621 return NULL; |
| 3588 } | 3622 } |
| 3589 // Here we wait for previous transfer operations to be finished. | 3623 // Here we wait for previous transfer operations to be finished. |
| 3590 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work | 3624 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work |
| 3591 // with this method of synchronization. Until this is fixed, | 3625 // with this method of synchronization. Until this is fixed, |
| 3592 // MapBufferCHROMIUM will not block even if the transfer is not ready | 3626 // MapBufferCHROMIUM will not block even if the transfer is not ready |
| 3593 // for these calls. | 3627 // for these calls. |
| 3594 if (buffer->transfer_ready_token()) { | 3628 if (buffer->last_usage_token()) { |
| 3595 helper_->WaitForToken(buffer->transfer_ready_token()); | 3629 helper_->WaitForToken(buffer->last_usage_token()); |
| 3596 buffer->set_transfer_ready_token(0); | 3630 buffer->set_last_usage_token(0); |
| 3597 } | 3631 } |
| 3598 buffer->set_mapped(true); | 3632 buffer->set_mapped(true); |
| 3599 | 3633 |
| 3600 GPU_CLIENT_LOG(" returned " << buffer->address()); | 3634 GPU_CLIENT_LOG(" returned " << buffer->address()); |
| 3601 CheckGLError(); | 3635 CheckGLError(); |
| 3602 return buffer->address(); | 3636 return buffer->address(); |
| 3603 } | 3637 } |
| 3604 | 3638 |
| 3605 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { | 3639 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
| 3606 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3640 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 3620 } | 3654 } |
| 3621 if (!buffer->mapped()) { | 3655 if (!buffer->mapped()) { |
| 3622 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); | 3656 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); |
| 3623 return false; | 3657 return false; |
| 3624 } | 3658 } |
| 3625 buffer->set_mapped(false); | 3659 buffer->set_mapped(false); |
| 3626 CheckGLError(); | 3660 CheckGLError(); |
| 3627 return true; | 3661 return true; |
| 3628 } | 3662 } |
| 3629 | 3663 |
| 3664 bool GLES2Implementation::EnsureAsyncUploadSync() { | |
| 3665 if (async_upload_sync_) | |
| 3666 return true; | |
| 3667 | |
| 3668 int32 shm_id; | |
| 3669 unsigned int shm_offset; | |
| 3670 void* mem = mapped_memory_->Alloc(sizeof(AsyncUploadSync), | |
| 3671 &shm_id, | |
| 3672 &shm_offset); | |
| 3673 if (!mem) | |
| 3674 return false; | |
| 3675 | |
| 3676 async_upload_sync_shm_id_ = shm_id; | |
| 3677 async_upload_sync_shm_offset_ = shm_offset; | |
| 3678 async_upload_sync_ = static_cast<AsyncUploadSync*>(mem); | |
| 3679 async_upload_sync_->Reset(); | |
| 3680 | |
| 3681 return true; | |
| 3682 } | |
| 3683 | |
| 3684 uint32 GLES2Implementation::NextAsyncUploadToken() { | |
| 3685 async_upload_token_++; | |
| 3686 if (async_upload_token_ == 0) | |
| 3687 async_upload_token_++; | |
| 3688 return async_upload_token_; | |
| 3689 } | |
| 3690 | |
| 3691 void GLES2Implementation::PollAsyncUploads(bool wait) { | |
| 3692 if (!async_upload_sync_) | |
| 3693 return; | |
| 3694 | |
| 3695 do { | |
| 3696 base::subtle::MemoryBarrier(); | |
|
epennerAtGoogle
2014/02/07 20:43:58
It wouldn't hurt to document each of these base::s
piman
2014/02/07 22:58:20
TBH, I'd rather make the access to the AsyncUpload
jadahl
2014/02/08 09:18:25
To be honest, I added the barrier here mostly beca
piman
2014/02/11 00:09:09
Some useful background: http://software.intel.com/
| |
| 3697 DetachedAsyncUploadMemoryList::iterator it = | |
| 3698 detached_async_upload_memory_.begin(); | |
| 3699 while (it != detached_async_upload_memory_.end()) { | |
| 3700 if (HasAsyncUploadTokenPassed(it->second)) { | |
|
piman
2014/02/07 22:58:20
Similar to what I mentioned in FencedAllocator, we
| |
| 3701 mapped_memory_->Free(it->first); | |
| 3702 it = detached_async_upload_memory_.erase(it); | |
| 3703 } else { | |
| 3704 break; | |
| 3705 } | |
| 3706 } | |
| 3707 if (wait) | |
| 3708 WaitForCmd(); | |
|
piman
2014/02/07 22:58:20
We need more than this, otherwise we'll spin loop
| |
| 3709 } while (!detached_async_upload_memory_.empty() && wait); | |
| 3710 } | |
| 3711 | |
| 3630 void GLES2Implementation::AsyncTexImage2DCHROMIUM( | 3712 void GLES2Implementation::AsyncTexImage2DCHROMIUM( |
| 3631 GLenum target, GLint level, GLint internalformat, GLsizei width, | 3713 GLenum target, GLint level, GLint internalformat, GLsizei width, |
| 3632 GLsizei height, GLint border, GLenum format, GLenum type, | 3714 GLsizei height, GLint border, GLenum format, GLenum type, |
| 3633 const void* pixels) { | 3715 const void* pixels) { |
| 3634 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3716 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3635 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" | 3717 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" |
| 3636 << GLES2Util::GetStringTextureTarget(target) << ", " | 3718 << GLES2Util::GetStringTextureTarget(target) << ", " |
| 3637 << level << ", " | 3719 << level << ", " |
| 3638 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " | 3720 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " |
| 3639 << width << ", " << height << ", " << border << ", " | 3721 << width << ", " << height << ", " << border << ", " |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 3651 width, height, format, type, unpack_alignment_, &size, | 3733 width, height, format, type, unpack_alignment_, &size, |
| 3652 &unpadded_row_size, &padded_row_size)) { | 3734 &unpadded_row_size, &padded_row_size)) { |
| 3653 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); | 3735 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
| 3654 return; | 3736 return; |
| 3655 } | 3737 } |
| 3656 | 3738 |
| 3657 // If there's no data/buffer just issue the AsyncTexImage2D | 3739 // If there's no data/buffer just issue the AsyncTexImage2D |
| 3658 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { | 3740 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { |
| 3659 helper_->AsyncTexImage2DCHROMIUM( | 3741 helper_->AsyncTexImage2DCHROMIUM( |
| 3660 target, level, internalformat, width, height, border, format, type, | 3742 target, level, internalformat, width, height, border, format, type, |
| 3661 0, 0); | 3743 0, 0, 0, 0, 0); |
| 3662 return; | 3744 return; |
| 3663 } | 3745 } |
| 3664 | 3746 |
| 3747 if (!EnsureAsyncUploadSync()) { | |
| 3748 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory"); | |
| 3749 return; | |
| 3750 } | |
| 3751 | |
| 3665 // Otherwise, async uploads require a transfer buffer to be bound. | 3752 // Otherwise, async uploads require a transfer buffer to be bound. |
| 3666 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use | 3753 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use |
| 3667 // the buffer before the transfer is finished. (Currently such | 3754 // the buffer before the transfer is finished. (Currently such |
| 3668 // synchronization has to be handled manually.) | 3755 // synchronization has to be handled manually.) |
| 3669 GLuint offset = ToGLuint(pixels); | 3756 GLuint offset = ToGLuint(pixels); |
| 3670 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3757 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 3671 bound_pixel_unpack_transfer_buffer_id_, | 3758 bound_pixel_unpack_transfer_buffer_id_, |
| 3672 "glAsyncTexImage2DCHROMIUM", offset, size); | 3759 "glAsyncTexImage2DCHROMIUM", offset, size); |
| 3673 if (buffer && buffer->shm_id() != -1) { | 3760 if (buffer && buffer->shm_id() != -1) { |
| 3761 uint32 async_token = NextAsyncUploadToken(); | |
| 3762 buffer->set_async_token(async_token); | |
| 3674 helper_->AsyncTexImage2DCHROMIUM( | 3763 helper_->AsyncTexImage2DCHROMIUM( |
| 3675 target, level, internalformat, width, height, border, format, type, | 3764 target, level, internalformat, width, height, border, format, type, |
| 3676 buffer->shm_id(), buffer->shm_offset() + offset); | 3765 buffer->shm_id(), buffer->shm_offset() + offset, |
| 3766 async_token, | |
| 3767 async_upload_sync_shm_id_, async_upload_sync_shm_offset_); | |
| 3677 } | 3768 } |
| 3678 } | 3769 } |
| 3679 | 3770 |
| 3680 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( | 3771 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( |
| 3681 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 3772 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
| 3682 GLsizei height, GLenum format, GLenum type, const void* pixels) { | 3773 GLsizei height, GLenum format, GLenum type, const void* pixels) { |
| 3683 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3774 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3684 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" | 3775 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" |
| 3685 << GLES2Util::GetStringTextureTarget(target) << ", " | 3776 << GLES2Util::GetStringTextureTarget(target) << ", " |
| 3686 << level << ", " | 3777 << level << ", " |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 3699 uint32 unpadded_row_size; | 3790 uint32 unpadded_row_size; |
| 3700 uint32 padded_row_size; | 3791 uint32 padded_row_size; |
| 3701 if (!GLES2Util::ComputeImageDataSizes( | 3792 if (!GLES2Util::ComputeImageDataSizes( |
| 3702 width, height, format, type, unpack_alignment_, &size, | 3793 width, height, format, type, unpack_alignment_, &size, |
| 3703 &unpadded_row_size, &padded_row_size)) { | 3794 &unpadded_row_size, &padded_row_size)) { |
| 3704 SetGLError( | 3795 SetGLError( |
| 3705 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); | 3796 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); |
| 3706 return; | 3797 return; |
| 3707 } | 3798 } |
| 3708 | 3799 |
| 3800 if (!EnsureAsyncUploadSync()) { | |
| 3801 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory"); | |
| 3802 return; | |
| 3803 } | |
| 3804 | |
| 3709 // Async uploads require a transfer buffer to be bound. | 3805 // Async uploads require a transfer buffer to be bound. |
| 3710 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use | 3806 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use |
| 3711 // the buffer before the transfer is finished. (Currently such | 3807 // the buffer before the transfer is finished. (Currently such |
| 3712 // synchronization has to be handled manually.) | 3808 // synchronization has to be handled manually.) |
| 3713 GLuint offset = ToGLuint(pixels); | 3809 GLuint offset = ToGLuint(pixels); |
| 3714 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3810 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 3715 bound_pixel_unpack_transfer_buffer_id_, | 3811 bound_pixel_unpack_transfer_buffer_id_, |
| 3716 "glAsyncTexSubImage2DCHROMIUM", offset, size); | 3812 "glAsyncTexSubImage2DCHROMIUM", offset, size); |
| 3717 if (buffer && buffer->shm_id() != -1) { | 3813 if (buffer && buffer->shm_id() != -1) { |
| 3814 uint32 async_token = NextAsyncUploadToken(); | |
| 3815 buffer->set_async_token(async_token); | |
| 3718 helper_->AsyncTexSubImage2DCHROMIUM( | 3816 helper_->AsyncTexSubImage2DCHROMIUM( |
| 3719 target, level, xoffset, yoffset, width, height, format, type, | 3817 target, level, xoffset, yoffset, width, height, format, type, |
| 3720 buffer->shm_id(), buffer->shm_offset() + offset); | 3818 buffer->shm_id(), buffer->shm_offset() + offset, |
| 3819 async_token, | |
| 3820 async_upload_sync_shm_id_, async_upload_sync_shm_offset_); | |
| 3721 } | 3821 } |
| 3722 } | 3822 } |
| 3723 | 3823 |
| 3724 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { | 3824 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { |
| 3725 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3825 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3726 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM(" | 3826 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM(" |
| 3727 << GLES2Util::GetStringTextureTarget(target) << ")"); | 3827 << GLES2Util::GetStringTextureTarget(target) << ")"); |
| 3728 helper_->WaitAsyncTexImage2DCHROMIUM(target); | 3828 helper_->WaitAsyncTexImage2DCHROMIUM(target); |
| 3729 CheckGLError(); | 3829 CheckGLError(); |
| 3730 } | 3830 } |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3897 CheckGLError(); | 3997 CheckGLError(); |
| 3898 } | 3998 } |
| 3899 | 3999 |
| 3900 // Include the auto-generated part of this file. We split this because it means | 4000 // Include the auto-generated part of this file. We split this because it means |
| 3901 // we can easily edit the non-auto generated parts right here in this file | 4001 // we can easily edit the non-auto generated parts right here in this file |
| 3902 // instead of having to edit some template or the code generator. | 4002 // instead of having to edit some template or the code generator. |
| 3903 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 4003 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
| 3904 | 4004 |
| 3905 } // namespace gles2 | 4005 } // namespace gles2 |
| 3906 } // namespace gpu | 4006 } // namespace gpu |
| OLD | NEW |