Chromium Code Reviews| 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> |
| (...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1371 } | 1371 } |
| 1372 | 1372 |
| 1373 GLuint buffer_id; | 1373 GLuint buffer_id; |
| 1374 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { | 1374 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { |
| 1375 if (!buffer_id) { | 1375 if (!buffer_id) { |
| 1376 return; | 1376 return; |
| 1377 } | 1377 } |
| 1378 | 1378 |
| 1379 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | 1379 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 1380 if (buffer) { | 1380 if (buffer) { |
| 1381 // Free buffer memory, pending the passage of a token. | 1381 FreeTransferBuffer(buffer); |
|
piman
2014/01/16 21:22:50
How does synchronization work wrt asynchronous Rea
jadahl
2014/01/17 08:50:25
Hmm. Good point. Reading how readpixels is impleme
| |
| 1382 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | 1382 buffer_tracker_->RemoveBuffer(buffer->id()); |
| 1383 | |
| 1384 // Remove old buffer. | |
| 1385 buffer_tracker_->RemoveBuffer(buffer_id); | |
| 1386 } | 1383 } |
| 1387 | 1384 |
| 1388 // Create new buffer. | 1385 // Create new buffer. |
| 1389 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); | 1386 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); |
| 1390 DCHECK(buffer); | 1387 DCHECK(buffer); |
| 1391 if (buffer->address() && data) | 1388 if (buffer->address() && data) |
| 1392 memcpy(buffer->address(), data, size); | 1389 memcpy(buffer->address(), data, size); |
| 1393 return; | 1390 return; |
| 1394 } | 1391 } |
| 1395 | 1392 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1504 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1501 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
| 1505 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1502 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1506 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" | 1503 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" |
| 1507 << GLES2Util::GetStringBufferTarget(target) << ", " | 1504 << GLES2Util::GetStringBufferTarget(target) << ", " |
| 1508 << offset << ", " << size << ", " | 1505 << offset << ", " << size << ", " |
| 1509 << static_cast<const void*>(data) << ")"); | 1506 << static_cast<const void*>(data) << ")"); |
| 1510 BufferSubDataHelper(target, offset, size, data); | 1507 BufferSubDataHelper(target, offset, size, data); |
| 1511 CheckGLError(); | 1508 CheckGLError(); |
| 1512 } | 1509 } |
| 1513 | 1510 |
| 1511 void GLES2Implementation::FreeTransferBuffer(BufferTracker::Buffer* buffer) { | |
| 1512 int32 token = buffer->last_usage_token(); | |
| 1513 | |
| 1514 if (buffer->async_query_id()) { | |
| 1515 QueryTracker::Query* query = | |
| 1516 query_tracker_->GetQuery(buffer->async_query_id()); | |
| 1517 if (!query->CheckResultsAvailable(helper_)) | |
| 1518 buffer_tracker_->FreePendingSerial(buffer, query->serial()); | |
| 1519 else | |
| 1520 buffer_tracker_->Free(buffer); | |
| 1521 } else if (token) { | |
| 1522 if (helper_->HasTokenPassed(token)) | |
| 1523 buffer_tracker_->Free(buffer); | |
| 1524 else | |
| 1525 buffer_tracker_->FreePendingToken(buffer, token); | |
| 1526 } | |
| 1527 } | |
| 1528 | |
| 1514 bool GLES2Implementation::GetBoundPixelTransferBuffer( | 1529 bool GLES2Implementation::GetBoundPixelTransferBuffer( |
| 1515 GLenum target, | 1530 GLenum target, |
| 1516 const char* function_name, | 1531 const char* function_name, |
| 1517 GLuint* buffer_id) { | 1532 GLuint* buffer_id) { |
| 1518 *buffer_id = 0; | 1533 *buffer_id = 0; |
| 1519 | 1534 |
| 1520 switch (target) { | 1535 switch (target) { |
| 1521 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | 1536 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| 1522 *buffer_id = bound_pixel_pack_transfer_buffer_id_; | 1537 *buffer_id = bound_pixel_pack_transfer_buffer_id_; |
| 1523 break; | 1538 break; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1579 // CompressedTexImage2D. | 1594 // CompressedTexImage2D. |
| 1580 if (bound_pixel_unpack_transfer_buffer_id_) { | 1595 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1581 GLuint offset = ToGLuint(data); | 1596 GLuint offset = ToGLuint(data); |
| 1582 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1597 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1583 bound_pixel_unpack_transfer_buffer_id_, | 1598 bound_pixel_unpack_transfer_buffer_id_, |
| 1584 "glCompressedTexImage2D", offset, image_size); | 1599 "glCompressedTexImage2D", offset, image_size); |
| 1585 if (buffer && buffer->shm_id() != -1) { | 1600 if (buffer && buffer->shm_id() != -1) { |
| 1586 helper_->CompressedTexImage2D( | 1601 helper_->CompressedTexImage2D( |
| 1587 target, level, internalformat, width, height, border, image_size, | 1602 target, level, internalformat, width, height, border, image_size, |
| 1588 buffer->shm_id(), buffer->shm_offset() + offset); | 1603 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1589 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1604 MarkPixelTransferBufferLastUsage(buffer); |
| 1590 } | 1605 } |
| 1591 return; | 1606 return; |
| 1592 } | 1607 } |
| 1593 SetBucketContents(kResultBucketId, data, image_size); | 1608 SetBucketContents(kResultBucketId, data, image_size); |
| 1594 helper_->CompressedTexImage2DBucket( | 1609 helper_->CompressedTexImage2DBucket( |
| 1595 target, level, internalformat, width, height, border, kResultBucketId); | 1610 target, level, internalformat, width, height, border, kResultBucketId); |
| 1596 // Free the bucket. This is not required but it does free up the memory. | 1611 // Free the bucket. This is not required but it does free up the memory. |
| 1597 // and we don't have to wait for the result so from the client's perspective | 1612 // and we don't have to wait for the result so from the client's perspective |
| 1598 // it's cheap. | 1613 // it's cheap. |
| 1599 helper_->SetBucketSize(kResultBucketId, 0); | 1614 helper_->SetBucketSize(kResultBucketId, 0); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1620 // CompressedTexSubImage2D. | 1635 // CompressedTexSubImage2D. |
| 1621 if (bound_pixel_unpack_transfer_buffer_id_) { | 1636 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1622 GLuint offset = ToGLuint(data); | 1637 GLuint offset = ToGLuint(data); |
| 1623 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1638 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1624 bound_pixel_unpack_transfer_buffer_id_, | 1639 bound_pixel_unpack_transfer_buffer_id_, |
| 1625 "glCompressedTexSubImage2D", offset, image_size); | 1640 "glCompressedTexSubImage2D", offset, image_size); |
| 1626 if (buffer && buffer->shm_id() != -1) { | 1641 if (buffer && buffer->shm_id() != -1) { |
| 1627 helper_->CompressedTexSubImage2D( | 1642 helper_->CompressedTexSubImage2D( |
| 1628 target, level, xoffset, yoffset, width, height, format, image_size, | 1643 target, level, xoffset, yoffset, width, height, format, image_size, |
| 1629 buffer->shm_id(), buffer->shm_offset() + offset); | 1644 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1630 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1645 MarkPixelTransferBufferLastUsage(buffer); |
| 1631 CheckGLError(); | 1646 CheckGLError(); |
| 1632 } | 1647 } |
| 1633 return; | 1648 return; |
| 1634 } | 1649 } |
| 1635 SetBucketContents(kResultBucketId, data, image_size); | 1650 SetBucketContents(kResultBucketId, data, image_size); |
| 1636 helper_->CompressedTexSubImage2DBucket( | 1651 helper_->CompressedTexSubImage2DBucket( |
| 1637 target, level, xoffset, yoffset, width, height, format, kResultBucketId); | 1652 target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
| 1638 // Free the bucket. This is not required but it does free up the memory. | 1653 // Free the bucket. This is not required but it does free up the memory. |
| 1639 // and we don't have to wait for the result so from the client's perspective | 1654 // and we don't have to wait for the result so from the client's perspective |
| 1640 // it's cheap. | 1655 // it's cheap. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1707 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. | 1722 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
| 1708 if (bound_pixel_unpack_transfer_buffer_id_) { | 1723 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1709 GLuint offset = ToGLuint(pixels); | 1724 GLuint offset = ToGLuint(pixels); |
| 1710 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1725 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1711 bound_pixel_unpack_transfer_buffer_id_, | 1726 bound_pixel_unpack_transfer_buffer_id_, |
| 1712 "glTexImage2D", offset, size); | 1727 "glTexImage2D", offset, size); |
| 1713 if (buffer && buffer->shm_id() != -1) { | 1728 if (buffer && buffer->shm_id() != -1) { |
| 1714 helper_->TexImage2D( | 1729 helper_->TexImage2D( |
| 1715 target, level, internalformat, width, height, border, format, type, | 1730 target, level, internalformat, width, height, border, format, type, |
| 1716 buffer->shm_id(), buffer->shm_offset() + offset); | 1731 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1717 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1732 MarkPixelTransferBufferLastUsage(buffer); |
| 1718 CheckGLError(); | 1733 CheckGLError(); |
| 1719 } | 1734 } |
| 1720 return; | 1735 return; |
| 1721 } | 1736 } |
| 1722 | 1737 |
| 1723 // If there's no data just issue TexImage2D | 1738 // If there's no data just issue TexImage2D |
| 1724 if (!pixels) { | 1739 if (!pixels) { |
| 1725 helper_->TexImage2D( | 1740 helper_->TexImage2D( |
| 1726 target, level, internalformat, width, height, border, format, type, | 1741 target, level, internalformat, width, height, border, format, type, |
| 1727 0, 0); | 1742 0, 0); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1813 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | 1828 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
| 1814 if (bound_pixel_unpack_transfer_buffer_id_) { | 1829 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1815 GLuint offset = ToGLuint(pixels); | 1830 GLuint offset = ToGLuint(pixels); |
| 1816 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1831 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1817 bound_pixel_unpack_transfer_buffer_id_, | 1832 bound_pixel_unpack_transfer_buffer_id_, |
| 1818 "glTexSubImage2D", offset, temp_size); | 1833 "glTexSubImage2D", offset, temp_size); |
| 1819 if (buffer && buffer->shm_id() != -1) { | 1834 if (buffer && buffer->shm_id() != -1) { |
| 1820 helper_->TexSubImage2D( | 1835 helper_->TexSubImage2D( |
| 1821 target, level, xoffset, yoffset, width, height, format, type, | 1836 target, level, xoffset, yoffset, width, height, format, type, |
| 1822 buffer->shm_id(), buffer->shm_offset() + offset, false); | 1837 buffer->shm_id(), buffer->shm_offset() + offset, false); |
| 1823 buffer->set_transfer_ready_token(helper_->InsertToken()); | 1838 MarkPixelTransferBufferLastUsage(buffer); |
| 1824 CheckGLError(); | 1839 CheckGLError(); |
| 1825 } | 1840 } |
| 1826 return; | 1841 return; |
| 1827 } | 1842 } |
| 1828 | 1843 |
| 1829 // compute the advance bytes per row for the src pixels | 1844 // compute the advance bytes per row for the src pixels |
| 1830 uint32 src_padded_row_size; | 1845 uint32 src_padded_row_size; |
| 1831 if (unpack_row_length_ > 0) { | 1846 if (unpack_row_length_ > 0) { |
| 1832 if (!GLES2Util::ComputeImagePaddedRowSize( | 1847 if (!GLES2Util::ComputeImagePaddedRowSize( |
| 1833 unpack_row_length_, format, type, unpack_alignment_, | 1848 unpack_row_length_, format, type, unpack_alignment_, |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2396 } | 2411 } |
| 2397 | 2412 |
| 2398 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id | 2413 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id |
| 2399 // generates a new resource. On newer versions of OpenGL they don't. The code | 2414 // generates a new resource. On newer versions of OpenGL they don't. The code |
| 2400 // related to binding below will need to change if we switch to the new OpenGL | 2415 // related to binding below will need to change if we switch to the new OpenGL |
| 2401 // model. Specifically it assumes a bind will succeed which is always true in | 2416 // model. Specifically it assumes a bind will succeed which is always true in |
| 2402 // the old model but possibly not true in the new model if another context has | 2417 // the old model but possibly not true in the new model if another context has |
| 2403 // deleted the resource. | 2418 // deleted the resource. |
| 2404 | 2419 |
| 2405 bool GLES2Implementation::BindBufferHelper( | 2420 bool GLES2Implementation::BindBufferHelper( |
| 2406 GLenum target, GLuint buffer) { | 2421 GLenum target, GLuint buffer_id) { |
| 2407 // TODO(gman): See note #1 above. | 2422 // TODO(gman): See note #1 above. |
| 2408 bool changed = false; | 2423 bool changed = false; |
| 2409 switch (target) { | 2424 switch (target) { |
| 2410 case GL_ARRAY_BUFFER: | 2425 case GL_ARRAY_BUFFER: |
| 2411 if (bound_array_buffer_id_ != buffer) { | 2426 if (bound_array_buffer_id_ != buffer_id) { |
| 2412 bound_array_buffer_id_ = buffer; | 2427 bound_array_buffer_id_ = buffer_id; |
| 2413 changed = true; | 2428 changed = true; |
| 2414 } | 2429 } |
| 2415 break; | 2430 break; |
| 2416 case GL_ELEMENT_ARRAY_BUFFER: | 2431 case GL_ELEMENT_ARRAY_BUFFER: |
| 2417 changed = vertex_array_object_manager_->BindElementArray(buffer); | 2432 changed = vertex_array_object_manager_->BindElementArray(buffer_id); |
| 2418 break; | 2433 break; |
| 2419 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | 2434 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| 2420 bound_pixel_pack_transfer_buffer_id_ = buffer; | 2435 bound_pixel_pack_transfer_buffer_id_ = buffer_id; |
| 2421 break; | 2436 break; |
| 2422 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | 2437 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| 2423 bound_pixel_unpack_transfer_buffer_id_ = buffer; | 2438 bound_pixel_unpack_transfer_buffer_id_ = buffer_id; |
| 2424 break; | 2439 break; |
| 2425 default: | 2440 default: |
| 2426 changed = true; | 2441 changed = true; |
| 2427 break; | 2442 break; |
| 2428 } | 2443 } |
| 2429 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2444 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
| 2430 // used even though it's marked it as used here. | 2445 // used even though it's marked it as used here. |
| 2431 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2446 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer_id); |
| 2432 return changed; | 2447 return changed; |
| 2433 } | 2448 } |
| 2434 | 2449 |
| 2435 bool GLES2Implementation::BindFramebufferHelper( | 2450 bool GLES2Implementation::BindFramebufferHelper( |
| 2436 GLenum target, GLuint framebuffer) { | 2451 GLenum target, GLuint framebuffer) { |
| 2437 // TODO(gman): See note #1 above. | 2452 // TODO(gman): See note #1 above. |
| 2438 bool changed = false; | 2453 bool changed = false; |
| 2439 switch (target) { | 2454 switch (target) { |
| 2440 case GL_FRAMEBUFFER: | 2455 case GL_FRAMEBUFFER: |
| 2441 if (bound_framebuffer_ != framebuffer || | 2456 if (bound_framebuffer_ != framebuffer || |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2555 SetGLError( | 2570 SetGLError( |
| 2556 GL_INVALID_VALUE, | 2571 GL_INVALID_VALUE, |
| 2557 "glDeleteBuffers", "id not created by this context."); | 2572 "glDeleteBuffers", "id not created by this context."); |
| 2558 return; | 2573 return; |
| 2559 } | 2574 } |
| 2560 for (GLsizei ii = 0; ii < n; ++ii) { | 2575 for (GLsizei ii = 0; ii < n; ++ii) { |
| 2561 if (buffers[ii] == bound_array_buffer_id_) { | 2576 if (buffers[ii] == bound_array_buffer_id_) { |
| 2562 bound_array_buffer_id_ = 0; | 2577 bound_array_buffer_id_ = 0; |
| 2563 } | 2578 } |
| 2564 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); | 2579 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); |
| 2580 | |
| 2565 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); | 2581 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
| 2566 if (buffer) { | 2582 if (buffer) { |
| 2567 // Free buffer memory, pending the passage of a token. | 2583 FreeTransferBuffer(buffer); |
| 2568 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | 2584 buffer_tracker_->RemoveBuffer(buffer->id()); |
| 2569 // Remove buffer. | |
| 2570 buffer_tracker_->RemoveBuffer(buffers[ii]); | |
| 2571 } | 2585 } |
| 2586 | |
| 2572 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { | 2587 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
| 2573 bound_pixel_unpack_transfer_buffer_id_ = 0; | 2588 bound_pixel_unpack_transfer_buffer_id_ = 0; |
| 2574 } | 2589 } |
| 2575 } | 2590 } |
| 2576 } | 2591 } |
| 2577 | 2592 |
| 2578 void GLES2Implementation::DeleteBuffersStub( | 2593 void GLES2Implementation::DeleteBuffersStub( |
| 2579 GLsizei n, const GLuint* buffers) { | 2594 GLsizei n, const GLuint* buffers) { |
| 2580 helper_->DeleteBuffersImmediate(n, buffers); | 2595 helper_->DeleteBuffersImmediate(n, buffers); |
| 2581 } | 2596 } |
| (...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3281 // queries across contexts? | 3296 // queries across contexts? |
| 3282 return query_tracker_->GetQuery(id) != NULL; | 3297 return query_tracker_->GetQuery(id) != NULL; |
| 3283 } | 3298 } |
| 3284 | 3299 |
| 3285 void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) { | 3300 void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) { |
| 3286 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3301 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3287 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] BeginQueryEXT(" | 3302 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] BeginQueryEXT(" |
| 3288 << GLES2Util::GetStringQueryTarget(target) | 3303 << GLES2Util::GetStringQueryTarget(target) |
| 3289 << ", " << id << ")"); | 3304 << ", " << id << ")"); |
| 3290 | 3305 |
| 3306 QueryKey key = std::make_pair(target, false); | |
| 3307 | |
| 3291 // if any outstanding queries INV_OP | 3308 // if any outstanding queries INV_OP |
| 3292 QueryMap::iterator it = current_queries_.find(target); | 3309 QueryMap::iterator it = current_queries_.find(key); |
| 3293 if (it != current_queries_.end()) { | 3310 if (it != current_queries_.end()) { |
| 3294 SetGLError( | 3311 SetGLError( |
| 3295 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); | 3312 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); |
| 3296 return; | 3313 return; |
| 3297 } | 3314 } |
| 3298 | 3315 |
| 3299 // id = 0 INV_OP | 3316 // id = 0 INV_OP |
| 3300 if (id == 0) { | 3317 if (id == 0) { |
| 3301 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); | 3318 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); |
| 3302 return; | 3319 return; |
| 3303 } | 3320 } |
| 3304 | 3321 |
| 3305 // TODO(gman) if id not GENned INV_OPERATION | 3322 // TODO(gman) if id not GENned INV_OPERATION |
| 3306 | 3323 |
| 3307 // if id does not have an object | 3324 // if id does not have an object |
| 3308 QueryTracker::Query* query = query_tracker_->GetQuery(id); | 3325 QueryTracker::Query* query = query_tracker_->GetQuery(id); |
| 3309 if (!query) { | 3326 if (!query) { |
| 3310 query = query_tracker_->CreateQuery(id, target); | 3327 query = query_tracker_->CreateQuery(id, target); |
| 3311 if (!query) { | 3328 if (!query) { |
| 3312 MustBeContextLost(); | 3329 MustBeContextLost(); |
| 3313 return; | 3330 return; |
| 3314 } | 3331 } |
| 3315 } else if (query->target() != target) { | 3332 } else if (query->target() != target) { |
| 3316 SetGLError( | 3333 SetGLError( |
| 3317 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match"); | 3334 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match"); |
| 3318 return; | 3335 return; |
| 3319 } | 3336 } |
| 3320 | 3337 |
| 3321 current_queries_[target] = query; | 3338 current_queries_[key] = query; |
| 3322 | 3339 |
| 3323 query->Begin(this); | 3340 query->Begin(this); |
| 3324 CheckGLError(); | 3341 CheckGLError(); |
| 3325 } | 3342 } |
| 3326 | 3343 |
| 3327 void GLES2Implementation::EndQueryEXT(GLenum target) { | 3344 void GLES2Implementation::EndQueryEXT(GLenum target) { |
| 3328 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3345 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3329 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] EndQueryEXT(" | 3346 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] EndQueryEXT(" |
| 3330 << GLES2Util::GetStringQueryTarget(target) << ")"); | 3347 << GLES2Util::GetStringQueryTarget(target) << ")"); |
| 3331 // Don't do anything if the context is lost. | 3348 // Don't do anything if the context is lost. |
| 3332 if (helper_->IsContextLost()) { | 3349 if (helper_->IsContextLost()) { |
| 3333 return; | 3350 return; |
| 3334 } | 3351 } |
| 3335 | 3352 |
| 3336 QueryMap::iterator it = current_queries_.find(target); | 3353 QueryKey key = std::make_pair(target, false); |
| 3354 QueryMap::iterator it = current_queries_.find(key); | |
| 3337 if (it == current_queries_.end()) { | 3355 if (it == current_queries_.end()) { |
| 3338 SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "no active query"); | 3356 SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "no active query"); |
| 3339 return; | 3357 return; |
| 3340 } | 3358 } |
| 3341 | 3359 |
| 3342 QueryTracker::Query* query = it->second; | 3360 QueryTracker::Query* query = it->second; |
| 3343 query->End(this); | 3361 query->End(this); |
| 3344 current_queries_.erase(it); | 3362 current_queries_.erase(it); |
| 3345 CheckGLError(); | 3363 CheckGLError(); |
| 3346 } | 3364 } |
| 3347 | 3365 |
| 3348 void GLES2Implementation::GetQueryivEXT( | 3366 void GLES2Implementation::GetQueryivEXT( |
| 3349 GLenum target, GLenum pname, GLint* params) { | 3367 GLenum target, GLenum pname, GLint* params) { |
| 3350 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3368 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3351 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] GetQueryivEXT(" | 3369 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] GetQueryivEXT(" |
| 3352 << GLES2Util::GetStringQueryTarget(target) << ", " | 3370 << GLES2Util::GetStringQueryTarget(target) << ", " |
| 3353 << GLES2Util::GetStringQueryParameter(pname) << ", " | 3371 << GLES2Util::GetStringQueryParameter(pname) << ", " |
| 3354 << static_cast<const void*>(params) << ")"); | 3372 << static_cast<const void*>(params) << ")"); |
| 3355 | 3373 |
| 3356 if (pname != GL_CURRENT_QUERY_EXT) { | 3374 if (pname != GL_CURRENT_QUERY_EXT) { |
| 3357 SetGLErrorInvalidEnum("glGetQueryivEXT", pname, "pname"); | 3375 SetGLErrorInvalidEnum("glGetQueryivEXT", pname, "pname"); |
| 3358 return; | 3376 return; |
| 3359 } | 3377 } |
| 3360 QueryMap::iterator it = current_queries_.find(target); | 3378 QueryKey key = std::make_pair(target, false); |
| 3379 QueryMap::iterator it = current_queries_.find(key); | |
| 3361 if (it != current_queries_.end()) { | 3380 if (it != current_queries_.end()) { |
| 3362 QueryTracker::Query* query = it->second; | 3381 QueryTracker::Query* query = it->second; |
| 3363 *params = query->id(); | 3382 *params = query->id(); |
| 3364 } else { | 3383 } else { |
| 3365 *params = 0; | 3384 *params = 0; |
| 3366 } | 3385 } |
| 3367 GPU_CLIENT_LOG(" " << *params); | 3386 GPU_CLIENT_LOG(" " << *params); |
| 3368 CheckGLError(); | 3387 CheckGLError(); |
| 3369 } | 3388 } |
| 3370 | 3389 |
| 3371 void GLES2Implementation::GetQueryObjectuivEXT( | 3390 void GLES2Implementation::GetQueryObjectuivEXT( |
| 3372 GLuint id, GLenum pname, GLuint* params) { | 3391 GLuint id, GLenum pname, GLuint* params) { |
| 3373 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3392 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3374 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] GetQueryivEXT(" << id << ", " | 3393 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] GetQueryivEXT(" << id << ", " |
| 3375 << GLES2Util::GetStringQueryObjectParameter(pname) << ", " | 3394 << GLES2Util::GetStringQueryObjectParameter(pname) << ", " |
| 3376 << static_cast<const void*>(params) << ")"); | 3395 << static_cast<const void*>(params) << ")"); |
| 3377 | 3396 |
| 3378 QueryTracker::Query* query = query_tracker_->GetQuery(id); | 3397 QueryTracker::Query* query = query_tracker_->GetQuery(id); |
| 3379 if (!query) { | 3398 if (!query) { |
| 3380 SetGLError(GL_INVALID_OPERATION, "glQueryObjectuivEXT", "unknown query id"); | 3399 SetGLError(GL_INVALID_OPERATION, "glQueryObjectuivEXT", "unknown query id"); |
| 3381 return; | 3400 return; |
| 3382 } | 3401 } |
| 3383 | 3402 |
| 3384 QueryMap::iterator it = current_queries_.find(query->target()); | 3403 QueryKey key = std::make_pair(query->target(), false); |
| 3404 QueryMap::iterator it = current_queries_.find(key); | |
| 3385 if (it != current_queries_.end()) { | 3405 if (it != current_queries_.end()) { |
| 3386 SetGLError( | 3406 SetGLError( |
| 3387 GL_INVALID_OPERATION, | 3407 GL_INVALID_OPERATION, |
| 3388 "glQueryObjectuivEXT", "query active. Did you to call glEndQueryEXT?"); | 3408 "glQueryObjectuivEXT", "query active. Did you to call glEndQueryEXT?"); |
| 3389 return; | 3409 return; |
| 3390 } | 3410 } |
| 3391 | 3411 |
| 3392 if (query->NeverUsed()) { | 3412 if (query->NeverUsed()) { |
| 3393 SetGLError( | 3413 SetGLError( |
| 3394 GL_INVALID_OPERATION, | 3414 GL_INVALID_OPERATION, |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3604 } | 3624 } |
| 3605 if (buffer->mapped()) { | 3625 if (buffer->mapped()) { |
| 3606 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); | 3626 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); |
| 3607 return NULL; | 3627 return NULL; |
| 3608 } | 3628 } |
| 3609 // Here we wait for previous transfer operations to be finished. | 3629 // Here we wait for previous transfer operations to be finished. |
| 3610 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work | 3630 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work |
| 3611 // with this method of synchronization. Until this is fixed, | 3631 // with this method of synchronization. Until this is fixed, |
| 3612 // MapBufferCHROMIUM will not block even if the transfer is not ready | 3632 // MapBufferCHROMIUM will not block even if the transfer is not ready |
| 3613 // for these calls. | 3633 // for these calls. |
| 3614 if (buffer->transfer_ready_token()) { | 3634 if (buffer->last_usage_token()) { |
| 3615 helper_->WaitForToken(buffer->transfer_ready_token()); | 3635 helper_->WaitForToken(buffer->last_usage_token()); |
| 3616 buffer->set_transfer_ready_token(0); | 3636 buffer->set_last_usage_token(0); |
| 3617 } | 3637 } |
| 3618 buffer->set_mapped(true); | 3638 buffer->set_mapped(true); |
| 3619 | 3639 |
| 3620 GPU_CLIENT_LOG(" returned " << buffer->address()); | 3640 GPU_CLIENT_LOG(" returned " << buffer->address()); |
| 3621 CheckGLError(); | 3641 CheckGLError(); |
| 3622 return buffer->address(); | 3642 return buffer->address(); |
| 3623 } | 3643 } |
| 3624 | 3644 |
| 3625 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { | 3645 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
| 3626 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3646 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 3640 } | 3660 } |
| 3641 if (!buffer->mapped()) { | 3661 if (!buffer->mapped()) { |
| 3642 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); | 3662 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); |
| 3643 return false; | 3663 return false; |
| 3644 } | 3664 } |
| 3645 buffer->set_mapped(false); | 3665 buffer->set_mapped(false); |
| 3646 CheckGLError(); | 3666 CheckGLError(); |
| 3647 return true; | 3667 return true; |
| 3648 } | 3668 } |
| 3649 | 3669 |
| 3670 void GLES2Implementation::BeginInternalQueryAsyncPixelUnpackCompleted( | |
| 3671 BufferTracker::Buffer *buffer) { | |
| 3672 QueryKey key = std::make_pair(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, true); | |
| 3673 | |
| 3674 DCHECK(current_queries_.find(key) == current_queries_.end()); | |
| 3675 | |
| 3676 GLuint id; | |
| 3677 GetIdHandler(id_namespaces::kQueries)->MakeIds(this, 0, 1, &id); | |
| 3678 QueryTracker::Query* query = query_tracker_->CreateInternalQuery( | |
| 3679 id, GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM); | |
| 3680 if (!query) { | |
| 3681 MustBeContextLost(); | |
| 3682 return; | |
| 3683 } | |
| 3684 | |
| 3685 buffer->set_async_query_id(id); | |
| 3686 query->Begin(this); | |
| 3687 CheckGLError(); | |
| 3688 | |
| 3689 current_queries_[key] = query; | |
| 3690 } | |
| 3691 | |
| 3692 void GLES2Implementation::EndInternalQueryAsyncPixelUnpackCompleted() { | |
| 3693 QueryKey key = std::make_pair(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, true); | |
| 3694 | |
| 3695 DCHECK(current_queries_.find(key) != current_queries_.end()); | |
| 3696 | |
| 3697 QueryMap::iterator it = current_queries_.find(key); | |
| 3698 QueryTracker::Query* query = it->second; | |
| 3699 query->End(this); | |
| 3700 current_queries_.erase(it); | |
| 3701 CheckGLError(); | |
| 3702 } | |
| 3703 | |
| 3704 void GLES2Implementation::MarkPixelTransferBufferLastUsage( | |
| 3705 BufferTracker::Buffer* buffer) { | |
| 3706 buffer->set_last_usage_token(helper_->InsertToken()); | |
| 3707 } | |
| 3708 | |
| 3650 void GLES2Implementation::AsyncTexImage2DCHROMIUM( | 3709 void GLES2Implementation::AsyncTexImage2DCHROMIUM( |
| 3651 GLenum target, GLint level, GLint internalformat, GLsizei width, | 3710 GLenum target, GLint level, GLint internalformat, GLsizei width, |
| 3652 GLsizei height, GLint border, GLenum format, GLenum type, | 3711 GLsizei height, GLint border, GLenum format, GLenum type, |
| 3653 const void* pixels) { | 3712 const void* pixels) { |
| 3654 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3713 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3655 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" | 3714 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" |
| 3656 << GLES2Util::GetStringTextureTarget(target) << ", " | 3715 << GLES2Util::GetStringTextureTarget(target) << ", " |
| 3657 << level << ", " | 3716 << level << ", " |
| 3658 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " | 3717 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " |
| 3659 << width << ", " << height << ", " << border << ", " | 3718 << width << ", " << height << ", " << border << ", " |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 3684 | 3743 |
| 3685 // Otherwise, async uploads require a transfer buffer to be bound. | 3744 // Otherwise, async uploads require a transfer buffer to be bound. |
| 3686 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use | 3745 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use |
| 3687 // the buffer before the transfer is finished. (Currently such | 3746 // the buffer before the transfer is finished. (Currently such |
| 3688 // synchronization has to be handled manually.) | 3747 // synchronization has to be handled manually.) |
| 3689 GLuint offset = ToGLuint(pixels); | 3748 GLuint offset = ToGLuint(pixels); |
| 3690 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3749 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 3691 bound_pixel_unpack_transfer_buffer_id_, | 3750 bound_pixel_unpack_transfer_buffer_id_, |
| 3692 "glAsyncTexImage2DCHROMIUM", offset, size); | 3751 "glAsyncTexImage2DCHROMIUM", offset, size); |
| 3693 if (buffer && buffer->shm_id() != -1) { | 3752 if (buffer && buffer->shm_id() != -1) { |
| 3753 BeginInternalQueryAsyncPixelUnpackCompleted(buffer); | |
| 3694 helper_->AsyncTexImage2DCHROMIUM( | 3754 helper_->AsyncTexImage2DCHROMIUM( |
| 3695 target, level, internalformat, width, height, border, format, type, | 3755 target, level, internalformat, width, height, border, format, type, |
| 3696 buffer->shm_id(), buffer->shm_offset() + offset); | 3756 buffer->shm_id(), buffer->shm_offset() + offset); |
| 3757 EndInternalQueryAsyncPixelUnpackCompleted(); | |
| 3697 } | 3758 } |
| 3698 } | 3759 } |
| 3699 | 3760 |
| 3700 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( | 3761 void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( |
| 3701 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 3762 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
| 3702 GLsizei height, GLenum format, GLenum type, const void* pixels) { | 3763 GLsizei height, GLenum format, GLenum type, const void* pixels) { |
| 3703 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3764 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3704 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" | 3765 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" |
| 3705 << GLES2Util::GetStringTextureTarget(target) << ", " | 3766 << GLES2Util::GetStringTextureTarget(target) << ", " |
| 3706 << level << ", " | 3767 << level << ", " |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 3728 | 3789 |
| 3729 // Async uploads require a transfer buffer to be bound. | 3790 // Async uploads require a transfer buffer to be bound. |
| 3730 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use | 3791 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use |
| 3731 // the buffer before the transfer is finished. (Currently such | 3792 // the buffer before the transfer is finished. (Currently such |
| 3732 // synchronization has to be handled manually.) | 3793 // synchronization has to be handled manually.) |
| 3733 GLuint offset = ToGLuint(pixels); | 3794 GLuint offset = ToGLuint(pixels); |
| 3734 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3795 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 3735 bound_pixel_unpack_transfer_buffer_id_, | 3796 bound_pixel_unpack_transfer_buffer_id_, |
| 3736 "glAsyncTexSubImage2DCHROMIUM", offset, size); | 3797 "glAsyncTexSubImage2DCHROMIUM", offset, size); |
| 3737 if (buffer && buffer->shm_id() != -1) { | 3798 if (buffer && buffer->shm_id() != -1) { |
| 3799 BeginInternalQueryAsyncPixelUnpackCompleted(buffer); | |
| 3738 helper_->AsyncTexSubImage2DCHROMIUM( | 3800 helper_->AsyncTexSubImage2DCHROMIUM( |
| 3739 target, level, xoffset, yoffset, width, height, format, type, | 3801 target, level, xoffset, yoffset, width, height, format, type, |
| 3740 buffer->shm_id(), buffer->shm_offset() + offset); | 3802 buffer->shm_id(), buffer->shm_offset() + offset); |
| 3803 EndInternalQueryAsyncPixelUnpackCompleted(); | |
| 3741 } | 3804 } |
| 3742 } | 3805 } |
| 3743 | 3806 |
| 3744 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { | 3807 void GLES2Implementation::WaitAsyncTexImage2DCHROMIUM(GLenum target) { |
| 3745 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3808 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3746 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM(" | 3809 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitAsyncTexImage2DCHROMIUM(" |
| 3747 << GLES2Util::GetStringTextureTarget(target) << ")"); | 3810 << GLES2Util::GetStringTextureTarget(target) << ")"); |
| 3748 helper_->WaitAsyncTexImage2DCHROMIUM(target); | 3811 helper_->WaitAsyncTexImage2DCHROMIUM(target); |
| 3749 CheckGLError(); | 3812 CheckGLError(); |
| 3750 } | 3813 } |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3917 CheckGLError(); | 3980 CheckGLError(); |
| 3918 } | 3981 } |
| 3919 | 3982 |
| 3920 // Include the auto-generated part of this file. We split this because it means | 3983 // Include the auto-generated part of this file. We split this because it means |
| 3921 // we can easily edit the non-auto generated parts right here in this file | 3984 // we can easily edit the non-auto generated parts right here in this file |
| 3922 // instead of having to edit some template or the code generator. | 3985 // instead of having to edit some template or the code generator. |
| 3923 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 3986 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
| 3924 | 3987 |
| 3925 } // namespace gles2 | 3988 } // namespace gles2 |
| 3926 } // namespace gpu | 3989 } // namespace gpu |
| OLD | NEW |