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