Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Side by Side Diff: gpu/command_buffer/client/gles2_implementation.cc

Issue 116863003: gpu: Reuse transfer buffers more aggresively (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Added glWaitAllAsyncTexImage2DCHROMIUM; other review issues addressed Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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_token_(0),
112 async_upload_sync_(NULL),
110 error_bits_(0), 113 error_bits_(0),
111 debug_(false), 114 debug_(false),
112 use_count_(0), 115 use_count_(0),
113 error_message_callback_(NULL), 116 error_message_callback_(NULL),
114 gpu_control_(gpu_control), 117 gpu_control_(gpu_control),
115 surface_visible_(true), 118 surface_visible_(true),
116 free_everything_when_invisible_(free_everything_when_invisible), 119 free_everything_when_invisible_(free_everything_when_invisible),
117 capabilities_(gpu_control->GetCapabilities()), 120 capabilities_(gpu_control->GetCapabilities()),
118 weak_ptr_factory_(this) { 121 weak_ptr_factory_(this) {
119 DCHECK(helper); 122 DCHECK(helper);
(...skipping 27 matching lines...) Expand all
147 if (!transfer_buffer_->Initialize( 150 if (!transfer_buffer_->Initialize(
148 starting_transfer_buffer_size, 151 starting_transfer_buffer_size,
149 kStartingOffset, 152 kStartingOffset,
150 min_transfer_buffer_size, 153 min_transfer_buffer_size,
151 max_transfer_buffer_size, 154 max_transfer_buffer_size,
152 kAlignment, 155 kAlignment,
153 kSizeToFlush)) { 156 kSizeToFlush)) {
154 return false; 157 return false;
155 } 158 }
156 159
157 mapped_memory_.reset(new MappedMemoryManager(helper_, mapped_memory_limit)); 160 mapped_memory_.reset(
161 new MappedMemoryManager(
162 helper_,
163 base::Bind(&GLES2Implementation::PollAsyncUploads,
164 // The mapped memory manager is owned by |this| here, and
165 // since its destroyed before before we destroy ourselves
166 // we don't need extra safety measures for this closure.
167 base::Unretained(this)),
168 mapped_memory_limit));
158 169
159 unsigned chunk_size = 2 * 1024 * 1024; 170 unsigned chunk_size = 2 * 1024 * 1024;
160 if (mapped_memory_limit != kNoLimit) { 171 if (mapped_memory_limit != kNoLimit) {
161 // Use smaller chunks if the client is very memory conscientious. 172 // Use smaller chunks if the client is very memory conscientious.
162 chunk_size = std::min(mapped_memory_limit / 4, chunk_size); 173 chunk_size = std::min(mapped_memory_limit / 4, chunk_size);
163 } 174 }
164 mapped_memory_->set_chunk_size_multiple(chunk_size); 175 mapped_memory_->set_chunk_size_multiple(chunk_size);
165 176
166 if (!QueryAndCacheStaticState()) 177 if (!QueryAndCacheStaticState())
167 return false; 178 return false;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 // by the queries. The GPU process when validating that memory is still 281 // by the queries. The GPU process when validating that memory is still
271 // shared will fail and abort (ie, it will stop running). 282 // shared will fail and abort (ie, it will stop running).
272 WaitForCmd(); 283 WaitForCmd();
273 query_tracker_.reset(); 284 query_tracker_.reset();
274 285
275 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 286 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
276 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); 287 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]);
277 #endif 288 #endif
278 buffer_tracker_.reset(); 289 buffer_tracker_.reset();
279 290
291 // Free all completed unmanaged async uploads buffers.
292 PollAsyncUploads();
293
294 // Synchronously free rest of the unmanaged async upload buffers.
295 if (!detached_async_upload_memory_.empty()) {
296 WaitAllAsyncTexImage2DCHROMIUM();
297 WaitForCmd();
298 PollAsyncUploads();
299 }
piman 2014/02/20 01:52:37 It would be nice to do this in FreeEverything too.
300
301 if (async_upload_sync_) {
302 mapped_memory_->Free(async_upload_sync_);
303 async_upload_sync_ = NULL;
304 }
305
280 // Make sure the commands make it the service. 306 // Make sure the commands make it the service.
281 WaitForCmd(); 307 WaitForCmd();
282 } 308 }
283 309
284 GLES2CmdHelper* GLES2Implementation::helper() const { 310 GLES2CmdHelper* GLES2Implementation::helper() const {
285 return helper_; 311 return helper_;
286 } 312 }
287 313
288 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { 314 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const {
289 return share_group_->GetIdHandler(namespace_id); 315 return share_group_->GetIdHandler(namespace_id);
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 return; 1397 return;
1372 } 1398 }
1373 1399
1374 GLuint buffer_id; 1400 GLuint buffer_id;
1375 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { 1401 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) {
1376 if (!buffer_id) { 1402 if (!buffer_id) {
1377 return; 1403 return;
1378 } 1404 }
1379 1405
1380 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); 1406 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
1381 if (buffer) { 1407 if (buffer)
1382 // Free buffer memory, pending the passage of a token. 1408 RemoveTransferBuffer(buffer);
1383 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken());
1384
1385 // Remove old buffer.
1386 buffer_tracker_->RemoveBuffer(buffer_id);
1387 }
1388 1409
1389 // Create new buffer. 1410 // Create new buffer.
1390 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); 1411 buffer = buffer_tracker_->CreateBuffer(buffer_id, size);
1391 DCHECK(buffer); 1412 DCHECK(buffer);
1392 if (buffer->address() && data) 1413 if (buffer->address() && data)
1393 memcpy(buffer->address(), data, size); 1414 memcpy(buffer->address(), data, size);
1394 return; 1415 return;
1395 } 1416 }
1396 1417
1397 if (size == 0) { 1418 if (size == 0) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { 1526 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
1506 GPU_CLIENT_SINGLE_THREAD_CHECK(); 1527 GPU_CLIENT_SINGLE_THREAD_CHECK();
1507 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" 1528 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData("
1508 << GLES2Util::GetStringBufferTarget(target) << ", " 1529 << GLES2Util::GetStringBufferTarget(target) << ", "
1509 << offset << ", " << size << ", " 1530 << offset << ", " << size << ", "
1510 << static_cast<const void*>(data) << ")"); 1531 << static_cast<const void*>(data) << ")");
1511 BufferSubDataHelper(target, offset, size, data); 1532 BufferSubDataHelper(target, offset, size, data);
1512 CheckGLError(); 1533 CheckGLError();
1513 } 1534 }
1514 1535
1536 void GLES2Implementation::RemoveTransferBuffer(BufferTracker::Buffer* buffer) {
1537 int32 token = buffer->last_usage_token();
1538 uint32 async_token = buffer->last_async_upload_token();
1539
1540 base::subtle::MemoryBarrier();
piman 2014/02/20 01:52:37 Because the necessary memory barrier is handled in
1541
1542 if (async_token) {
1543 if (HasAsyncUploadTokenPassed(async_token)) {
1544 buffer_tracker_->Free(buffer);
1545 } else {
1546 detached_async_upload_memory_.push_back(
1547 std::make_pair(buffer->address(), async_token));
1548 buffer_tracker_->Unmanage(buffer);
1549 }
1550 } else if (token) {
1551 if (helper_->HasTokenPassed(token))
1552 buffer_tracker_->Free(buffer);
1553 else
1554 buffer_tracker_->FreePendingToken(buffer, token);
1555 } else {
1556 buffer_tracker_->Free(buffer);
1557 }
1558
1559 buffer_tracker_->RemoveBuffer(buffer->id());
1560 }
1561
1515 bool GLES2Implementation::GetBoundPixelTransferBuffer( 1562 bool GLES2Implementation::GetBoundPixelTransferBuffer(
1516 GLenum target, 1563 GLenum target,
1517 const char* function_name, 1564 const char* function_name,
1518 GLuint* buffer_id) { 1565 GLuint* buffer_id) {
1519 *buffer_id = 0; 1566 *buffer_id = 0;
1520 1567
1521 switch (target) { 1568 switch (target) {
1522 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: 1569 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
1523 *buffer_id = bound_pixel_pack_transfer_buffer_id_; 1570 *buffer_id = bound_pixel_pack_transfer_buffer_id_;
1524 break; 1571 break;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1580 // CompressedTexImage2D. 1627 // CompressedTexImage2D.
1581 if (bound_pixel_unpack_transfer_buffer_id_) { 1628 if (bound_pixel_unpack_transfer_buffer_id_) {
1582 GLuint offset = ToGLuint(data); 1629 GLuint offset = ToGLuint(data);
1583 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1630 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1584 bound_pixel_unpack_transfer_buffer_id_, 1631 bound_pixel_unpack_transfer_buffer_id_,
1585 "glCompressedTexImage2D", offset, image_size); 1632 "glCompressedTexImage2D", offset, image_size);
1586 if (buffer && buffer->shm_id() != -1) { 1633 if (buffer && buffer->shm_id() != -1) {
1587 helper_->CompressedTexImage2D( 1634 helper_->CompressedTexImage2D(
1588 target, level, internalformat, width, height, border, image_size, 1635 target, level, internalformat, width, height, border, image_size,
1589 buffer->shm_id(), buffer->shm_offset() + offset); 1636 buffer->shm_id(), buffer->shm_offset() + offset);
1590 buffer->set_transfer_ready_token(helper_->InsertToken()); 1637 buffer->set_last_usage_token(helper_->InsertToken());
1591 } 1638 }
1592 return; 1639 return;
1593 } 1640 }
1594 SetBucketContents(kResultBucketId, data, image_size); 1641 SetBucketContents(kResultBucketId, data, image_size);
1595 helper_->CompressedTexImage2DBucket( 1642 helper_->CompressedTexImage2DBucket(
1596 target, level, internalformat, width, height, border, kResultBucketId); 1643 target, level, internalformat, width, height, border, kResultBucketId);
1597 // Free the bucket. This is not required but it does free up the memory. 1644 // 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 1645 // and we don't have to wait for the result so from the client's perspective
1599 // it's cheap. 1646 // it's cheap.
1600 helper_->SetBucketSize(kResultBucketId, 0); 1647 helper_->SetBucketSize(kResultBucketId, 0);
(...skipping 20 matching lines...) Expand all
1621 // CompressedTexSubImage2D. 1668 // CompressedTexSubImage2D.
1622 if (bound_pixel_unpack_transfer_buffer_id_) { 1669 if (bound_pixel_unpack_transfer_buffer_id_) {
1623 GLuint offset = ToGLuint(data); 1670 GLuint offset = ToGLuint(data);
1624 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1671 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1625 bound_pixel_unpack_transfer_buffer_id_, 1672 bound_pixel_unpack_transfer_buffer_id_,
1626 "glCompressedTexSubImage2D", offset, image_size); 1673 "glCompressedTexSubImage2D", offset, image_size);
1627 if (buffer && buffer->shm_id() != -1) { 1674 if (buffer && buffer->shm_id() != -1) {
1628 helper_->CompressedTexSubImage2D( 1675 helper_->CompressedTexSubImage2D(
1629 target, level, xoffset, yoffset, width, height, format, image_size, 1676 target, level, xoffset, yoffset, width, height, format, image_size,
1630 buffer->shm_id(), buffer->shm_offset() + offset); 1677 buffer->shm_id(), buffer->shm_offset() + offset);
1631 buffer->set_transfer_ready_token(helper_->InsertToken()); 1678 buffer->set_last_usage_token(helper_->InsertToken());
1632 CheckGLError(); 1679 CheckGLError();
1633 } 1680 }
1634 return; 1681 return;
1635 } 1682 }
1636 SetBucketContents(kResultBucketId, data, image_size); 1683 SetBucketContents(kResultBucketId, data, image_size);
1637 helper_->CompressedTexSubImage2DBucket( 1684 helper_->CompressedTexSubImage2DBucket(
1638 target, level, xoffset, yoffset, width, height, format, kResultBucketId); 1685 target, level, xoffset, yoffset, width, height, format, kResultBucketId);
1639 // Free the bucket. This is not required but it does free up the memory. 1686 // 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 1687 // and we don't have to wait for the result so from the client's perspective
1641 // it's cheap. 1688 // it's cheap.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. 1755 // If there's a pixel unpack buffer bound use it when issuing TexImage2D.
1709 if (bound_pixel_unpack_transfer_buffer_id_) { 1756 if (bound_pixel_unpack_transfer_buffer_id_) {
1710 GLuint offset = ToGLuint(pixels); 1757 GLuint offset = ToGLuint(pixels);
1711 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1758 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1712 bound_pixel_unpack_transfer_buffer_id_, 1759 bound_pixel_unpack_transfer_buffer_id_,
1713 "glTexImage2D", offset, size); 1760 "glTexImage2D", offset, size);
1714 if (buffer && buffer->shm_id() != -1) { 1761 if (buffer && buffer->shm_id() != -1) {
1715 helper_->TexImage2D( 1762 helper_->TexImage2D(
1716 target, level, internalformat, width, height, border, format, type, 1763 target, level, internalformat, width, height, border, format, type,
1717 buffer->shm_id(), buffer->shm_offset() + offset); 1764 buffer->shm_id(), buffer->shm_offset() + offset);
1718 buffer->set_transfer_ready_token(helper_->InsertToken()); 1765 buffer->set_last_usage_token(helper_->InsertToken());
1719 CheckGLError(); 1766 CheckGLError();
1720 } 1767 }
1721 return; 1768 return;
1722 } 1769 }
1723 1770
1724 // If there's no data just issue TexImage2D 1771 // If there's no data just issue TexImage2D
1725 if (!pixels) { 1772 if (!pixels) {
1726 helper_->TexImage2D( 1773 helper_->TexImage2D(
1727 target, level, internalformat, width, height, border, format, type, 1774 target, level, internalformat, width, height, border, format, type,
1728 0, 0); 1775 0, 0);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. 1861 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D.
1815 if (bound_pixel_unpack_transfer_buffer_id_) { 1862 if (bound_pixel_unpack_transfer_buffer_id_) {
1816 GLuint offset = ToGLuint(pixels); 1863 GLuint offset = ToGLuint(pixels);
1817 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1864 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1818 bound_pixel_unpack_transfer_buffer_id_, 1865 bound_pixel_unpack_transfer_buffer_id_,
1819 "glTexSubImage2D", offset, temp_size); 1866 "glTexSubImage2D", offset, temp_size);
1820 if (buffer && buffer->shm_id() != -1) { 1867 if (buffer && buffer->shm_id() != -1) {
1821 helper_->TexSubImage2D( 1868 helper_->TexSubImage2D(
1822 target, level, xoffset, yoffset, width, height, format, type, 1869 target, level, xoffset, yoffset, width, height, format, type,
1823 buffer->shm_id(), buffer->shm_offset() + offset, false); 1870 buffer->shm_id(), buffer->shm_offset() + offset, false);
1824 buffer->set_transfer_ready_token(helper_->InsertToken()); 1871 buffer->set_last_usage_token(helper_->InsertToken());
1825 CheckGLError(); 1872 CheckGLError();
1826 } 1873 }
1827 return; 1874 return;
1828 } 1875 }
1829 1876
1830 // compute the advance bytes per row for the src pixels 1877 // compute the advance bytes per row for the src pixels
1831 uint32 src_padded_row_size; 1878 uint32 src_padded_row_size;
1832 if (unpack_row_length_ > 0) { 1879 if (unpack_row_length_ > 0) {
1833 if (!GLES2Util::ComputeImagePaddedRowSize( 1880 if (!GLES2Util::ComputeImagePaddedRowSize(
1834 unpack_row_length_, format, type, unpack_alignment_, 1881 unpack_row_length_, format, type, unpack_alignment_,
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
2397 } 2444 }
2398 2445
2399 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id 2446 // 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 2447 // 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 2448 // 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 2449 // 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 2450 // the old model but possibly not true in the new model if another context has
2404 // deleted the resource. 2451 // deleted the resource.
2405 2452
2406 bool GLES2Implementation::BindBufferHelper( 2453 bool GLES2Implementation::BindBufferHelper(
2407 GLenum target, GLuint buffer) { 2454 GLenum target, GLuint buffer_id) {
2408 // TODO(gman): See note #1 above. 2455 // TODO(gman): See note #1 above.
2409 bool changed = false; 2456 bool changed = false;
2410 switch (target) { 2457 switch (target) {
2411 case GL_ARRAY_BUFFER: 2458 case GL_ARRAY_BUFFER:
2412 if (bound_array_buffer_id_ != buffer) { 2459 if (bound_array_buffer_id_ != buffer_id) {
2413 bound_array_buffer_id_ = buffer; 2460 bound_array_buffer_id_ = buffer_id;
2414 changed = true; 2461 changed = true;
2415 } 2462 }
2416 break; 2463 break;
2417 case GL_ELEMENT_ARRAY_BUFFER: 2464 case GL_ELEMENT_ARRAY_BUFFER:
2418 changed = vertex_array_object_manager_->BindElementArray(buffer); 2465 changed = vertex_array_object_manager_->BindElementArray(buffer_id);
2419 break; 2466 break;
2420 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: 2467 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
2421 bound_pixel_pack_transfer_buffer_id_ = buffer; 2468 bound_pixel_pack_transfer_buffer_id_ = buffer_id;
2422 break; 2469 break;
2423 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: 2470 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM:
2424 bound_pixel_unpack_transfer_buffer_id_ = buffer; 2471 bound_pixel_unpack_transfer_buffer_id_ = buffer_id;
2425 break; 2472 break;
2426 default: 2473 default:
2427 changed = true; 2474 changed = true;
2428 break; 2475 break;
2429 } 2476 }
2430 // TODO(gman): There's a bug here. If the target is invalid the ID will not be 2477 // 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. 2478 // used even though it's marked it as used here.
2432 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); 2479 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer_id);
2433 return changed; 2480 return changed;
2434 } 2481 }
2435 2482
2436 bool GLES2Implementation::BindFramebufferHelper( 2483 bool GLES2Implementation::BindFramebufferHelper(
2437 GLenum target, GLuint framebuffer) { 2484 GLenum target, GLuint framebuffer) {
2438 // TODO(gman): See note #1 above. 2485 // TODO(gman): See note #1 above.
2439 bool changed = false; 2486 bool changed = false;
2440 switch (target) { 2487 switch (target) {
2441 case GL_FRAMEBUFFER: 2488 case GL_FRAMEBUFFER:
2442 if (bound_framebuffer_ != framebuffer || 2489 if (bound_framebuffer_ != framebuffer ||
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2556 SetGLError( 2603 SetGLError(
2557 GL_INVALID_VALUE, 2604 GL_INVALID_VALUE,
2558 "glDeleteBuffers", "id not created by this context."); 2605 "glDeleteBuffers", "id not created by this context.");
2559 return; 2606 return;
2560 } 2607 }
2561 for (GLsizei ii = 0; ii < n; ++ii) { 2608 for (GLsizei ii = 0; ii < n; ++ii) {
2562 if (buffers[ii] == bound_array_buffer_id_) { 2609 if (buffers[ii] == bound_array_buffer_id_) {
2563 bound_array_buffer_id_ = 0; 2610 bound_array_buffer_id_ = 0;
2564 } 2611 }
2565 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); 2612 vertex_array_object_manager_->UnbindBuffer(buffers[ii]);
2613
2566 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); 2614 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]);
2567 if (buffer) { 2615 if (buffer)
2568 // Free buffer memory, pending the passage of a token. 2616 RemoveTransferBuffer(buffer);
2569 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); 2617
2570 // Remove buffer.
2571 buffer_tracker_->RemoveBuffer(buffers[ii]);
2572 }
2573 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { 2618 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
2574 bound_pixel_unpack_transfer_buffer_id_ = 0; 2619 bound_pixel_unpack_transfer_buffer_id_ = 0;
2575 } 2620 }
2576 } 2621 }
2577 } 2622 }
2578 2623
2579 void GLES2Implementation::DeleteBuffersStub( 2624 void GLES2Implementation::DeleteBuffersStub(
2580 GLsizei n, const GLuint* buffers) { 2625 GLsizei n, const GLuint* buffers) {
2581 helper_->DeleteBuffersImmediate(n, buffers); 2626 helper_->DeleteBuffersImmediate(n, buffers);
2582 } 2627 }
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after
3584 } 3629 }
3585 if (buffer->mapped()) { 3630 if (buffer->mapped()) {
3586 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); 3631 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped");
3587 return NULL; 3632 return NULL;
3588 } 3633 }
3589 // Here we wait for previous transfer operations to be finished. 3634 // Here we wait for previous transfer operations to be finished.
3590 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work 3635 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work
3591 // with this method of synchronization. Until this is fixed, 3636 // with this method of synchronization. Until this is fixed,
3592 // MapBufferCHROMIUM will not block even if the transfer is not ready 3637 // MapBufferCHROMIUM will not block even if the transfer is not ready
3593 // for these calls. 3638 // for these calls.
3594 if (buffer->transfer_ready_token()) { 3639 if (buffer->last_usage_token()) {
3595 helper_->WaitForToken(buffer->transfer_ready_token()); 3640 helper_->WaitForToken(buffer->last_usage_token());
3596 buffer->set_transfer_ready_token(0); 3641 buffer->set_last_usage_token(0);
3597 } 3642 }
3598 buffer->set_mapped(true); 3643 buffer->set_mapped(true);
3599 3644
3600 GPU_CLIENT_LOG(" returned " << buffer->address()); 3645 GPU_CLIENT_LOG(" returned " << buffer->address());
3601 CheckGLError(); 3646 CheckGLError();
3602 return buffer->address(); 3647 return buffer->address();
3603 } 3648 }
3604 3649
3605 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { 3650 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) {
3606 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3651 GPU_CLIENT_SINGLE_THREAD_CHECK();
(...skipping 13 matching lines...) Expand all
3620 } 3665 }
3621 if (!buffer->mapped()) { 3666 if (!buffer->mapped()) {
3622 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); 3667 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped");
3623 return false; 3668 return false;
3624 } 3669 }
3625 buffer->set_mapped(false); 3670 buffer->set_mapped(false);
3626 CheckGLError(); 3671 CheckGLError();
3627 return true; 3672 return true;
3628 } 3673 }
3629 3674
3675 bool GLES2Implementation::EnsureAsyncUploadSync() {
3676 if (async_upload_sync_)
3677 return true;
3678
3679 int32 shm_id;
3680 unsigned int shm_offset;
3681 void* mem = mapped_memory_->Alloc(sizeof(AsyncUploadSync),
3682 &shm_id,
3683 &shm_offset);
3684 if (!mem)
3685 return false;
3686
3687 async_upload_sync_shm_id_ = shm_id;
3688 async_upload_sync_shm_offset_ = shm_offset;
3689 async_upload_sync_ = static_cast<AsyncUploadSync*>(mem);
3690 async_upload_sync_->Reset();
3691
3692 return true;
3693 }
3694
3695 uint32 GLES2Implementation::NextAsyncUploadToken() {
3696 async_upload_token_++;
3697 if (async_upload_token_ == 0)
3698 async_upload_token_++;
3699 return async_upload_token_;
3700 }
3701
3702 void GLES2Implementation::PollAsyncUploads() {
3703 if (!async_upload_sync_)
3704 return;
3705
3706 if (helper_->IsContextLost()) {
3707 DetachedAsyncUploadMemoryList::iterator it =
3708 detached_async_upload_memory_.begin();
3709 while (it != detached_async_upload_memory_.end()) {
3710 mapped_memory_->Free(it->first);
3711 it = detached_async_upload_memory_.erase(it);
3712 }
3713 return;
3714 }
3715
3716 DetachedAsyncUploadMemoryList::iterator it =
3717 detached_async_upload_memory_.begin();
3718 while (it != detached_async_upload_memory_.end()) {
3719 if (HasAsyncUploadTokenPassed(it->second)) {
3720 mapped_memory_->Free(it->first);
3721 it = detached_async_upload_memory_.erase(it);
3722 } else {
3723 break;
3724 }
3725 }
3726 }
3727
3630 void GLES2Implementation::AsyncTexImage2DCHROMIUM( 3728 void GLES2Implementation::AsyncTexImage2DCHROMIUM(
3631 GLenum target, GLint level, GLint internalformat, GLsizei width, 3729 GLenum target, GLint level, GLint internalformat, GLsizei width,
3632 GLsizei height, GLint border, GLenum format, GLenum type, 3730 GLsizei height, GLint border, GLenum format, GLenum type,
3633 const void* pixels) { 3731 const void* pixels) {
3634 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3732 GPU_CLIENT_SINGLE_THREAD_CHECK();
3635 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" 3733 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D("
3636 << GLES2Util::GetStringTextureTarget(target) << ", " 3734 << GLES2Util::GetStringTextureTarget(target) << ", "
3637 << level << ", " 3735 << level << ", "
3638 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " 3736 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", "
3639 << width << ", " << height << ", " << border << ", " 3737 << width << ", " << height << ", " << border << ", "
(...skipping 11 matching lines...) Expand all
3651 width, height, format, type, unpack_alignment_, &size, 3749 width, height, format, type, unpack_alignment_, &size,
3652 &unpadded_row_size, &padded_row_size)) { 3750 &unpadded_row_size, &padded_row_size)) {
3653 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); 3751 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large");
3654 return; 3752 return;
3655 } 3753 }
3656 3754
3657 // If there's no data/buffer just issue the AsyncTexImage2D 3755 // If there's no data/buffer just issue the AsyncTexImage2D
3658 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { 3756 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) {
3659 helper_->AsyncTexImage2DCHROMIUM( 3757 helper_->AsyncTexImage2DCHROMIUM(
3660 target, level, internalformat, width, height, border, format, type, 3758 target, level, internalformat, width, height, border, format, type,
3661 0, 0); 3759 0, 0, 0, 0, 0);
3662 return; 3760 return;
3663 } 3761 }
3664 3762
3763 if (!EnsureAsyncUploadSync()) {
3764 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
3765 return;
3766 }
3767
3665 // Otherwise, async uploads require a transfer buffer to be bound. 3768 // Otherwise, async uploads require a transfer buffer to be bound.
3666 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use 3769 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use
3667 // the buffer before the transfer is finished. (Currently such 3770 // the buffer before the transfer is finished. (Currently such
3668 // synchronization has to be handled manually.) 3771 // synchronization has to be handled manually.)
3669 GLuint offset = ToGLuint(pixels); 3772 GLuint offset = ToGLuint(pixels);
3670 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 3773 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
3671 bound_pixel_unpack_transfer_buffer_id_, 3774 bound_pixel_unpack_transfer_buffer_id_,
3672 "glAsyncTexImage2DCHROMIUM", offset, size); 3775 "glAsyncTexImage2DCHROMIUM", offset, size);
3673 if (buffer && buffer->shm_id() != -1) { 3776 if (buffer && buffer->shm_id() != -1) {
3777 uint32 async_token = NextAsyncUploadToken();
3778 buffer->set_last_async_upload_token(async_token);
3674 helper_->AsyncTexImage2DCHROMIUM( 3779 helper_->AsyncTexImage2DCHROMIUM(
3675 target, level, internalformat, width, height, border, format, type, 3780 target, level, internalformat, width, height, border, format, type,
3676 buffer->shm_id(), buffer->shm_offset() + offset); 3781 buffer->shm_id(), buffer->shm_offset() + offset,
3782 async_token,
3783 async_upload_sync_shm_id_, async_upload_sync_shm_offset_);
3677 } 3784 }
3678 } 3785 }
3679 3786
3680 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( 3787 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM(
3681 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, 3788 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
3682 GLsizei height, GLenum format, GLenum type, const void* pixels) { 3789 GLsizei height, GLenum format, GLenum type, const void* pixels) {
3683 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3790 GPU_CLIENT_SINGLE_THREAD_CHECK();
3684 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" 3791 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM("
3685 << GLES2Util::GetStringTextureTarget(target) << ", " 3792 << GLES2Util::GetStringTextureTarget(target) << ", "
3686 << level << ", " 3793 << level << ", "
(...skipping 12 matching lines...) Expand all
3699 uint32 unpadded_row_size; 3806 uint32 unpadded_row_size;
3700 uint32 padded_row_size; 3807 uint32 padded_row_size;
3701 if (!GLES2Util::ComputeImageDataSizes( 3808 if (!GLES2Util::ComputeImageDataSizes(
3702 width, height, format, type, unpack_alignment_, &size, 3809 width, height, format, type, unpack_alignment_, &size,
3703 &unpadded_row_size, &padded_row_size)) { 3810 &unpadded_row_size, &padded_row_size)) {
3704 SetGLError( 3811 SetGLError(
3705 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); 3812 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large");
3706 return; 3813 return;
3707 } 3814 }
3708 3815
3816 if (!EnsureAsyncUploadSync()) {
3817 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
3818 return;
3819 }
3820
3709 // Async uploads require a transfer buffer to be bound. 3821 // Async uploads require a transfer buffer to be bound.
3710 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use 3822 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use
3711 // the buffer before the transfer is finished. (Currently such 3823 // the buffer before the transfer is finished. (Currently such
3712 // synchronization has to be handled manually.) 3824 // synchronization has to be handled manually.)
3713 GLuint offset = ToGLuint(pixels); 3825 GLuint offset = ToGLuint(pixels);
3714 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 3826 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
3715 bound_pixel_unpack_transfer_buffer_id_, 3827 bound_pixel_unpack_transfer_buffer_id_,
3716 "glAsyncTexSubImage2DCHROMIUM", offset, size); 3828 "glAsyncTexSubImage2DCHROMIUM", offset, size);
3717 if (buffer && buffer->shm_id() != -1) { 3829 if (buffer && buffer->shm_id() != -1) {
3830 uint32 async_token = NextAsyncUploadToken();
3831 buffer->set_last_async_upload_token(async_token);
3718 helper_->AsyncTexSubImage2DCHROMIUM( 3832 helper_->AsyncTexSubImage2DCHROMIUM(
3719 target, level, xoffset, yoffset, width, height, format, type, 3833 target, level, xoffset, yoffset, width, height, format, type,
3720 buffer->shm_id(), buffer->shm_offset() + offset); 3834 buffer->shm_id(), buffer->shm_offset() + offset,
3835 async_token,
3836 async_upload_sync_shm_id_, async_upload_sync_shm_offset_);
3721 } 3837 }
3722 } 3838 }
3723 3839
3724 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { 3840 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) {
3725 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3841 GPU_CLIENT_SINGLE_THREAD_CHECK();
3726 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM(" 3842 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM("
3727 << GLES2Util::GetStringTextureTarget(target) << ")"); 3843 << GLES2Util::GetStringTextureTarget(target) << ")");
3728 helper_->WaitAsyncTexImage2DCHROMIUM(target); 3844 helper_->WaitAsyncTexImage2DCHROMIUM(target);
3729 CheckGLError(); 3845 CheckGLError();
3730 } 3846 }
3731 3847
3848 void GLES2Implementation::WaitAllAsyncTexImage2DCHROMIUM() {
3849 GPU_CLIENT_SINGLE_THREAD_CHECK();
3850 GPU_CLIENT_LOG("[" << GetLogPrefix()
3851 << "] glWaitAllAsyncTexImage2DCHROMIUM()");
3852 helper_->WaitAllAsyncTexImage2DCHROMIUM();
3853 CheckGLError();
3854 }
3855
3732 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { 3856 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() {
3733 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3857 GPU_CLIENT_SINGLE_THREAD_CHECK();
3734 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM"); 3858 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM");
3735 helper_->CommandBufferHelper::Flush(); 3859 helper_->CommandBufferHelper::Flush();
3736 return gpu_control_->InsertSyncPoint(); 3860 return gpu_control_->InsertSyncPoint();
3737 } 3861 }
3738 3862
3739 GLuint GLES2Implementation::CreateImageCHROMIUMHelper( 3863 GLuint GLES2Implementation::CreateImageCHROMIUMHelper(
3740 GLsizei width, GLsizei height, GLenum internalformat) { 3864 GLsizei width, GLsizei height, GLenum internalformat) {
3741 if (width <= 0) { 3865 if (width <= 0) {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
3897 CheckGLError(); 4021 CheckGLError();
3898 } 4022 }
3899 4023
3900 // Include the auto-generated part of this file. We split this because it means 4024 // 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 4025 // 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. 4026 // instead of having to edit some template or the code generator.
3903 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" 4027 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h"
3904 4028
3905 } // namespace gles2 4029 } // namespace gles2
3906 } // namespace gpu 4030 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698