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

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: Unset texture and texture_ref after deleting Created 6 years, 8 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 <sstream> 14 #include <sstream>
15 #include <string> 15 #include <string>
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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 unpack_skip_pixels_(0), 100 unpack_skip_pixels_(0),
100 pack_reverse_row_order_(false), 101 pack_reverse_row_order_(false),
101 active_texture_unit_(0), 102 active_texture_unit_(0),
102 bound_framebuffer_(0), 103 bound_framebuffer_(0),
103 bound_read_framebuffer_(0), 104 bound_read_framebuffer_(0),
104 bound_renderbuffer_(0), 105 bound_renderbuffer_(0),
105 current_program_(0), 106 current_program_(0),
106 bound_array_buffer_id_(0), 107 bound_array_buffer_id_(0),
107 bound_pixel_pack_transfer_buffer_id_(0), 108 bound_pixel_pack_transfer_buffer_id_(0),
108 bound_pixel_unpack_transfer_buffer_id_(0), 109 bound_pixel_unpack_transfer_buffer_id_(0),
110 async_upload_token_(0),
111 async_upload_sync_(NULL),
112 async_upload_sync_shm_id_(0),
113 async_upload_sync_shm_offset_(0),
109 error_bits_(0), 114 error_bits_(0),
110 debug_(false), 115 debug_(false),
111 use_count_(0), 116 use_count_(0),
112 error_message_callback_(NULL), 117 error_message_callback_(NULL),
113 gpu_control_(gpu_control), 118 gpu_control_(gpu_control),
114 capabilities_(gpu_control->GetCapabilities()), 119 capabilities_(gpu_control->GetCapabilities()),
115 weak_ptr_factory_(this) { 120 weak_ptr_factory_(this) {
116 DCHECK(helper); 121 DCHECK(helper);
117 DCHECK(transfer_buffer); 122 DCHECK(transfer_buffer);
118 DCHECK(gpu_control); 123 DCHECK(gpu_control);
(...skipping 25 matching lines...) Expand all
144 if (!transfer_buffer_->Initialize( 149 if (!transfer_buffer_->Initialize(
145 starting_transfer_buffer_size, 150 starting_transfer_buffer_size,
146 kStartingOffset, 151 kStartingOffset,
147 min_transfer_buffer_size, 152 min_transfer_buffer_size,
148 max_transfer_buffer_size, 153 max_transfer_buffer_size,
149 kAlignment, 154 kAlignment,
150 kSizeToFlush)) { 155 kSizeToFlush)) {
151 return false; 156 return false;
152 } 157 }
153 158
154 mapped_memory_.reset(new MappedMemoryManager(helper_, mapped_memory_limit)); 159 mapped_memory_.reset(
160 new MappedMemoryManager(
161 helper_,
162 base::Bind(&GLES2Implementation::PollAsyncUploads,
163 // The mapped memory manager is owned by |this| here, and
164 // since its destroyed before before we destroy ourselves
165 // we don't need extra safety measures for this closure.
166 base::Unretained(this)),
167 mapped_memory_limit));
155 168
156 unsigned chunk_size = 2 * 1024 * 1024; 169 unsigned chunk_size = 2 * 1024 * 1024;
157 if (mapped_memory_limit != kNoLimit) { 170 if (mapped_memory_limit != kNoLimit) {
158 // Use smaller chunks if the client is very memory conscientious. 171 // Use smaller chunks if the client is very memory conscientious.
159 chunk_size = std::min(mapped_memory_limit / 4, chunk_size); 172 chunk_size = std::min(mapped_memory_limit / 4, chunk_size);
160 } 173 }
161 mapped_memory_->set_chunk_size_multiple(chunk_size); 174 mapped_memory_->set_chunk_size_multiple(chunk_size);
162 175
163 if (!QueryAndCacheStaticState()) 176 if (!QueryAndCacheStaticState())
164 return false; 177 return false;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 284
272 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 285 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
273 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); 286 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]);
274 #endif 287 #endif
275 288
276 // Release any per-context data in share group. 289 // Release any per-context data in share group.
277 share_group_->FreeContext(this); 290 share_group_->FreeContext(this);
278 291
279 buffer_tracker_.reset(); 292 buffer_tracker_.reset();
280 293
294 FreeAllAsyncUploadBuffers();
295
296 if (async_upload_sync_) {
297 mapped_memory_->Free(async_upload_sync_);
298 async_upload_sync_ = NULL;
299 }
300
281 // Make sure the commands make it the service. 301 // Make sure the commands make it the service.
282 WaitForCmd(); 302 WaitForCmd();
283 } 303 }
284 304
285 GLES2CmdHelper* GLES2Implementation::helper() const { 305 GLES2CmdHelper* GLES2Implementation::helper() const {
286 return helper_; 306 return helper_;
287 } 307 }
288 308
289 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { 309 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const {
290 return share_group_->GetIdHandler(namespace_id); 310 return share_group_->GetIdHandler(namespace_id);
291 } 311 }
292 312
293 void* GLES2Implementation::GetResultBuffer() { 313 void* GLES2Implementation::GetResultBuffer() {
294 return transfer_buffer_->GetResultBuffer(); 314 return transfer_buffer_->GetResultBuffer();
295 } 315 }
296 316
297 int32 GLES2Implementation::GetResultShmId() { 317 int32 GLES2Implementation::GetResultShmId() {
298 return transfer_buffer_->GetShmId(); 318 return transfer_buffer_->GetShmId();
299 } 319 }
300 320
301 uint32 GLES2Implementation::GetResultShmOffset() { 321 uint32 GLES2Implementation::GetResultShmOffset() {
302 return transfer_buffer_->GetResultOffset(); 322 return transfer_buffer_->GetResultOffset();
303 } 323 }
304 324
305 void GLES2Implementation::FreeUnusedSharedMemory() { 325 void GLES2Implementation::FreeUnusedSharedMemory() {
306 mapped_memory_->FreeUnused(); 326 mapped_memory_->FreeUnused();
307 } 327 }
308 328
309 void GLES2Implementation::FreeEverything() { 329 void GLES2Implementation::FreeEverything() {
330 FreeAllAsyncUploadBuffers();
310 WaitForCmd(); 331 WaitForCmd();
311 query_tracker_->Shrink(); 332 query_tracker_->Shrink();
312 FreeUnusedSharedMemory(); 333 FreeUnusedSharedMemory();
313 transfer_buffer_->Free(); 334 transfer_buffer_->Free();
314 helper_->FreeRingBuffer(); 335 helper_->FreeRingBuffer();
315 } 336 }
316 337
317 void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) { 338 void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) {
318 if (!helper_->IsContextLost()) 339 if (!helper_->IsContextLost())
319 callback.Run(); 340 callback.Run();
(...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 return; 1378 return;
1358 } 1379 }
1359 1380
1360 GLuint buffer_id; 1381 GLuint buffer_id;
1361 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { 1382 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) {
1362 if (!buffer_id) { 1383 if (!buffer_id) {
1363 return; 1384 return;
1364 } 1385 }
1365 1386
1366 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); 1387 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
1367 if (buffer) { 1388 if (buffer)
1368 // Free buffer memory, pending the passage of a token. 1389 RemoveTransferBuffer(buffer);
1369 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken());
1370
1371 // Remove old buffer.
1372 buffer_tracker_->RemoveBuffer(buffer_id);
1373 }
1374 1390
1375 // Create new buffer. 1391 // Create new buffer.
1376 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); 1392 buffer = buffer_tracker_->CreateBuffer(buffer_id, size);
1377 DCHECK(buffer); 1393 DCHECK(buffer);
1378 if (buffer->address() && data) 1394 if (buffer->address() && data)
1379 memcpy(buffer->address(), data, size); 1395 memcpy(buffer->address(), data, size);
1380 return; 1396 return;
1381 } 1397 }
1382 1398
1383 if (size == 0) { 1399 if (size == 0) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { 1507 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
1492 GPU_CLIENT_SINGLE_THREAD_CHECK(); 1508 GPU_CLIENT_SINGLE_THREAD_CHECK();
1493 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" 1509 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData("
1494 << GLES2Util::GetStringBufferTarget(target) << ", " 1510 << GLES2Util::GetStringBufferTarget(target) << ", "
1495 << offset << ", " << size << ", " 1511 << offset << ", " << size << ", "
1496 << static_cast<const void*>(data) << ")"); 1512 << static_cast<const void*>(data) << ")");
1497 BufferSubDataHelper(target, offset, size, data); 1513 BufferSubDataHelper(target, offset, size, data);
1498 CheckGLError(); 1514 CheckGLError();
1499 } 1515 }
1500 1516
1517 void GLES2Implementation::RemoveTransferBuffer(BufferTracker::Buffer* buffer) {
1518 int32 token = buffer->last_usage_token();
1519 uint32 async_token = buffer->last_async_upload_token();
1520
1521 if (async_token) {
1522 if (HasAsyncUploadTokenPassed(async_token)) {
1523 buffer_tracker_->Free(buffer);
1524 } else {
1525 detached_async_upload_memory_.push_back(
1526 std::make_pair(buffer->address(), async_token));
1527 buffer_tracker_->Unmanage(buffer);
1528 }
1529 } else if (token) {
1530 if (helper_->HasTokenPassed(token))
1531 buffer_tracker_->Free(buffer);
1532 else
1533 buffer_tracker_->FreePendingToken(buffer, token);
1534 } else {
1535 buffer_tracker_->Free(buffer);
1536 }
1537
1538 buffer_tracker_->RemoveBuffer(buffer->id());
1539 }
1540
1501 bool GLES2Implementation::GetBoundPixelTransferBuffer( 1541 bool GLES2Implementation::GetBoundPixelTransferBuffer(
1502 GLenum target, 1542 GLenum target,
1503 const char* function_name, 1543 const char* function_name,
1504 GLuint* buffer_id) { 1544 GLuint* buffer_id) {
1505 *buffer_id = 0; 1545 *buffer_id = 0;
1506 1546
1507 switch (target) { 1547 switch (target) {
1508 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: 1548 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
1509 *buffer_id = bound_pixel_pack_transfer_buffer_id_; 1549 *buffer_id = bound_pixel_pack_transfer_buffer_id_;
1510 break; 1550 break;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 // CompressedTexImage2D. 1606 // CompressedTexImage2D.
1567 if (bound_pixel_unpack_transfer_buffer_id_) { 1607 if (bound_pixel_unpack_transfer_buffer_id_) {
1568 GLuint offset = ToGLuint(data); 1608 GLuint offset = ToGLuint(data);
1569 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1609 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1570 bound_pixel_unpack_transfer_buffer_id_, 1610 bound_pixel_unpack_transfer_buffer_id_,
1571 "glCompressedTexImage2D", offset, image_size); 1611 "glCompressedTexImage2D", offset, image_size);
1572 if (buffer && buffer->shm_id() != -1) { 1612 if (buffer && buffer->shm_id() != -1) {
1573 helper_->CompressedTexImage2D( 1613 helper_->CompressedTexImage2D(
1574 target, level, internalformat, width, height, border, image_size, 1614 target, level, internalformat, width, height, border, image_size,
1575 buffer->shm_id(), buffer->shm_offset() + offset); 1615 buffer->shm_id(), buffer->shm_offset() + offset);
1576 buffer->set_transfer_ready_token(helper_->InsertToken()); 1616 buffer->set_last_usage_token(helper_->InsertToken());
1577 } 1617 }
1578 return; 1618 return;
1579 } 1619 }
1580 SetBucketContents(kResultBucketId, data, image_size); 1620 SetBucketContents(kResultBucketId, data, image_size);
1581 helper_->CompressedTexImage2DBucket( 1621 helper_->CompressedTexImage2DBucket(
1582 target, level, internalformat, width, height, border, kResultBucketId); 1622 target, level, internalformat, width, height, border, kResultBucketId);
1583 // Free the bucket. This is not required but it does free up the memory. 1623 // Free the bucket. This is not required but it does free up the memory.
1584 // and we don't have to wait for the result so from the client's perspective 1624 // and we don't have to wait for the result so from the client's perspective
1585 // it's cheap. 1625 // it's cheap.
1586 helper_->SetBucketSize(kResultBucketId, 0); 1626 helper_->SetBucketSize(kResultBucketId, 0);
(...skipping 20 matching lines...) Expand all
1607 // CompressedTexSubImage2D. 1647 // CompressedTexSubImage2D.
1608 if (bound_pixel_unpack_transfer_buffer_id_) { 1648 if (bound_pixel_unpack_transfer_buffer_id_) {
1609 GLuint offset = ToGLuint(data); 1649 GLuint offset = ToGLuint(data);
1610 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1650 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1611 bound_pixel_unpack_transfer_buffer_id_, 1651 bound_pixel_unpack_transfer_buffer_id_,
1612 "glCompressedTexSubImage2D", offset, image_size); 1652 "glCompressedTexSubImage2D", offset, image_size);
1613 if (buffer && buffer->shm_id() != -1) { 1653 if (buffer && buffer->shm_id() != -1) {
1614 helper_->CompressedTexSubImage2D( 1654 helper_->CompressedTexSubImage2D(
1615 target, level, xoffset, yoffset, width, height, format, image_size, 1655 target, level, xoffset, yoffset, width, height, format, image_size,
1616 buffer->shm_id(), buffer->shm_offset() + offset); 1656 buffer->shm_id(), buffer->shm_offset() + offset);
1617 buffer->set_transfer_ready_token(helper_->InsertToken()); 1657 buffer->set_last_usage_token(helper_->InsertToken());
1618 CheckGLError(); 1658 CheckGLError();
1619 } 1659 }
1620 return; 1660 return;
1621 } 1661 }
1622 SetBucketContents(kResultBucketId, data, image_size); 1662 SetBucketContents(kResultBucketId, data, image_size);
1623 helper_->CompressedTexSubImage2DBucket( 1663 helper_->CompressedTexSubImage2DBucket(
1624 target, level, xoffset, yoffset, width, height, format, kResultBucketId); 1664 target, level, xoffset, yoffset, width, height, format, kResultBucketId);
1625 // Free the bucket. This is not required but it does free up the memory. 1665 // Free the bucket. This is not required but it does free up the memory.
1626 // and we don't have to wait for the result so from the client's perspective 1666 // and we don't have to wait for the result so from the client's perspective
1627 // it's cheap. 1667 // it's cheap.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1694 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. 1734 // If there's a pixel unpack buffer bound use it when issuing TexImage2D.
1695 if (bound_pixel_unpack_transfer_buffer_id_) { 1735 if (bound_pixel_unpack_transfer_buffer_id_) {
1696 GLuint offset = ToGLuint(pixels); 1736 GLuint offset = ToGLuint(pixels);
1697 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1737 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1698 bound_pixel_unpack_transfer_buffer_id_, 1738 bound_pixel_unpack_transfer_buffer_id_,
1699 "glTexImage2D", offset, size); 1739 "glTexImage2D", offset, size);
1700 if (buffer && buffer->shm_id() != -1) { 1740 if (buffer && buffer->shm_id() != -1) {
1701 helper_->TexImage2D( 1741 helper_->TexImage2D(
1702 target, level, internalformat, width, height, border, format, type, 1742 target, level, internalformat, width, height, border, format, type,
1703 buffer->shm_id(), buffer->shm_offset() + offset); 1743 buffer->shm_id(), buffer->shm_offset() + offset);
1704 buffer->set_transfer_ready_token(helper_->InsertToken()); 1744 buffer->set_last_usage_token(helper_->InsertToken());
1705 CheckGLError(); 1745 CheckGLError();
1706 } 1746 }
1707 return; 1747 return;
1708 } 1748 }
1709 1749
1710 // If there's no data just issue TexImage2D 1750 // If there's no data just issue TexImage2D
1711 if (!pixels) { 1751 if (!pixels) {
1712 helper_->TexImage2D( 1752 helper_->TexImage2D(
1713 target, level, internalformat, width, height, border, format, type, 1753 target, level, internalformat, width, height, border, format, type,
1714 0, 0); 1754 0, 0);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1800 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. 1840 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D.
1801 if (bound_pixel_unpack_transfer_buffer_id_) { 1841 if (bound_pixel_unpack_transfer_buffer_id_) {
1802 GLuint offset = ToGLuint(pixels); 1842 GLuint offset = ToGLuint(pixels);
1803 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1843 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1804 bound_pixel_unpack_transfer_buffer_id_, 1844 bound_pixel_unpack_transfer_buffer_id_,
1805 "glTexSubImage2D", offset, temp_size); 1845 "glTexSubImage2D", offset, temp_size);
1806 if (buffer && buffer->shm_id() != -1) { 1846 if (buffer && buffer->shm_id() != -1) {
1807 helper_->TexSubImage2D( 1847 helper_->TexSubImage2D(
1808 target, level, xoffset, yoffset, width, height, format, type, 1848 target, level, xoffset, yoffset, width, height, format, type,
1809 buffer->shm_id(), buffer->shm_offset() + offset, false); 1849 buffer->shm_id(), buffer->shm_offset() + offset, false);
1810 buffer->set_transfer_ready_token(helper_->InsertToken()); 1850 buffer->set_last_usage_token(helper_->InsertToken());
1811 CheckGLError(); 1851 CheckGLError();
1812 } 1852 }
1813 return; 1853 return;
1814 } 1854 }
1815 1855
1816 // compute the advance bytes per row for the src pixels 1856 // compute the advance bytes per row for the src pixels
1817 uint32 src_padded_row_size; 1857 uint32 src_padded_row_size;
1818 if (unpack_row_length_ > 0) { 1858 if (unpack_row_length_ > 0) {
1819 if (!GLES2Util::ComputeImagePaddedRowSize( 1859 if (!GLES2Util::ComputeImagePaddedRowSize(
1820 unpack_row_length_, format, type, unpack_alignment_, 1860 unpack_row_length_, format, type, unpack_alignment_,
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
2383 } 2423 }
2384 2424
2385 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id 2425 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id
2386 // generates a new resource. On newer versions of OpenGL they don't. The code 2426 // generates a new resource. On newer versions of OpenGL they don't. The code
2387 // related to binding below will need to change if we switch to the new OpenGL 2427 // related to binding below will need to change if we switch to the new OpenGL
2388 // model. Specifically it assumes a bind will succeed which is always true in 2428 // model. Specifically it assumes a bind will succeed which is always true in
2389 // the old model but possibly not true in the new model if another context has 2429 // the old model but possibly not true in the new model if another context has
2390 // deleted the resource. 2430 // deleted the resource.
2391 2431
2392 bool GLES2Implementation::BindBufferHelper( 2432 bool GLES2Implementation::BindBufferHelper(
2393 GLenum target, GLuint buffer) { 2433 GLenum target, GLuint buffer_id) {
2394 // TODO(gman): See note #1 above. 2434 // TODO(gman): See note #1 above.
2395 bool changed = false; 2435 bool changed = false;
2396 switch (target) { 2436 switch (target) {
2397 case GL_ARRAY_BUFFER: 2437 case GL_ARRAY_BUFFER:
2398 if (bound_array_buffer_id_ != buffer) { 2438 if (bound_array_buffer_id_ != buffer_id) {
2399 bound_array_buffer_id_ = buffer; 2439 bound_array_buffer_id_ = buffer_id;
2400 changed = true; 2440 changed = true;
2401 } 2441 }
2402 break; 2442 break;
2403 case GL_ELEMENT_ARRAY_BUFFER: 2443 case GL_ELEMENT_ARRAY_BUFFER:
2404 changed = vertex_array_object_manager_->BindElementArray(buffer); 2444 changed = vertex_array_object_manager_->BindElementArray(buffer_id);
2405 break; 2445 break;
2406 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: 2446 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
2407 bound_pixel_pack_transfer_buffer_id_ = buffer; 2447 bound_pixel_pack_transfer_buffer_id_ = buffer_id;
2408 break; 2448 break;
2409 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: 2449 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM:
2410 bound_pixel_unpack_transfer_buffer_id_ = buffer; 2450 bound_pixel_unpack_transfer_buffer_id_ = buffer_id;
2411 break; 2451 break;
2412 default: 2452 default:
2413 changed = true; 2453 changed = true;
2414 break; 2454 break;
2415 } 2455 }
2416 // TODO(gman): There's a bug here. If the target is invalid the ID will not be 2456 // TODO(gman): There's a bug here. If the target is invalid the ID will not be
2417 // used even though it's marked it as used here. 2457 // used even though it's marked it as used here.
2418 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); 2458 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer_id);
2419 return changed; 2459 return changed;
2420 } 2460 }
2421 2461
2422 bool GLES2Implementation::BindFramebufferHelper( 2462 bool GLES2Implementation::BindFramebufferHelper(
2423 GLenum target, GLuint framebuffer) { 2463 GLenum target, GLuint framebuffer) {
2424 // TODO(gman): See note #1 above. 2464 // TODO(gman): See note #1 above.
2425 bool changed = false; 2465 bool changed = false;
2426 switch (target) { 2466 switch (target) {
2427 case GL_FRAMEBUFFER: 2467 case GL_FRAMEBUFFER:
2428 if (bound_framebuffer_ != framebuffer || 2468 if (bound_framebuffer_ != framebuffer ||
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2551 SetGLError( 2591 SetGLError(
2552 GL_INVALID_VALUE, 2592 GL_INVALID_VALUE,
2553 "glDeleteBuffers", "id not created by this context."); 2593 "glDeleteBuffers", "id not created by this context.");
2554 return; 2594 return;
2555 } 2595 }
2556 for (GLsizei ii = 0; ii < n; ++ii) { 2596 for (GLsizei ii = 0; ii < n; ++ii) {
2557 if (buffers[ii] == bound_array_buffer_id_) { 2597 if (buffers[ii] == bound_array_buffer_id_) {
2558 bound_array_buffer_id_ = 0; 2598 bound_array_buffer_id_ = 0;
2559 } 2599 }
2560 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); 2600 vertex_array_object_manager_->UnbindBuffer(buffers[ii]);
2601
2561 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); 2602 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]);
2562 if (buffer) { 2603 if (buffer)
2563 // Free buffer memory, pending the passage of a token. 2604 RemoveTransferBuffer(buffer);
2564 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); 2605
2565 // Remove buffer.
2566 buffer_tracker_->RemoveBuffer(buffers[ii]);
2567 }
2568 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { 2606 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
2569 bound_pixel_unpack_transfer_buffer_id_ = 0; 2607 bound_pixel_unpack_transfer_buffer_id_ = 0;
2570 } 2608 }
2571 } 2609 }
2572 } 2610 }
2573 2611
2574 void GLES2Implementation::DeleteBuffersStub( 2612 void GLES2Implementation::DeleteBuffersStub(
2575 GLsizei n, const GLuint* buffers) { 2613 GLsizei n, const GLuint* buffers) {
2576 helper_->DeleteBuffersImmediate(n, buffers); 2614 helper_->DeleteBuffersImmediate(n, buffers);
2577 } 2615 }
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after
3601 } 3639 }
3602 if (buffer->mapped()) { 3640 if (buffer->mapped()) {
3603 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); 3641 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped");
3604 return NULL; 3642 return NULL;
3605 } 3643 }
3606 // Here we wait for previous transfer operations to be finished. 3644 // Here we wait for previous transfer operations to be finished.
3607 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work 3645 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work
3608 // with this method of synchronization. Until this is fixed, 3646 // with this method of synchronization. Until this is fixed,
3609 // MapBufferCHROMIUM will not block even if the transfer is not ready 3647 // MapBufferCHROMIUM will not block even if the transfer is not ready
3610 // for these calls. 3648 // for these calls.
3611 if (buffer->transfer_ready_token()) { 3649 if (buffer->last_usage_token()) {
3612 helper_->WaitForToken(buffer->transfer_ready_token()); 3650 helper_->WaitForToken(buffer->last_usage_token());
3613 buffer->set_transfer_ready_token(0); 3651 buffer->set_last_usage_token(0);
3614 } 3652 }
3615 buffer->set_mapped(true); 3653 buffer->set_mapped(true);
3616 3654
3617 GPU_CLIENT_LOG(" returned " << buffer->address()); 3655 GPU_CLIENT_LOG(" returned " << buffer->address());
3618 CheckGLError(); 3656 CheckGLError();
3619 return buffer->address(); 3657 return buffer->address();
3620 } 3658 }
3621 3659
3622 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { 3660 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) {
3623 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3661 GPU_CLIENT_SINGLE_THREAD_CHECK();
(...skipping 13 matching lines...) Expand all
3637 } 3675 }
3638 if (!buffer->mapped()) { 3676 if (!buffer->mapped()) {
3639 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); 3677 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped");
3640 return false; 3678 return false;
3641 } 3679 }
3642 buffer->set_mapped(false); 3680 buffer->set_mapped(false);
3643 CheckGLError(); 3681 CheckGLError();
3644 return true; 3682 return true;
3645 } 3683 }
3646 3684
3685 bool GLES2Implementation::EnsureAsyncUploadSync() {
3686 if (async_upload_sync_)
3687 return true;
3688
3689 int32 shm_id;
3690 unsigned int shm_offset;
3691 void* mem = mapped_memory_->Alloc(sizeof(AsyncUploadSync),
3692 &shm_id,
3693 &shm_offset);
3694 if (!mem)
3695 return false;
3696
3697 async_upload_sync_shm_id_ = shm_id;
3698 async_upload_sync_shm_offset_ = shm_offset;
3699 async_upload_sync_ = static_cast<AsyncUploadSync*>(mem);
3700 async_upload_sync_->Reset();
3701
3702 return true;
3703 }
3704
3705 uint32 GLES2Implementation::NextAsyncUploadToken() {
3706 async_upload_token_++;
3707 if (async_upload_token_ == 0)
3708 async_upload_token_++;
3709 return async_upload_token_;
3710 }
3711
3712 void GLES2Implementation::PollAsyncUploads() {
3713 if (!async_upload_sync_)
3714 return;
3715
3716 if (helper_->IsContextLost()) {
3717 DetachedAsyncUploadMemoryList::iterator it =
3718 detached_async_upload_memory_.begin();
3719 while (it != detached_async_upload_memory_.end()) {
3720 mapped_memory_->Free(it->first);
3721 it = detached_async_upload_memory_.erase(it);
3722 }
3723 return;
3724 }
3725
3726 DetachedAsyncUploadMemoryList::iterator it =
3727 detached_async_upload_memory_.begin();
3728 while (it != detached_async_upload_memory_.end()) {
3729 if (HasAsyncUploadTokenPassed(it->second)) {
3730 mapped_memory_->Free(it->first);
3731 it = detached_async_upload_memory_.erase(it);
3732 } else {
3733 break;
3734 }
3735 }
3736 }
3737
3738 void GLES2Implementation::FreeAllAsyncUploadBuffers() {
3739 // Free all completed unmanaged async uploads buffers.
3740 PollAsyncUploads();
3741
3742 // Synchronously free rest of the unmanaged async upload buffers.
3743 if (!detached_async_upload_memory_.empty()) {
3744 WaitAllAsyncTexImage2DCHROMIUM();
3745 WaitForCmd();
3746 PollAsyncUploads();
3747 }
3748 }
3749
3647 void GLES2Implementation::AsyncTexImage2DCHROMIUM( 3750 void GLES2Implementation::AsyncTexImage2DCHROMIUM(
3648 GLenum target, GLint level, GLint internalformat, GLsizei width, 3751 GLenum target, GLint level, GLint internalformat, GLsizei width,
3649 GLsizei height, GLint border, GLenum format, GLenum type, 3752 GLsizei height, GLint border, GLenum format, GLenum type,
3650 const void* pixels) { 3753 const void* pixels) {
3651 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3754 GPU_CLIENT_SINGLE_THREAD_CHECK();
3652 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" 3755 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D("
3653 << GLES2Util::GetStringTextureTarget(target) << ", " 3756 << GLES2Util::GetStringTextureTarget(target) << ", "
3654 << level << ", " 3757 << level << ", "
3655 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " 3758 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", "
3656 << width << ", " << height << ", " << border << ", " 3759 << width << ", " << height << ", " << border << ", "
(...skipping 11 matching lines...) Expand all
3668 width, height, format, type, unpack_alignment_, &size, 3771 width, height, format, type, unpack_alignment_, &size,
3669 &unpadded_row_size, &padded_row_size)) { 3772 &unpadded_row_size, &padded_row_size)) {
3670 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); 3773 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large");
3671 return; 3774 return;
3672 } 3775 }
3673 3776
3674 // If there's no data/buffer just issue the AsyncTexImage2D 3777 // If there's no data/buffer just issue the AsyncTexImage2D
3675 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { 3778 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) {
3676 helper_->AsyncTexImage2DCHROMIUM( 3779 helper_->AsyncTexImage2DCHROMIUM(
3677 target, level, internalformat, width, height, border, format, type, 3780 target, level, internalformat, width, height, border, format, type,
3678 0, 0); 3781 0, 0, 0, 0, 0);
3679 return; 3782 return;
3680 } 3783 }
3681 3784
3785 if (!EnsureAsyncUploadSync()) {
3786 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
3787 return;
3788 }
3789
3682 // Otherwise, async uploads require a transfer buffer to be bound. 3790 // Otherwise, async uploads require a transfer buffer to be bound.
3683 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use 3791 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use
3684 // the buffer before the transfer is finished. (Currently such 3792 // the buffer before the transfer is finished. (Currently such
3685 // synchronization has to be handled manually.) 3793 // synchronization has to be handled manually.)
3686 GLuint offset = ToGLuint(pixels); 3794 GLuint offset = ToGLuint(pixels);
3687 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 3795 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
3688 bound_pixel_unpack_transfer_buffer_id_, 3796 bound_pixel_unpack_transfer_buffer_id_,
3689 "glAsyncTexImage2DCHROMIUM", offset, size); 3797 "glAsyncTexImage2DCHROMIUM", offset, size);
3690 if (buffer && buffer->shm_id() != -1) { 3798 if (buffer && buffer->shm_id() != -1) {
3799 uint32 async_token = NextAsyncUploadToken();
3800 buffer->set_last_async_upload_token(async_token);
3691 helper_->AsyncTexImage2DCHROMIUM( 3801 helper_->AsyncTexImage2DCHROMIUM(
3692 target, level, internalformat, width, height, border, format, type, 3802 target, level, internalformat, width, height, border, format, type,
3693 buffer->shm_id(), buffer->shm_offset() + offset); 3803 buffer->shm_id(), buffer->shm_offset() + offset,
3804 async_token,
3805 async_upload_sync_shm_id_, async_upload_sync_shm_offset_);
3694 } 3806 }
3695 } 3807 }
3696 3808
3697 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( 3809 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM(
3698 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, 3810 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
3699 GLsizei height, GLenum format, GLenum type, const void* pixels) { 3811 GLsizei height, GLenum format, GLenum type, const void* pixels) {
3700 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3812 GPU_CLIENT_SINGLE_THREAD_CHECK();
3701 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" 3813 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM("
3702 << GLES2Util::GetStringTextureTarget(target) << ", " 3814 << GLES2Util::GetStringTextureTarget(target) << ", "
3703 << level << ", " 3815 << level << ", "
(...skipping 12 matching lines...) Expand all
3716 uint32 unpadded_row_size; 3828 uint32 unpadded_row_size;
3717 uint32 padded_row_size; 3829 uint32 padded_row_size;
3718 if (!GLES2Util::ComputeImageDataSizes( 3830 if (!GLES2Util::ComputeImageDataSizes(
3719 width, height, format, type, unpack_alignment_, &size, 3831 width, height, format, type, unpack_alignment_, &size,
3720 &unpadded_row_size, &padded_row_size)) { 3832 &unpadded_row_size, &padded_row_size)) {
3721 SetGLError( 3833 SetGLError(
3722 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); 3834 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large");
3723 return; 3835 return;
3724 } 3836 }
3725 3837
3838 if (!EnsureAsyncUploadSync()) {
3839 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
3840 return;
3841 }
3842
3726 // Async uploads require a transfer buffer to be bound. 3843 // Async uploads require a transfer buffer to be bound.
3727 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use 3844 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use
3728 // the buffer before the transfer is finished. (Currently such 3845 // the buffer before the transfer is finished. (Currently such
3729 // synchronization has to be handled manually.) 3846 // synchronization has to be handled manually.)
3730 GLuint offset = ToGLuint(pixels); 3847 GLuint offset = ToGLuint(pixels);
3731 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 3848 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
3732 bound_pixel_unpack_transfer_buffer_id_, 3849 bound_pixel_unpack_transfer_buffer_id_,
3733 "glAsyncTexSubImage2DCHROMIUM", offset, size); 3850 "glAsyncTexSubImage2DCHROMIUM", offset, size);
3734 if (buffer && buffer->shm_id() != -1) { 3851 if (buffer && buffer->shm_id() != -1) {
3852 uint32 async_token = NextAsyncUploadToken();
3853 buffer->set_last_async_upload_token(async_token);
3735 helper_->AsyncTexSubImage2DCHROMIUM( 3854 helper_->AsyncTexSubImage2DCHROMIUM(
3736 target, level, xoffset, yoffset, width, height, format, type, 3855 target, level, xoffset, yoffset, width, height, format, type,
3737 buffer->shm_id(), buffer->shm_offset() + offset); 3856 buffer->shm_id(), buffer->shm_offset() + offset,
3857 async_token,
3858 async_upload_sync_shm_id_, async_upload_sync_shm_offset_);
3738 } 3859 }
3739 } 3860 }
3740 3861
3741 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { 3862 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) {
3742 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3863 GPU_CLIENT_SINGLE_THREAD_CHECK();
3743 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM(" 3864 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM("
3744 << GLES2Util::GetStringTextureTarget(target) << ")"); 3865 << GLES2Util::GetStringTextureTarget(target) << ")");
3745 helper_->WaitAsyncTexImage2DCHROMIUM(target); 3866 helper_->WaitAsyncTexImage2DCHROMIUM(target);
3746 CheckGLError(); 3867 CheckGLError();
3747 } 3868 }
3748 3869
3870 void GLES2Implementation::WaitAllAsyncTexImage2DCHROMIUM() {
3871 GPU_CLIENT_SINGLE_THREAD_CHECK();
3872 GPU_CLIENT_LOG("[" << GetLogPrefix()
3873 << "] glWaitAllAsyncTexImage2DCHROMIUM()");
3874 helper_->WaitAllAsyncTexImage2DCHROMIUM();
3875 CheckGLError();
3876 }
3877
3749 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { 3878 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() {
3750 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3879 GPU_CLIENT_SINGLE_THREAD_CHECK();
3751 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM"); 3880 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM");
3752 helper_->CommandBufferHelper::Flush(); 3881 helper_->CommandBufferHelper::Flush();
3753 return gpu_control_->InsertSyncPoint(); 3882 return gpu_control_->InsertSyncPoint();
3754 } 3883 }
3755 3884
3756 GLuint GLES2Implementation::CreateImageCHROMIUMHelper( 3885 GLuint GLES2Implementation::CreateImageCHROMIUMHelper(
3757 GLsizei width, GLsizei height, GLenum internalformat) { 3886 GLsizei width, GLsizei height, GLenum internalformat) {
3758 if (width <= 0) { 3887 if (width <= 0) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3920 CheckGLError(); 4049 CheckGLError();
3921 } 4050 }
3922 4051
3923 // Include the auto-generated part of this file. We split this because it means 4052 // Include the auto-generated part of this file. We split this because it means
3924 // we can easily edit the non-auto generated parts right here in this file 4053 // we can easily edit the non-auto generated parts right here in this file
3925 // instead of having to edit some template or the code generator. 4054 // instead of having to edit some template or the code generator.
3926 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" 4055 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h"
3927 4056
3928 } // namespace gles2 4057 } // namespace gles2
3929 } // namespace gpu 4058 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/gles2_implementation.h ('k') | gpu/command_buffer/client/gles2_implementation_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698