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 |