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

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

Powered by Google App Engine
This is Rietveld 408576698