OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |