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

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

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

Powered by Google App Engine
This is Rietveld 408576698