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

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: Rebased; removed unnecessary barrier; use CheckedNumeric Created 6 years, 9 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 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 return; 1388 return;
1368 } 1389 }
1369 1390
1370 GLuint buffer_id; 1391 GLuint buffer_id;
1371 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { 1392 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) {
1372 if (!buffer_id) { 1393 if (!buffer_id) {
1373 return; 1394 return;
1374 } 1395 }
1375 1396
1376 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); 1397 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
1377 if (buffer) { 1398 if (buffer)
1378 // Free buffer memory, pending the passage of a token. 1399 RemoveTransferBuffer(buffer);
1379 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken());
1380
1381 // Remove old buffer.
1382 buffer_tracker_->RemoveBuffer(buffer_id);
1383 }
1384 1400
1385 // Create new buffer. 1401 // Create new buffer.
1386 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); 1402 buffer = buffer_tracker_->CreateBuffer(buffer_id, size);
1387 DCHECK(buffer); 1403 DCHECK(buffer);
1388 if (buffer->address() && data) 1404 if (buffer->address() && data)
1389 memcpy(buffer->address(), data, size); 1405 memcpy(buffer->address(), data, size);
1390 return; 1406 return;
1391 } 1407 }
1392 1408
1393 if (size == 0) { 1409 if (size == 0) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { 1517 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
1502 GPU_CLIENT_SINGLE_THREAD_CHECK(); 1518 GPU_CLIENT_SINGLE_THREAD_CHECK();
1503 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" 1519 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData("
1504 << GLES2Util::GetStringBufferTarget(target) << ", " 1520 << GLES2Util::GetStringBufferTarget(target) << ", "
1505 << offset << ", " << size << ", " 1521 << offset << ", " << size << ", "
1506 << static_cast<const void*>(data) << ")"); 1522 << static_cast<const void*>(data) << ")");
1507 BufferSubDataHelper(target, offset, size, data); 1523 BufferSubDataHelper(target, offset, size, data);
1508 CheckGLError(); 1524 CheckGLError();
1509 } 1525 }
1510 1526
1527 void GLES2Implementation::RemoveTransferBuffer(BufferTracker::Buffer* buffer) {
1528 int32 token = buffer->last_usage_token();
1529 uint32 async_token = buffer->last_async_upload_token();
1530
1531 if (async_token) {
1532 if (HasAsyncUploadTokenPassed(async_token)) {
1533 buffer_tracker_->Free(buffer);
1534 } else {
1535 detached_async_upload_memory_.push_back(
1536 std::make_pair(buffer->address(), async_token));
1537 buffer_tracker_->Unmanage(buffer);
1538 }
1539 } else if (token) {
1540 if (helper_->HasTokenPassed(token))
1541 buffer_tracker_->Free(buffer);
1542 else
1543 buffer_tracker_->FreePendingToken(buffer, token);
1544 } else {
1545 buffer_tracker_->Free(buffer);
1546 }
1547
1548 buffer_tracker_->RemoveBuffer(buffer->id());
1549 }
1550
1511 bool GLES2Implementation::GetBoundPixelTransferBuffer( 1551 bool GLES2Implementation::GetBoundPixelTransferBuffer(
1512 GLenum target, 1552 GLenum target,
1513 const char* function_name, 1553 const char* function_name,
1514 GLuint* buffer_id) { 1554 GLuint* buffer_id) {
1515 *buffer_id = 0; 1555 *buffer_id = 0;
1516 1556
1517 switch (target) { 1557 switch (target) {
1518 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: 1558 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
1519 *buffer_id = bound_pixel_pack_transfer_buffer_id_; 1559 *buffer_id = bound_pixel_pack_transfer_buffer_id_;
1520 break; 1560 break;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 // CompressedTexImage2D. 1616 // CompressedTexImage2D.
1577 if (bound_pixel_unpack_transfer_buffer_id_) { 1617 if (bound_pixel_unpack_transfer_buffer_id_) {
1578 GLuint offset = ToGLuint(data); 1618 GLuint offset = ToGLuint(data);
1579 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1619 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1580 bound_pixel_unpack_transfer_buffer_id_, 1620 bound_pixel_unpack_transfer_buffer_id_,
1581 "glCompressedTexImage2D", offset, image_size); 1621 "glCompressedTexImage2D", offset, image_size);
1582 if (buffer && buffer->shm_id() != -1) { 1622 if (buffer && buffer->shm_id() != -1) {
1583 helper_->CompressedTexImage2D( 1623 helper_->CompressedTexImage2D(
1584 target, level, internalformat, width, height, border, image_size, 1624 target, level, internalformat, width, height, border, image_size,
1585 buffer->shm_id(), buffer->shm_offset() + offset); 1625 buffer->shm_id(), buffer->shm_offset() + offset);
1586 buffer->set_transfer_ready_token(helper_->InsertToken()); 1626 buffer->set_last_usage_token(helper_->InsertToken());
1587 } 1627 }
1588 return; 1628 return;
1589 } 1629 }
1590 SetBucketContents(kResultBucketId, data, image_size); 1630 SetBucketContents(kResultBucketId, data, image_size);
1591 helper_->CompressedTexImage2DBucket( 1631 helper_->CompressedTexImage2DBucket(
1592 target, level, internalformat, width, height, border, kResultBucketId); 1632 target, level, internalformat, width, height, border, kResultBucketId);
1593 // Free the bucket. This is not required but it does free up the memory. 1633 // Free the bucket. This is not required but it does free up the memory.
1594 // and we don't have to wait for the result so from the client's perspective 1634 // and we don't have to wait for the result so from the client's perspective
1595 // it's cheap. 1635 // it's cheap.
1596 helper_->SetBucketSize(kResultBucketId, 0); 1636 helper_->SetBucketSize(kResultBucketId, 0);
(...skipping 20 matching lines...) Expand all
1617 // CompressedTexSubImage2D. 1657 // CompressedTexSubImage2D.
1618 if (bound_pixel_unpack_transfer_buffer_id_) { 1658 if (bound_pixel_unpack_transfer_buffer_id_) {
1619 GLuint offset = ToGLuint(data); 1659 GLuint offset = ToGLuint(data);
1620 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1660 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1621 bound_pixel_unpack_transfer_buffer_id_, 1661 bound_pixel_unpack_transfer_buffer_id_,
1622 "glCompressedTexSubImage2D", offset, image_size); 1662 "glCompressedTexSubImage2D", offset, image_size);
1623 if (buffer && buffer->shm_id() != -1) { 1663 if (buffer && buffer->shm_id() != -1) {
1624 helper_->CompressedTexSubImage2D( 1664 helper_->CompressedTexSubImage2D(
1625 target, level, xoffset, yoffset, width, height, format, image_size, 1665 target, level, xoffset, yoffset, width, height, format, image_size,
1626 buffer->shm_id(), buffer->shm_offset() + offset); 1666 buffer->shm_id(), buffer->shm_offset() + offset);
1627 buffer->set_transfer_ready_token(helper_->InsertToken()); 1667 buffer->set_last_usage_token(helper_->InsertToken());
1628 CheckGLError(); 1668 CheckGLError();
1629 } 1669 }
1630 return; 1670 return;
1631 } 1671 }
1632 SetBucketContents(kResultBucketId, data, image_size); 1672 SetBucketContents(kResultBucketId, data, image_size);
1633 helper_->CompressedTexSubImage2DBucket( 1673 helper_->CompressedTexSubImage2DBucket(
1634 target, level, xoffset, yoffset, width, height, format, kResultBucketId); 1674 target, level, xoffset, yoffset, width, height, format, kResultBucketId);
1635 // Free the bucket. This is not required but it does free up the memory. 1675 // Free the bucket. This is not required but it does free up the memory.
1636 // and we don't have to wait for the result so from the client's perspective 1676 // and we don't have to wait for the result so from the client's perspective
1637 // it's cheap. 1677 // it's cheap.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. 1744 // If there's a pixel unpack buffer bound use it when issuing TexImage2D.
1705 if (bound_pixel_unpack_transfer_buffer_id_) { 1745 if (bound_pixel_unpack_transfer_buffer_id_) {
1706 GLuint offset = ToGLuint(pixels); 1746 GLuint offset = ToGLuint(pixels);
1707 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1747 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1708 bound_pixel_unpack_transfer_buffer_id_, 1748 bound_pixel_unpack_transfer_buffer_id_,
1709 "glTexImage2D", offset, size); 1749 "glTexImage2D", offset, size);
1710 if (buffer && buffer->shm_id() != -1) { 1750 if (buffer && buffer->shm_id() != -1) {
1711 helper_->TexImage2D( 1751 helper_->TexImage2D(
1712 target, level, internalformat, width, height, border, format, type, 1752 target, level, internalformat, width, height, border, format, type,
1713 buffer->shm_id(), buffer->shm_offset() + offset); 1753 buffer->shm_id(), buffer->shm_offset() + offset);
1714 buffer->set_transfer_ready_token(helper_->InsertToken()); 1754 buffer->set_last_usage_token(helper_->InsertToken());
1715 CheckGLError(); 1755 CheckGLError();
1716 } 1756 }
1717 return; 1757 return;
1718 } 1758 }
1719 1759
1720 // If there's no data just issue TexImage2D 1760 // If there's no data just issue TexImage2D
1721 if (!pixels) { 1761 if (!pixels) {
1722 helper_->TexImage2D( 1762 helper_->TexImage2D(
1723 target, level, internalformat, width, height, border, format, type, 1763 target, level, internalformat, width, height, border, format, type,
1724 0, 0); 1764 0, 0);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1810 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. 1850 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D.
1811 if (bound_pixel_unpack_transfer_buffer_id_) { 1851 if (bound_pixel_unpack_transfer_buffer_id_) {
1812 GLuint offset = ToGLuint(pixels); 1852 GLuint offset = ToGLuint(pixels);
1813 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 1853 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
1814 bound_pixel_unpack_transfer_buffer_id_, 1854 bound_pixel_unpack_transfer_buffer_id_,
1815 "glTexSubImage2D", offset, temp_size); 1855 "glTexSubImage2D", offset, temp_size);
1816 if (buffer && buffer->shm_id() != -1) { 1856 if (buffer && buffer->shm_id() != -1) {
1817 helper_->TexSubImage2D( 1857 helper_->TexSubImage2D(
1818 target, level, xoffset, yoffset, width, height, format, type, 1858 target, level, xoffset, yoffset, width, height, format, type,
1819 buffer->shm_id(), buffer->shm_offset() + offset, false); 1859 buffer->shm_id(), buffer->shm_offset() + offset, false);
1820 buffer->set_transfer_ready_token(helper_->InsertToken()); 1860 buffer->set_last_usage_token(helper_->InsertToken());
1821 CheckGLError(); 1861 CheckGLError();
1822 } 1862 }
1823 return; 1863 return;
1824 } 1864 }
1825 1865
1826 // compute the advance bytes per row for the src pixels 1866 // compute the advance bytes per row for the src pixels
1827 uint32 src_padded_row_size; 1867 uint32 src_padded_row_size;
1828 if (unpack_row_length_ > 0) { 1868 if (unpack_row_length_ > 0) {
1829 if (!GLES2Util::ComputeImagePaddedRowSize( 1869 if (!GLES2Util::ComputeImagePaddedRowSize(
1830 unpack_row_length_, format, type, unpack_alignment_, 1870 unpack_row_length_, format, type, unpack_alignment_,
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
2393 } 2433 }
2394 2434
2395 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id 2435 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id
2396 // generates a new resource. On newer versions of OpenGL they don't. The code 2436 // generates a new resource. On newer versions of OpenGL they don't. The code
2397 // related to binding below will need to change if we switch to the new OpenGL 2437 // related to binding below will need to change if we switch to the new OpenGL
2398 // model. Specifically it assumes a bind will succeed which is always true in 2438 // model. Specifically it assumes a bind will succeed which is always true in
2399 // the old model but possibly not true in the new model if another context has 2439 // the old model but possibly not true in the new model if another context has
2400 // deleted the resource. 2440 // deleted the resource.
2401 2441
2402 bool GLES2Implementation::BindBufferHelper( 2442 bool GLES2Implementation::BindBufferHelper(
2403 GLenum target, GLuint buffer) { 2443 GLenum target, GLuint buffer_id) {
2404 // TODO(gman): See note #1 above. 2444 // TODO(gman): See note #1 above.
2405 bool changed = false; 2445 bool changed = false;
2406 switch (target) { 2446 switch (target) {
2407 case GL_ARRAY_BUFFER: 2447 case GL_ARRAY_BUFFER:
2408 if (bound_array_buffer_id_ != buffer) { 2448 if (bound_array_buffer_id_ != buffer_id) {
2409 bound_array_buffer_id_ = buffer; 2449 bound_array_buffer_id_ = buffer_id;
2410 changed = true; 2450 changed = true;
2411 } 2451 }
2412 break; 2452 break;
2413 case GL_ELEMENT_ARRAY_BUFFER: 2453 case GL_ELEMENT_ARRAY_BUFFER:
2414 changed = vertex_array_object_manager_->BindElementArray(buffer); 2454 changed = vertex_array_object_manager_->BindElementArray(buffer_id);
2415 break; 2455 break;
2416 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: 2456 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
2417 bound_pixel_pack_transfer_buffer_id_ = buffer; 2457 bound_pixel_pack_transfer_buffer_id_ = buffer_id;
2418 break; 2458 break;
2419 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: 2459 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM:
2420 bound_pixel_unpack_transfer_buffer_id_ = buffer; 2460 bound_pixel_unpack_transfer_buffer_id_ = buffer_id;
2421 break; 2461 break;
2422 default: 2462 default:
2423 changed = true; 2463 changed = true;
2424 break; 2464 break;
2425 } 2465 }
2426 // TODO(gman): There's a bug here. If the target is invalid the ID will not be 2466 // TODO(gman): There's a bug here. If the target is invalid the ID will not be
2427 // used even though it's marked it as used here. 2467 // used even though it's marked it as used here.
2428 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); 2468 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer_id);
2429 return changed; 2469 return changed;
2430 } 2470 }
2431 2471
2432 bool GLES2Implementation::BindFramebufferHelper( 2472 bool GLES2Implementation::BindFramebufferHelper(
2433 GLenum target, GLuint framebuffer) { 2473 GLenum target, GLuint framebuffer) {
2434 // TODO(gman): See note #1 above. 2474 // TODO(gman): See note #1 above.
2435 bool changed = false; 2475 bool changed = false;
2436 switch (target) { 2476 switch (target) {
2437 case GL_FRAMEBUFFER: 2477 case GL_FRAMEBUFFER:
2438 if (bound_framebuffer_ != framebuffer || 2478 if (bound_framebuffer_ != framebuffer ||
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2552 SetGLError( 2592 SetGLError(
2553 GL_INVALID_VALUE, 2593 GL_INVALID_VALUE,
2554 "glDeleteBuffers", "id not created by this context."); 2594 "glDeleteBuffers", "id not created by this context.");
2555 return; 2595 return;
2556 } 2596 }
2557 for (GLsizei ii = 0; ii < n; ++ii) { 2597 for (GLsizei ii = 0; ii < n; ++ii) {
2558 if (buffers[ii] == bound_array_buffer_id_) { 2598 if (buffers[ii] == bound_array_buffer_id_) {
2559 bound_array_buffer_id_ = 0; 2599 bound_array_buffer_id_ = 0;
2560 } 2600 }
2561 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); 2601 vertex_array_object_manager_->UnbindBuffer(buffers[ii]);
2602
2562 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); 2603 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]);
2563 if (buffer) { 2604 if (buffer)
2564 // Free buffer memory, pending the passage of a token. 2605 RemoveTransferBuffer(buffer);
2565 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); 2606
2566 // Remove buffer.
2567 buffer_tracker_->RemoveBuffer(buffers[ii]);
2568 }
2569 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { 2607 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
2570 bound_pixel_unpack_transfer_buffer_id_ = 0; 2608 bound_pixel_unpack_transfer_buffer_id_ = 0;
2571 } 2609 }
2572 } 2610 }
2573 } 2611 }
2574 2612
2575 void GLES2Implementation::DeleteBuffersStub( 2613 void GLES2Implementation::DeleteBuffersStub(
2576 GLsizei n, const GLuint* buffers) { 2614 GLsizei n, const GLuint* buffers) {
2577 helper_->DeleteBuffersImmediate(n, buffers); 2615 helper_->DeleteBuffersImmediate(n, buffers);
2578 } 2616 }
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after
3602 } 3640 }
3603 if (buffer->mapped()) { 3641 if (buffer->mapped()) {
3604 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); 3642 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped");
3605 return NULL; 3643 return NULL;
3606 } 3644 }
3607 // Here we wait for previous transfer operations to be finished. 3645 // Here we wait for previous transfer operations to be finished.
3608 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work 3646 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work
3609 // with this method of synchronization. Until this is fixed, 3647 // with this method of synchronization. Until this is fixed,
3610 // MapBufferCHROMIUM will not block even if the transfer is not ready 3648 // MapBufferCHROMIUM will not block even if the transfer is not ready
3611 // for these calls. 3649 // for these calls.
3612 if (buffer->transfer_ready_token()) { 3650 if (buffer->last_usage_token()) {
3613 helper_->WaitForToken(buffer->transfer_ready_token()); 3651 helper_->WaitForToken(buffer->last_usage_token());
3614 buffer->set_transfer_ready_token(0); 3652 buffer->set_last_usage_token(0);
3615 } 3653 }
3616 buffer->set_mapped(true); 3654 buffer->set_mapped(true);
3617 3655
3618 GPU_CLIENT_LOG(" returned " << buffer->address()); 3656 GPU_CLIENT_LOG(" returned " << buffer->address());
3619 CheckGLError(); 3657 CheckGLError();
3620 return buffer->address(); 3658 return buffer->address();
3621 } 3659 }
3622 3660
3623 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { 3661 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) {
3624 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3662 GPU_CLIENT_SINGLE_THREAD_CHECK();
(...skipping 13 matching lines...) Expand all
3638 } 3676 }
3639 if (!buffer->mapped()) { 3677 if (!buffer->mapped()) {
3640 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); 3678 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped");
3641 return false; 3679 return false;
3642 } 3680 }
3643 buffer->set_mapped(false); 3681 buffer->set_mapped(false);
3644 CheckGLError(); 3682 CheckGLError();
3645 return true; 3683 return true;
3646 } 3684 }
3647 3685
3686 bool GLES2Implementation::EnsureAsyncUploadSync() {
3687 if (async_upload_sync_)
3688 return true;
3689
3690 int32 shm_id;
3691 unsigned int shm_offset;
3692 void* mem = mapped_memory_->Alloc(sizeof(AsyncUploadSync),
3693 &shm_id,
3694 &shm_offset);
3695 if (!mem)
3696 return false;
3697
3698 async_upload_sync_shm_id_ = shm_id;
3699 async_upload_sync_shm_offset_ = shm_offset;
3700 async_upload_sync_ = static_cast<AsyncUploadSync*>(mem);
3701 async_upload_sync_->Reset();
3702
3703 return true;
3704 }
3705
3706 uint32 GLES2Implementation::NextAsyncUploadToken() {
3707 async_upload_token_++;
3708 if (async_upload_token_ == 0)
3709 async_upload_token_++;
3710 return async_upload_token_;
3711 }
3712
3713 void GLES2Implementation::PollAsyncUploads() {
3714 if (!async_upload_sync_)
3715 return;
3716
3717 if (helper_->IsContextLost()) {
3718 DetachedAsyncUploadMemoryList::iterator it =
3719 detached_async_upload_memory_.begin();
3720 while (it != detached_async_upload_memory_.end()) {
3721 mapped_memory_->Free(it->first);
3722 it = detached_async_upload_memory_.erase(it);
3723 }
3724 return;
3725 }
3726
3727 DetachedAsyncUploadMemoryList::iterator it =
3728 detached_async_upload_memory_.begin();
3729 while (it != detached_async_upload_memory_.end()) {
3730 if (HasAsyncUploadTokenPassed(it->second)) {
3731 mapped_memory_->Free(it->first);
3732 it = detached_async_upload_memory_.erase(it);
3733 } else {
3734 break;
3735 }
3736 }
3737 }
3738
3739 void GLES2Implementation::FreeAllAsyncUploadBuffers() {
3740 // Free all completed unmanaged async uploads buffers.
3741 PollAsyncUploads();
3742
3743 // Synchronously free rest of the unmanaged async upload buffers.
3744 if (!detached_async_upload_memory_.empty()) {
3745 WaitAllAsyncTexImage2DCHROMIUM();
3746 WaitForCmd();
3747 PollAsyncUploads();
3748 }
3749 }
3750
3648 void GLES2Implementation::AsyncTexImage2DCHROMIUM( 3751 void GLES2Implementation::AsyncTexImage2DCHROMIUM(
3649 GLenum target, GLint level, GLint internalformat, GLsizei width, 3752 GLenum target, GLint level, GLint internalformat, GLsizei width,
3650 GLsizei height, GLint border, GLenum format, GLenum type, 3753 GLsizei height, GLint border, GLenum format, GLenum type,
3651 const void* pixels) { 3754 const void* pixels) {
3652 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3755 GPU_CLIENT_SINGLE_THREAD_CHECK();
3653 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" 3756 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D("
3654 << GLES2Util::GetStringTextureTarget(target) << ", " 3757 << GLES2Util::GetStringTextureTarget(target) << ", "
3655 << level << ", " 3758 << level << ", "
3656 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " 3759 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", "
3657 << width << ", " << height << ", " << border << ", " 3760 << width << ", " << height << ", " << border << ", "
(...skipping 11 matching lines...) Expand all
3669 width, height, format, type, unpack_alignment_, &size, 3772 width, height, format, type, unpack_alignment_, &size,
3670 &unpadded_row_size, &padded_row_size)) { 3773 &unpadded_row_size, &padded_row_size)) {
3671 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); 3774 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large");
3672 return; 3775 return;
3673 } 3776 }
3674 3777
3675 // If there's no data/buffer just issue the AsyncTexImage2D 3778 // If there's no data/buffer just issue the AsyncTexImage2D
3676 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { 3779 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) {
3677 helper_->AsyncTexImage2DCHROMIUM( 3780 helper_->AsyncTexImage2DCHROMIUM(
3678 target, level, internalformat, width, height, border, format, type, 3781 target, level, internalformat, width, height, border, format, type,
3679 0, 0); 3782 0, 0, 0, 0, 0);
3680 return; 3783 return;
3681 } 3784 }
3682 3785
3786 if (!EnsureAsyncUploadSync()) {
3787 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
3788 return;
3789 }
3790
3683 // Otherwise, async uploads require a transfer buffer to be bound. 3791 // Otherwise, async uploads require a transfer buffer to be bound.
3684 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use 3792 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use
3685 // the buffer before the transfer is finished. (Currently such 3793 // the buffer before the transfer is finished. (Currently such
3686 // synchronization has to be handled manually.) 3794 // synchronization has to be handled manually.)
3687 GLuint offset = ToGLuint(pixels); 3795 GLuint offset = ToGLuint(pixels);
3688 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 3796 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
3689 bound_pixel_unpack_transfer_buffer_id_, 3797 bound_pixel_unpack_transfer_buffer_id_,
3690 "glAsyncTexImage2DCHROMIUM", offset, size); 3798 "glAsyncTexImage2DCHROMIUM", offset, size);
3691 if (buffer && buffer->shm_id() != -1) { 3799 if (buffer && buffer->shm_id() != -1) {
3800 uint32 async_token = NextAsyncUploadToken();
3801 buffer->set_last_async_upload_token(async_token);
3692 helper_->AsyncTexImage2DCHROMIUM( 3802 helper_->AsyncTexImage2DCHROMIUM(
3693 target, level, internalformat, width, height, border, format, type, 3803 target, level, internalformat, width, height, border, format, type,
3694 buffer->shm_id(), buffer->shm_offset() + offset); 3804 buffer->shm_id(), buffer->shm_offset() + offset,
3805 async_token,
3806 async_upload_sync_shm_id_, async_upload_sync_shm_offset_);
3695 } 3807 }
3696 } 3808 }
3697 3809
3698 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( 3810 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM(
3699 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, 3811 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
3700 GLsizei height, GLenum format, GLenum type, const void* pixels) { 3812 GLsizei height, GLenum format, GLenum type, const void* pixels) {
3701 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3813 GPU_CLIENT_SINGLE_THREAD_CHECK();
3702 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" 3814 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM("
3703 << GLES2Util::GetStringTextureTarget(target) << ", " 3815 << GLES2Util::GetStringTextureTarget(target) << ", "
3704 << level << ", " 3816 << level << ", "
(...skipping 12 matching lines...) Expand all
3717 uint32 unpadded_row_size; 3829 uint32 unpadded_row_size;
3718 uint32 padded_row_size; 3830 uint32 padded_row_size;
3719 if (!GLES2Util::ComputeImageDataSizes( 3831 if (!GLES2Util::ComputeImageDataSizes(
3720 width, height, format, type, unpack_alignment_, &size, 3832 width, height, format, type, unpack_alignment_, &size,
3721 &unpadded_row_size, &padded_row_size)) { 3833 &unpadded_row_size, &padded_row_size)) {
3722 SetGLError( 3834 SetGLError(
3723 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); 3835 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large");
3724 return; 3836 return;
3725 } 3837 }
3726 3838
3839 if (!EnsureAsyncUploadSync()) {
3840 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
3841 return;
3842 }
3843
3727 // Async uploads require a transfer buffer to be bound. 3844 // Async uploads require a transfer buffer to be bound.
3728 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use 3845 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use
3729 // the buffer before the transfer is finished. (Currently such 3846 // the buffer before the transfer is finished. (Currently such
3730 // synchronization has to be handled manually.) 3847 // synchronization has to be handled manually.)
3731 GLuint offset = ToGLuint(pixels); 3848 GLuint offset = ToGLuint(pixels);
3732 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( 3849 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
3733 bound_pixel_unpack_transfer_buffer_id_, 3850 bound_pixel_unpack_transfer_buffer_id_,
3734 "glAsyncTexSubImage2DCHROMIUM", offset, size); 3851 "glAsyncTexSubImage2DCHROMIUM", offset, size);
3735 if (buffer && buffer->shm_id() != -1) { 3852 if (buffer && buffer->shm_id() != -1) {
3853 uint32 async_token = NextAsyncUploadToken();
3854 buffer->set_last_async_upload_token(async_token);
3736 helper_->AsyncTexSubImage2DCHROMIUM( 3855 helper_->AsyncTexSubImage2DCHROMIUM(
3737 target, level, xoffset, yoffset, width, height, format, type, 3856 target, level, xoffset, yoffset, width, height, format, type,
3738 buffer->shm_id(), buffer->shm_offset() + offset); 3857 buffer->shm_id(), buffer->shm_offset() + offset,
3858 async_token,
3859 async_upload_sync_shm_id_, async_upload_sync_shm_offset_);
3739 } 3860 }
3740 } 3861 }
3741 3862
3742 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { 3863 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) {
3743 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3864 GPU_CLIENT_SINGLE_THREAD_CHECK();
3744 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM(" 3865 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM("
3745 << GLES2Util::GetStringTextureTarget(target) << ")"); 3866 << GLES2Util::GetStringTextureTarget(target) << ")");
3746 helper_->WaitAsyncTexImage2DCHROMIUM(target); 3867 helper_->WaitAsyncTexImage2DCHROMIUM(target);
3747 CheckGLError(); 3868 CheckGLError();
3748 } 3869 }
3749 3870
3871 void GLES2Implementation::WaitAllAsyncTexImage2DCHROMIUM() {
3872 GPU_CLIENT_SINGLE_THREAD_CHECK();
3873 GPU_CLIENT_LOG("[" << GetLogPrefix()
3874 << "] glWaitAllAsyncTexImage2DCHROMIUM()");
3875 helper_->WaitAllAsyncTexImage2DCHROMIUM();
3876 CheckGLError();
3877 }
3878
3750 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { 3879 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() {
3751 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3880 GPU_CLIENT_SINGLE_THREAD_CHECK();
3752 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM"); 3881 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM");
3753 helper_->CommandBufferHelper::Flush(); 3882 helper_->CommandBufferHelper::Flush();
3754 return gpu_control_->InsertSyncPoint(); 3883 return gpu_control_->InsertSyncPoint();
3755 } 3884 }
3756 3885
3757 GLuint GLES2Implementation::CreateImageCHROMIUMHelper( 3886 GLuint GLES2Implementation::CreateImageCHROMIUMHelper(
3758 GLsizei width, GLsizei height, GLenum internalformat) { 3887 GLsizei width, GLsizei height, GLenum internalformat) {
3759 if (width <= 0) { 3888 if (width <= 0) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3921 CheckGLError(); 4050 CheckGLError();
3922 } 4051 }
3923 4052
3924 // Include the auto-generated part of this file. We split this because it means 4053 // Include the auto-generated part of this file. We split this because it means
3925 // we can easily edit the non-auto generated parts right here in this file 4054 // we can easily edit the non-auto generated parts right here in this file
3926 // instead of having to edit some template or the code generator. 4055 // instead of having to edit some template or the code generator.
3927 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" 4056 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h"
3928 4057
3929 } // namespace gles2 4058 } // namespace gles2
3930 } // namespace gpu 4059 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698