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 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |