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 <stdio.h> | 14 #include <stdio.h> |
15 #include <string.h> | 15 #include <string.h> |
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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 unpack_skip_pixels_(0), | 101 unpack_skip_pixels_(0), |
101 pack_reverse_row_order_(false), | 102 pack_reverse_row_order_(false), |
102 active_texture_unit_(0), | 103 active_texture_unit_(0), |
103 bound_framebuffer_(0), | 104 bound_framebuffer_(0), |
104 bound_read_framebuffer_(0), | 105 bound_read_framebuffer_(0), |
105 bound_renderbuffer_(0), | 106 bound_renderbuffer_(0), |
106 current_program_(0), | 107 current_program_(0), |
107 bound_array_buffer_id_(0), | 108 bound_array_buffer_id_(0), |
108 bound_pixel_pack_transfer_buffer_id_(0), | 109 bound_pixel_pack_transfer_buffer_id_(0), |
109 bound_pixel_unpack_transfer_buffer_id_(0), | 110 bound_pixel_unpack_transfer_buffer_id_(0), |
| 111 async_upload_token_(0), |
| 112 async_upload_sync_(NULL), |
| 113 async_upload_sync_shm_id_(0), |
| 114 async_upload_sync_shm_offset_(0), |
110 error_bits_(0), | 115 error_bits_(0), |
111 debug_(false), | 116 debug_(false), |
112 use_count_(0), | 117 use_count_(0), |
113 error_message_callback_(NULL), | 118 error_message_callback_(NULL), |
114 gpu_control_(gpu_control), | 119 gpu_control_(gpu_control), |
115 surface_visible_(true), | 120 surface_visible_(true), |
116 free_everything_when_invisible_(free_everything_when_invisible), | 121 free_everything_when_invisible_(free_everything_when_invisible), |
117 capabilities_(gpu_control->GetCapabilities()), | 122 capabilities_(gpu_control->GetCapabilities()), |
118 weak_ptr_factory_(this) { | 123 weak_ptr_factory_(this) { |
119 DCHECK(helper); | 124 DCHECK(helper); |
(...skipping 27 matching lines...) Expand all Loading... |
147 if (!transfer_buffer_->Initialize( | 152 if (!transfer_buffer_->Initialize( |
148 starting_transfer_buffer_size, | 153 starting_transfer_buffer_size, |
149 kStartingOffset, | 154 kStartingOffset, |
150 min_transfer_buffer_size, | 155 min_transfer_buffer_size, |
151 max_transfer_buffer_size, | 156 max_transfer_buffer_size, |
152 kAlignment, | 157 kAlignment, |
153 kSizeToFlush)) { | 158 kSizeToFlush)) { |
154 return false; | 159 return false; |
155 } | 160 } |
156 | 161 |
157 mapped_memory_.reset(new MappedMemoryManager(helper_, mapped_memory_limit)); | 162 mapped_memory_.reset( |
| 163 new MappedMemoryManager( |
| 164 helper_, |
| 165 base::Bind(&GLES2Implementation::PollAsyncUploads, |
| 166 // The mapped memory manager is owned by |this| here, and |
| 167 // since its destroyed before before we destroy ourselves |
| 168 // we don't need extra safety measures for this closure. |
| 169 base::Unretained(this)), |
| 170 mapped_memory_limit)); |
158 | 171 |
159 unsigned chunk_size = 2 * 1024 * 1024; | 172 unsigned chunk_size = 2 * 1024 * 1024; |
160 if (mapped_memory_limit != kNoLimit) { | 173 if (mapped_memory_limit != kNoLimit) { |
161 // Use smaller chunks if the client is very memory conscientious. | 174 // Use smaller chunks if the client is very memory conscientious. |
162 chunk_size = std::min(mapped_memory_limit / 4, chunk_size); | 175 chunk_size = std::min(mapped_memory_limit / 4, chunk_size); |
163 } | 176 } |
164 mapped_memory_->set_chunk_size_multiple(chunk_size); | 177 mapped_memory_->set_chunk_size_multiple(chunk_size); |
165 | 178 |
166 if (!QueryAndCacheStaticState()) | 179 if (!QueryAndCacheStaticState()) |
167 return false; | 180 return false; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 // by the queries. The GPU process when validating that memory is still | 283 // by the queries. The GPU process when validating that memory is still |
271 // shared will fail and abort (ie, it will stop running). | 284 // shared will fail and abort (ie, it will stop running). |
272 WaitForCmd(); | 285 WaitForCmd(); |
273 query_tracker_.reset(); | 286 query_tracker_.reset(); |
274 | 287 |
275 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 288 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
276 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); | 289 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); |
277 #endif | 290 #endif |
278 buffer_tracker_.reset(); | 291 buffer_tracker_.reset(); |
279 | 292 |
| 293 FreeAllAsyncUploadBuffers(); |
| 294 |
| 295 if (async_upload_sync_) { |
| 296 mapped_memory_->Free(async_upload_sync_); |
| 297 async_upload_sync_ = NULL; |
| 298 } |
| 299 |
280 // Make sure the commands make it the service. | 300 // Make sure the commands make it the service. |
281 WaitForCmd(); | 301 WaitForCmd(); |
282 } | 302 } |
283 | 303 |
284 GLES2CmdHelper* GLES2Implementation::helper() const { | 304 GLES2CmdHelper* GLES2Implementation::helper() const { |
285 return helper_; | 305 return helper_; |
286 } | 306 } |
287 | 307 |
288 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { | 308 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { |
289 return share_group_->GetIdHandler(namespace_id); | 309 return share_group_->GetIdHandler(namespace_id); |
290 } | 310 } |
291 | 311 |
292 void* GLES2Implementation::GetResultBuffer() { | 312 void* GLES2Implementation::GetResultBuffer() { |
293 return transfer_buffer_->GetResultBuffer(); | 313 return transfer_buffer_->GetResultBuffer(); |
294 } | 314 } |
295 | 315 |
296 int32 GLES2Implementation::GetResultShmId() { | 316 int32 GLES2Implementation::GetResultShmId() { |
297 return transfer_buffer_->GetShmId(); | 317 return transfer_buffer_->GetShmId(); |
298 } | 318 } |
299 | 319 |
300 uint32 GLES2Implementation::GetResultShmOffset() { | 320 uint32 GLES2Implementation::GetResultShmOffset() { |
301 return transfer_buffer_->GetResultOffset(); | 321 return transfer_buffer_->GetResultOffset(); |
302 } | 322 } |
303 | 323 |
304 void GLES2Implementation::FreeUnusedSharedMemory() { | 324 void GLES2Implementation::FreeUnusedSharedMemory() { |
305 mapped_memory_->FreeUnused(); | 325 mapped_memory_->FreeUnused(); |
306 } | 326 } |
307 | 327 |
308 void GLES2Implementation::FreeEverything() { | 328 void GLES2Implementation::FreeEverything() { |
| 329 FreeAllAsyncUploadBuffers(); |
309 WaitForCmd(); | 330 WaitForCmd(); |
310 query_tracker_->Shrink(); | 331 query_tracker_->Shrink(); |
311 FreeUnusedSharedMemory(); | 332 FreeUnusedSharedMemory(); |
312 transfer_buffer_->Free(); | 333 transfer_buffer_->Free(); |
313 helper_->FreeRingBuffer(); | 334 helper_->FreeRingBuffer(); |
314 } | 335 } |
315 | 336 |
316 void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) { | 337 void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) { |
317 if (!helper_->IsContextLost()) | 338 if (!helper_->IsContextLost()) |
318 callback.Run(); | 339 callback.Run(); |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 return; | 1392 return; |
1372 } | 1393 } |
1373 | 1394 |
1374 GLuint buffer_id; | 1395 GLuint buffer_id; |
1375 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { | 1396 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { |
1376 if (!buffer_id) { | 1397 if (!buffer_id) { |
1377 return; | 1398 return; |
1378 } | 1399 } |
1379 | 1400 |
1380 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | 1401 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
1381 if (buffer) { | 1402 if (buffer) |
1382 // Free buffer memory, pending the passage of a token. | 1403 RemoveTransferBuffer(buffer); |
1383 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | |
1384 | |
1385 // Remove old buffer. | |
1386 buffer_tracker_->RemoveBuffer(buffer_id); | |
1387 } | |
1388 | 1404 |
1389 // Create new buffer. | 1405 // Create new buffer. |
1390 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); | 1406 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); |
1391 DCHECK(buffer); | 1407 DCHECK(buffer); |
1392 if (buffer->address() && data) | 1408 if (buffer->address() && data) |
1393 memcpy(buffer->address(), data, size); | 1409 memcpy(buffer->address(), data, size); |
1394 return; | 1410 return; |
1395 } | 1411 } |
1396 | 1412 |
1397 if (size == 0) { | 1413 if (size == 0) { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1521 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
1506 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1522 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1507 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" | 1523 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" |
1508 << GLES2Util::GetStringBufferTarget(target) << ", " | 1524 << GLES2Util::GetStringBufferTarget(target) << ", " |
1509 << offset << ", " << size << ", " | 1525 << offset << ", " << size << ", " |
1510 << static_cast<const void*>(data) << ")"); | 1526 << static_cast<const void*>(data) << ")"); |
1511 BufferSubDataHelper(target, offset, size, data); | 1527 BufferSubDataHelper(target, offset, size, data); |
1512 CheckGLError(); | 1528 CheckGLError(); |
1513 } | 1529 } |
1514 | 1530 |
| 1531 void GLES2Implementation::RemoveTransferBuffer(BufferTracker::Buffer* buffer) { |
| 1532 int32 token = buffer->last_usage_token(); |
| 1533 uint32 async_token = buffer->last_async_upload_token(); |
| 1534 |
| 1535 if (async_token) { |
| 1536 if (HasAsyncUploadTokenPassed(async_token)) { |
| 1537 buffer_tracker_->Free(buffer); |
| 1538 } else { |
| 1539 detached_async_upload_memory_.push_back( |
| 1540 std::make_pair(buffer->address(), async_token)); |
| 1541 buffer_tracker_->Unmanage(buffer); |
| 1542 } |
| 1543 } else if (token) { |
| 1544 if (helper_->HasTokenPassed(token)) |
| 1545 buffer_tracker_->Free(buffer); |
| 1546 else |
| 1547 buffer_tracker_->FreePendingToken(buffer, token); |
| 1548 } else { |
| 1549 buffer_tracker_->Free(buffer); |
| 1550 } |
| 1551 |
| 1552 buffer_tracker_->RemoveBuffer(buffer->id()); |
| 1553 } |
| 1554 |
1515 bool GLES2Implementation::GetBoundPixelTransferBuffer( | 1555 bool GLES2Implementation::GetBoundPixelTransferBuffer( |
1516 GLenum target, | 1556 GLenum target, |
1517 const char* function_name, | 1557 const char* function_name, |
1518 GLuint* buffer_id) { | 1558 GLuint* buffer_id) { |
1519 *buffer_id = 0; | 1559 *buffer_id = 0; |
1520 | 1560 |
1521 switch (target) { | 1561 switch (target) { |
1522 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | 1562 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
1523 *buffer_id = bound_pixel_pack_transfer_buffer_id_; | 1563 *buffer_id = bound_pixel_pack_transfer_buffer_id_; |
1524 break; | 1564 break; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 // CompressedTexImage2D. | 1620 // CompressedTexImage2D. |
1581 if (bound_pixel_unpack_transfer_buffer_id_) { | 1621 if (bound_pixel_unpack_transfer_buffer_id_) { |
1582 GLuint offset = ToGLuint(data); | 1622 GLuint offset = ToGLuint(data); |
1583 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1623 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
1584 bound_pixel_unpack_transfer_buffer_id_, | 1624 bound_pixel_unpack_transfer_buffer_id_, |
1585 "glCompressedTexImage2D", offset, image_size); | 1625 "glCompressedTexImage2D", offset, image_size); |
1586 if (buffer && buffer->shm_id() != -1) { | 1626 if (buffer && buffer->shm_id() != -1) { |
1587 helper_->CompressedTexImage2D( | 1627 helper_->CompressedTexImage2D( |
1588 target, level, internalformat, width, height, border, image_size, | 1628 target, level, internalformat, width, height, border, image_size, |
1589 buffer->shm_id(), buffer->shm_offset() + offset); | 1629 buffer->shm_id(), buffer->shm_offset() + offset); |
1590 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1630 buffer->set_last_usage_token(helper_->InsertToken()); |
1591 } | 1631 } |
1592 return; | 1632 return; |
1593 } | 1633 } |
1594 SetBucketContents(kResultBucketId, data, image_size); | 1634 SetBucketContents(kResultBucketId, data, image_size); |
1595 helper_->CompressedTexImage2DBucket( | 1635 helper_->CompressedTexImage2DBucket( |
1596 target, level, internalformat, width, height, border, kResultBucketId); | 1636 target, level, internalformat, width, height, border, kResultBucketId); |
1597 // Free the bucket. This is not required but it does free up the memory. | 1637 // Free the bucket. This is not required but it does free up the memory. |
1598 // and we don't have to wait for the result so from the client's perspective | 1638 // and we don't have to wait for the result so from the client's perspective |
1599 // it's cheap. | 1639 // it's cheap. |
1600 helper_->SetBucketSize(kResultBucketId, 0); | 1640 helper_->SetBucketSize(kResultBucketId, 0); |
(...skipping 20 matching lines...) Expand all Loading... |
1621 // CompressedTexSubImage2D. | 1661 // CompressedTexSubImage2D. |
1622 if (bound_pixel_unpack_transfer_buffer_id_) { | 1662 if (bound_pixel_unpack_transfer_buffer_id_) { |
1623 GLuint offset = ToGLuint(data); | 1663 GLuint offset = ToGLuint(data); |
1624 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1664 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
1625 bound_pixel_unpack_transfer_buffer_id_, | 1665 bound_pixel_unpack_transfer_buffer_id_, |
1626 "glCompressedTexSubImage2D", offset, image_size); | 1666 "glCompressedTexSubImage2D", offset, image_size); |
1627 if (buffer && buffer->shm_id() != -1) { | 1667 if (buffer && buffer->shm_id() != -1) { |
1628 helper_->CompressedTexSubImage2D( | 1668 helper_->CompressedTexSubImage2D( |
1629 target, level, xoffset, yoffset, width, height, format, image_size, | 1669 target, level, xoffset, yoffset, width, height, format, image_size, |
1630 buffer->shm_id(), buffer->shm_offset() + offset); | 1670 buffer->shm_id(), buffer->shm_offset() + offset); |
1631 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1671 buffer->set_last_usage_token(helper_->InsertToken()); |
1632 CheckGLError(); | 1672 CheckGLError(); |
1633 } | 1673 } |
1634 return; | 1674 return; |
1635 } | 1675 } |
1636 SetBucketContents(kResultBucketId, data, image_size); | 1676 SetBucketContents(kResultBucketId, data, image_size); |
1637 helper_->CompressedTexSubImage2DBucket( | 1677 helper_->CompressedTexSubImage2DBucket( |
1638 target, level, xoffset, yoffset, width, height, format, kResultBucketId); | 1678 target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
1639 // Free the bucket. This is not required but it does free up the memory. | 1679 // Free the bucket. This is not required but it does free up the memory. |
1640 // and we don't have to wait for the result so from the client's perspective | 1680 // and we don't have to wait for the result so from the client's perspective |
1641 // it's cheap. | 1681 // it's cheap. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. | 1748 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
1709 if (bound_pixel_unpack_transfer_buffer_id_) { | 1749 if (bound_pixel_unpack_transfer_buffer_id_) { |
1710 GLuint offset = ToGLuint(pixels); | 1750 GLuint offset = ToGLuint(pixels); |
1711 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1751 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
1712 bound_pixel_unpack_transfer_buffer_id_, | 1752 bound_pixel_unpack_transfer_buffer_id_, |
1713 "glTexImage2D", offset, size); | 1753 "glTexImage2D", offset, size); |
1714 if (buffer && buffer->shm_id() != -1) { | 1754 if (buffer && buffer->shm_id() != -1) { |
1715 helper_->TexImage2D( | 1755 helper_->TexImage2D( |
1716 target, level, internalformat, width, height, border, format, type, | 1756 target, level, internalformat, width, height, border, format, type, |
1717 buffer->shm_id(), buffer->shm_offset() + offset); | 1757 buffer->shm_id(), buffer->shm_offset() + offset); |
1718 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1758 buffer->set_last_usage_token(helper_->InsertToken()); |
1719 CheckGLError(); | 1759 CheckGLError(); |
1720 } | 1760 } |
1721 return; | 1761 return; |
1722 } | 1762 } |
1723 | 1763 |
1724 // If there's no data just issue TexImage2D | 1764 // If there's no data just issue TexImage2D |
1725 if (!pixels) { | 1765 if (!pixels) { |
1726 helper_->TexImage2D( | 1766 helper_->TexImage2D( |
1727 target, level, internalformat, width, height, border, format, type, | 1767 target, level, internalformat, width, height, border, format, type, |
1728 0, 0); | 1768 0, 0); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1814 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | 1854 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
1815 if (bound_pixel_unpack_transfer_buffer_id_) { | 1855 if (bound_pixel_unpack_transfer_buffer_id_) { |
1816 GLuint offset = ToGLuint(pixels); | 1856 GLuint offset = ToGLuint(pixels); |
1817 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1857 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
1818 bound_pixel_unpack_transfer_buffer_id_, | 1858 bound_pixel_unpack_transfer_buffer_id_, |
1819 "glTexSubImage2D", offset, temp_size); | 1859 "glTexSubImage2D", offset, temp_size); |
1820 if (buffer && buffer->shm_id() != -1) { | 1860 if (buffer && buffer->shm_id() != -1) { |
1821 helper_->TexSubImage2D( | 1861 helper_->TexSubImage2D( |
1822 target, level, xoffset, yoffset, width, height, format, type, | 1862 target, level, xoffset, yoffset, width, height, format, type, |
1823 buffer->shm_id(), buffer->shm_offset() + offset, false); | 1863 buffer->shm_id(), buffer->shm_offset() + offset, false); |
1824 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1864 buffer->set_last_usage_token(helper_->InsertToken()); |
1825 CheckGLError(); | 1865 CheckGLError(); |
1826 } | 1866 } |
1827 return; | 1867 return; |
1828 } | 1868 } |
1829 | 1869 |
1830 // compute the advance bytes per row for the src pixels | 1870 // compute the advance bytes per row for the src pixels |
1831 uint32 src_padded_row_size; | 1871 uint32 src_padded_row_size; |
1832 if (unpack_row_length_ > 0) { | 1872 if (unpack_row_length_ > 0) { |
1833 if (!GLES2Util::ComputeImagePaddedRowSize( | 1873 if (!GLES2Util::ComputeImagePaddedRowSize( |
1834 unpack_row_length_, format, type, unpack_alignment_, | 1874 unpack_row_length_, format, type, unpack_alignment_, |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2397 } | 2437 } |
2398 | 2438 |
2399 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id | 2439 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id |
2400 // generates a new resource. On newer versions of OpenGL they don't. The code | 2440 // generates a new resource. On newer versions of OpenGL they don't. The code |
2401 // related to binding below will need to change if we switch to the new OpenGL | 2441 // related to binding below will need to change if we switch to the new OpenGL |
2402 // model. Specifically it assumes a bind will succeed which is always true in | 2442 // model. Specifically it assumes a bind will succeed which is always true in |
2403 // the old model but possibly not true in the new model if another context has | 2443 // the old model but possibly not true in the new model if another context has |
2404 // deleted the resource. | 2444 // deleted the resource. |
2405 | 2445 |
2406 bool GLES2Implementation::BindBufferHelper( | 2446 bool GLES2Implementation::BindBufferHelper( |
2407 GLenum target, GLuint buffer) { | 2447 GLenum target, GLuint buffer_id) { |
2408 // TODO(gman): See note #1 above. | 2448 // TODO(gman): See note #1 above. |
2409 bool changed = false; | 2449 bool changed = false; |
2410 switch (target) { | 2450 switch (target) { |
2411 case GL_ARRAY_BUFFER: | 2451 case GL_ARRAY_BUFFER: |
2412 if (bound_array_buffer_id_ != buffer) { | 2452 if (bound_array_buffer_id_ != buffer_id) { |
2413 bound_array_buffer_id_ = buffer; | 2453 bound_array_buffer_id_ = buffer_id; |
2414 changed = true; | 2454 changed = true; |
2415 } | 2455 } |
2416 break; | 2456 break; |
2417 case GL_ELEMENT_ARRAY_BUFFER: | 2457 case GL_ELEMENT_ARRAY_BUFFER: |
2418 changed = vertex_array_object_manager_->BindElementArray(buffer); | 2458 changed = vertex_array_object_manager_->BindElementArray(buffer_id); |
2419 break; | 2459 break; |
2420 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | 2460 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
2421 bound_pixel_pack_transfer_buffer_id_ = buffer; | 2461 bound_pixel_pack_transfer_buffer_id_ = buffer_id; |
2422 break; | 2462 break; |
2423 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | 2463 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
2424 bound_pixel_unpack_transfer_buffer_id_ = buffer; | 2464 bound_pixel_unpack_transfer_buffer_id_ = buffer_id; |
2425 break; | 2465 break; |
2426 default: | 2466 default: |
2427 changed = true; | 2467 changed = true; |
2428 break; | 2468 break; |
2429 } | 2469 } |
2430 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2470 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
2431 // used even though it's marked it as used here. | 2471 // used even though it's marked it as used here. |
2432 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2472 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer_id); |
2433 return changed; | 2473 return changed; |
2434 } | 2474 } |
2435 | 2475 |
2436 bool GLES2Implementation::BindFramebufferHelper( | 2476 bool GLES2Implementation::BindFramebufferHelper( |
2437 GLenum target, GLuint framebuffer) { | 2477 GLenum target, GLuint framebuffer) { |
2438 // TODO(gman): See note #1 above. | 2478 // TODO(gman): See note #1 above. |
2439 bool changed = false; | 2479 bool changed = false; |
2440 switch (target) { | 2480 switch (target) { |
2441 case GL_FRAMEBUFFER: | 2481 case GL_FRAMEBUFFER: |
2442 if (bound_framebuffer_ != framebuffer || | 2482 if (bound_framebuffer_ != framebuffer || |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2556 SetGLError( | 2596 SetGLError( |
2557 GL_INVALID_VALUE, | 2597 GL_INVALID_VALUE, |
2558 "glDeleteBuffers", "id not created by this context."); | 2598 "glDeleteBuffers", "id not created by this context."); |
2559 return; | 2599 return; |
2560 } | 2600 } |
2561 for (GLsizei ii = 0; ii < n; ++ii) { | 2601 for (GLsizei ii = 0; ii < n; ++ii) { |
2562 if (buffers[ii] == bound_array_buffer_id_) { | 2602 if (buffers[ii] == bound_array_buffer_id_) { |
2563 bound_array_buffer_id_ = 0; | 2603 bound_array_buffer_id_ = 0; |
2564 } | 2604 } |
2565 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); | 2605 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); |
| 2606 |
2566 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); | 2607 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
2567 if (buffer) { | 2608 if (buffer) |
2568 // Free buffer memory, pending the passage of a token. | 2609 RemoveTransferBuffer(buffer); |
2569 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | 2610 |
2570 // Remove buffer. | |
2571 buffer_tracker_->RemoveBuffer(buffers[ii]); | |
2572 } | |
2573 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { | 2611 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
2574 bound_pixel_unpack_transfer_buffer_id_ = 0; | 2612 bound_pixel_unpack_transfer_buffer_id_ = 0; |
2575 } | 2613 } |
2576 } | 2614 } |
2577 } | 2615 } |
2578 | 2616 |
2579 void GLES2Implementation::DeleteBuffersStub( | 2617 void GLES2Implementation::DeleteBuffersStub( |
2580 GLsizei n, const GLuint* buffers) { | 2618 GLsizei n, const GLuint* buffers) { |
2581 helper_->DeleteBuffersImmediate(n, buffers); | 2619 helper_->DeleteBuffersImmediate(n, buffers); |
2582 } | 2620 } |
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3584 } | 3622 } |
3585 if (buffer->mapped()) { | 3623 if (buffer->mapped()) { |
3586 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); | 3624 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); |
3587 return NULL; | 3625 return NULL; |
3588 } | 3626 } |
3589 // Here we wait for previous transfer operations to be finished. | 3627 // Here we wait for previous transfer operations to be finished. |
3590 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work | 3628 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work |
3591 // with this method of synchronization. Until this is fixed, | 3629 // with this method of synchronization. Until this is fixed, |
3592 // MapBufferCHROMIUM will not block even if the transfer is not ready | 3630 // MapBufferCHROMIUM will not block even if the transfer is not ready |
3593 // for these calls. | 3631 // for these calls. |
3594 if (buffer->transfer_ready_token()) { | 3632 if (buffer->last_usage_token()) { |
3595 helper_->WaitForToken(buffer->transfer_ready_token()); | 3633 helper_->WaitForToken(buffer->last_usage_token()); |
3596 buffer->set_transfer_ready_token(0); | 3634 buffer->set_last_usage_token(0); |
3597 } | 3635 } |
3598 buffer->set_mapped(true); | 3636 buffer->set_mapped(true); |
3599 | 3637 |
3600 GPU_CLIENT_LOG(" returned " << buffer->address()); | 3638 GPU_CLIENT_LOG(" returned " << buffer->address()); |
3601 CheckGLError(); | 3639 CheckGLError(); |
3602 return buffer->address(); | 3640 return buffer->address(); |
3603 } | 3641 } |
3604 | 3642 |
3605 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { | 3643 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
3606 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3644 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
(...skipping 13 matching lines...) Expand all Loading... |
3620 } | 3658 } |
3621 if (!buffer->mapped()) { | 3659 if (!buffer->mapped()) { |
3622 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); | 3660 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); |
3623 return false; | 3661 return false; |
3624 } | 3662 } |
3625 buffer->set_mapped(false); | 3663 buffer->set_mapped(false); |
3626 CheckGLError(); | 3664 CheckGLError(); |
3627 return true; | 3665 return true; |
3628 } | 3666 } |
3629 | 3667 |
| 3668 bool GLES2Implementation::EnsureAsyncUploadSync() { |
| 3669 if (async_upload_sync_) |
| 3670 return true; |
| 3671 |
| 3672 int32 shm_id; |
| 3673 unsigned int shm_offset; |
| 3674 void* mem = mapped_memory_->Alloc(sizeof(AsyncUploadSync), |
| 3675 &shm_id, |
| 3676 &shm_offset); |
| 3677 if (!mem) |
| 3678 return false; |
| 3679 |
| 3680 async_upload_sync_shm_id_ = shm_id; |
| 3681 async_upload_sync_shm_offset_ = shm_offset; |
| 3682 async_upload_sync_ = static_cast<AsyncUploadSync*>(mem); |
| 3683 async_upload_sync_->Reset(); |
| 3684 |
| 3685 return true; |
| 3686 } |
| 3687 |
| 3688 uint32 GLES2Implementation::NextAsyncUploadToken() { |
| 3689 async_upload_token_++; |
| 3690 if (async_upload_token_ == 0) |
| 3691 async_upload_token_++; |
| 3692 return async_upload_token_; |
| 3693 } |
| 3694 |
| 3695 void GLES2Implementation::PollAsyncUploads() { |
| 3696 if (!async_upload_sync_) |
| 3697 return; |
| 3698 |
| 3699 if (helper_->IsContextLost()) { |
| 3700 DetachedAsyncUploadMemoryList::iterator it = |
| 3701 detached_async_upload_memory_.begin(); |
| 3702 while (it != detached_async_upload_memory_.end()) { |
| 3703 mapped_memory_->Free(it->first); |
| 3704 it = detached_async_upload_memory_.erase(it); |
| 3705 } |
| 3706 return; |
| 3707 } |
| 3708 |
| 3709 DetachedAsyncUploadMemoryList::iterator it = |
| 3710 detached_async_upload_memory_.begin(); |
| 3711 while (it != detached_async_upload_memory_.end()) { |
| 3712 if (HasAsyncUploadTokenPassed(it->second)) { |
| 3713 mapped_memory_->Free(it->first); |
| 3714 it = detached_async_upload_memory_.erase(it); |
| 3715 } else { |
| 3716 break; |
| 3717 } |
| 3718 } |
| 3719 } |
| 3720 |
| 3721 void GLES2Implementation::FreeAllAsyncUploadBuffers() { |
| 3722 // Free all completed unmanaged async uploads buffers. |
| 3723 PollAsyncUploads(); |
| 3724 |
| 3725 // Synchronously free rest of the unmanaged async upload buffers. |
| 3726 if (!detached_async_upload_memory_.empty()) { |
| 3727 WaitAllAsyncTexImage2DCHROMIUM(); |
| 3728 WaitForCmd(); |
| 3729 PollAsyncUploads(); |
| 3730 } |
| 3731 } |
| 3732 |
3630 void GLES2Implementation::AsyncTexImage2DCHROMIUM( | 3733 void GLES2Implementation::AsyncTexImage2DCHROMIUM( |
3631 GLenum target, GLint level, GLint internalformat, GLsizei width, | 3734 GLenum target, GLint level, GLint internalformat, GLsizei width, |
3632 GLsizei height, GLint border, GLenum format, GLenum type, | 3735 GLsizei height, GLint border, GLenum format, GLenum type, |
3633 const void* pixels) { | 3736 const void* pixels) { |
3634 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3737 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
3635 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" | 3738 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" |
3636 << GLES2Util::GetStringTextureTarget(target) << ", " | 3739 << GLES2Util::GetStringTextureTarget(target) << ", " |
3637 << level << ", " | 3740 << level << ", " |
3638 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " | 3741 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " |
3639 << width << ", " << height << ", " << border << ", " | 3742 << width << ", " << height << ", " << border << ", " |
(...skipping 11 matching lines...) Expand all Loading... |
3651 width, height, format, type, unpack_alignment_, &size, | 3754 width, height, format, type, unpack_alignment_, &size, |
3652 &unpadded_row_size, &padded_row_size)) { | 3755 &unpadded_row_size, &padded_row_size)) { |
3653 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); | 3756 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
3654 return; | 3757 return; |
3655 } | 3758 } |
3656 | 3759 |
3657 // If there's no data/buffer just issue the AsyncTexImage2D | 3760 // If there's no data/buffer just issue the AsyncTexImage2D |
3658 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { | 3761 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { |
3659 helper_->AsyncTexImage2DCHROMIUM( | 3762 helper_->AsyncTexImage2DCHROMIUM( |
3660 target, level, internalformat, width, height, border, format, type, | 3763 target, level, internalformat, width, height, border, format, type, |
3661 0, 0); | 3764 0, 0, 0, 0, 0); |
3662 return; | 3765 return; |
3663 } | 3766 } |
3664 | 3767 |
| 3768 if (!EnsureAsyncUploadSync()) { |
| 3769 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory"); |
| 3770 return; |
| 3771 } |
| 3772 |
3665 // Otherwise, async uploads require a transfer buffer to be bound. | 3773 // Otherwise, async uploads require a transfer buffer to be bound. |
3666 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use | 3774 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use |
3667 // the buffer before the transfer is finished. (Currently such | 3775 // the buffer before the transfer is finished. (Currently such |
3668 // synchronization has to be handled manually.) | 3776 // synchronization has to be handled manually.) |
3669 GLuint offset = ToGLuint(pixels); | 3777 GLuint offset = ToGLuint(pixels); |
3670 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3778 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
3671 bound_pixel_unpack_transfer_buffer_id_, | 3779 bound_pixel_unpack_transfer_buffer_id_, |
3672 "glAsyncTexImage2DCHROMIUM", offset, size); | 3780 "glAsyncTexImage2DCHROMIUM", offset, size); |
3673 if (buffer && buffer->shm_id() != -1) { | 3781 if (buffer && buffer->shm_id() != -1) { |
| 3782 uint32 async_token = NextAsyncUploadToken(); |
| 3783 buffer->set_last_async_upload_token(async_token); |
3674 helper_->AsyncTexImage2DCHROMIUM( | 3784 helper_->AsyncTexImage2DCHROMIUM( |
3675 target, level, internalformat, width, height, border, format, type, | 3785 target, level, internalformat, width, height, border, format, type, |
3676 buffer->shm_id(), buffer->shm_offset() + offset); | 3786 buffer->shm_id(), buffer->shm_offset() + offset, |
| 3787 async_token, |
| 3788 async_upload_sync_shm_id_, async_upload_sync_shm_offset_); |
3677 } | 3789 } |
3678 } | 3790 } |
3679 | 3791 |
3680 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( | 3792 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( |
3681 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 3793 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
3682 GLsizei height, GLenum format, GLenum type, const void* pixels) { | 3794 GLsizei height, GLenum format, GLenum type, const void* pixels) { |
3683 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3795 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
3684 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" | 3796 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" |
3685 << GLES2Util::GetStringTextureTarget(target) << ", " | 3797 << GLES2Util::GetStringTextureTarget(target) << ", " |
3686 << level << ", " | 3798 << level << ", " |
(...skipping 12 matching lines...) Expand all Loading... |
3699 uint32 unpadded_row_size; | 3811 uint32 unpadded_row_size; |
3700 uint32 padded_row_size; | 3812 uint32 padded_row_size; |
3701 if (!GLES2Util::ComputeImageDataSizes( | 3813 if (!GLES2Util::ComputeImageDataSizes( |
3702 width, height, format, type, unpack_alignment_, &size, | 3814 width, height, format, type, unpack_alignment_, &size, |
3703 &unpadded_row_size, &padded_row_size)) { | 3815 &unpadded_row_size, &padded_row_size)) { |
3704 SetGLError( | 3816 SetGLError( |
3705 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); | 3817 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); |
3706 return; | 3818 return; |
3707 } | 3819 } |
3708 | 3820 |
| 3821 if (!EnsureAsyncUploadSync()) { |
| 3822 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory"); |
| 3823 return; |
| 3824 } |
| 3825 |
3709 // Async uploads require a transfer buffer to be bound. | 3826 // Async uploads require a transfer buffer to be bound. |
3710 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use | 3827 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use |
3711 // the buffer before the transfer is finished. (Currently such | 3828 // the buffer before the transfer is finished. (Currently such |
3712 // synchronization has to be handled manually.) | 3829 // synchronization has to be handled manually.) |
3713 GLuint offset = ToGLuint(pixels); | 3830 GLuint offset = ToGLuint(pixels); |
3714 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3831 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
3715 bound_pixel_unpack_transfer_buffer_id_, | 3832 bound_pixel_unpack_transfer_buffer_id_, |
3716 "glAsyncTexSubImage2DCHROMIUM", offset, size); | 3833 "glAsyncTexSubImage2DCHROMIUM", offset, size); |
3717 if (buffer && buffer->shm_id() != -1) { | 3834 if (buffer && buffer->shm_id() != -1) { |
| 3835 uint32 async_token = NextAsyncUploadToken(); |
| 3836 buffer->set_last_async_upload_token(async_token); |
3718 helper_->AsyncTexSubImage2DCHROMIUM( | 3837 helper_->AsyncTexSubImage2DCHROMIUM( |
3719 target, level, xoffset, yoffset, width, height, format, type, | 3838 target, level, xoffset, yoffset, width, height, format, type, |
3720 buffer->shm_id(), buffer->shm_offset() + offset); | 3839 buffer->shm_id(), buffer->shm_offset() + offset, |
| 3840 async_token, |
| 3841 async_upload_sync_shm_id_, async_upload_sync_shm_offset_); |
3721 } | 3842 } |
3722 } | 3843 } |
3723 | 3844 |
3724 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { | 3845 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { |
3725 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3846 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
3726 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM(" | 3847 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM(" |
3727 << GLES2Util::GetStringTextureTarget(target) << ")"); | 3848 << GLES2Util::GetStringTextureTarget(target) << ")"); |
3728 helper_->WaitAsyncTexImage2DCHROMIUM(target); | 3849 helper_->WaitAsyncTexImage2DCHROMIUM(target); |
3729 CheckGLError(); | 3850 CheckGLError(); |
3730 } | 3851 } |
3731 | 3852 |
| 3853 void GLES2Implementation::WaitAllAsyncTexImage2DCHROMIUM() { |
| 3854 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3855 GPU_CLIENT_LOG("[" << GetLogPrefix() |
| 3856 << "] glWaitAllAsyncTexImage2DCHROMIUM()"); |
| 3857 helper_->WaitAllAsyncTexImage2DCHROMIUM(); |
| 3858 CheckGLError(); |
| 3859 } |
| 3860 |
3732 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { | 3861 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { |
3733 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3862 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
3734 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM"); | 3863 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM"); |
3735 helper_->CommandBufferHelper::Flush(); | 3864 helper_->CommandBufferHelper::Flush(); |
3736 return gpu_control_->InsertSyncPoint(); | 3865 return gpu_control_->InsertSyncPoint(); |
3737 } | 3866 } |
3738 | 3867 |
3739 GLuint GLES2Implementation::CreateImageCHROMIUMHelper( | 3868 GLuint GLES2Implementation::CreateImageCHROMIUMHelper( |
3740 GLsizei width, GLsizei height, GLenum internalformat) { | 3869 GLsizei width, GLsizei height, GLenum internalformat) { |
3741 if (width <= 0) { | 3870 if (width <= 0) { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3897 CheckGLError(); | 4026 CheckGLError(); |
3898 } | 4027 } |
3899 | 4028 |
3900 // Include the auto-generated part of this file. We split this because it means | 4029 // Include the auto-generated part of this file. We split this because it means |
3901 // we can easily edit the non-auto generated parts right here in this file | 4030 // we can easily edit the non-auto generated parts right here in this file |
3902 // instead of having to edit some template or the code generator. | 4031 // instead of having to edit some template or the code generator. |
3903 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 4032 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
3904 | 4033 |
3905 } // namespace gles2 | 4034 } // namespace gles2 |
3906 } // namespace gpu | 4035 } // namespace gpu |
OLD | NEW |