| 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 "../client/gles2_implementation.h" | 7 #include "../client/gles2_implementation.h" |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 ShareGroup* share_group, | 382 ShareGroup* share_group, |
| 383 TransferBufferInterface* transfer_buffer, | 383 TransferBufferInterface* transfer_buffer, |
| 384 bool share_resources, | 384 bool share_resources, |
| 385 bool bind_generates_resource) | 385 bool bind_generates_resource) |
| 386 : helper_(helper), | 386 : helper_(helper), |
| 387 transfer_buffer_(transfer_buffer), | 387 transfer_buffer_(transfer_buffer), |
| 388 angle_pack_reverse_row_order_status(kUnknownExtensionStatus), | 388 angle_pack_reverse_row_order_status(kUnknownExtensionStatus), |
| 389 pack_alignment_(4), | 389 pack_alignment_(4), |
| 390 unpack_alignment_(4), | 390 unpack_alignment_(4), |
| 391 unpack_flip_y_(false), | 391 unpack_flip_y_(false), |
| 392 unpack_row_length_(0), |
| 393 unpack_skip_rows_(0), |
| 394 unpack_skip_pixels_(0), |
| 392 pack_reverse_row_order_(false), | 395 pack_reverse_row_order_(false), |
| 393 active_texture_unit_(0), | 396 active_texture_unit_(0), |
| 394 bound_framebuffer_(0), | 397 bound_framebuffer_(0), |
| 395 bound_renderbuffer_(0), | 398 bound_renderbuffer_(0), |
| 396 bound_array_buffer_id_(0), | 399 bound_array_buffer_id_(0), |
| 397 bound_element_array_buffer_id_(0), | 400 bound_element_array_buffer_id_(0), |
| 398 client_side_array_id_(0), | 401 client_side_array_id_(0), |
| 399 client_side_element_array_id_(0), | 402 client_side_element_array_id_(0), |
| 400 error_bits_(0), | 403 error_bits_(0), |
| 401 debug_(false), | 404 debug_(false), |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1222 GPU_CLIENT_LOG("[" << this << "] glPixelStorei(" | 1225 GPU_CLIENT_LOG("[" << this << "] glPixelStorei(" |
| 1223 << GLES2Util::GetStringPixelStore(pname) << ", " | 1226 << GLES2Util::GetStringPixelStore(pname) << ", " |
| 1224 << param << ")"); | 1227 << param << ")"); |
| 1225 switch (pname) { | 1228 switch (pname) { |
| 1226 case GL_PACK_ALIGNMENT: | 1229 case GL_PACK_ALIGNMENT: |
| 1227 pack_alignment_ = param; | 1230 pack_alignment_ = param; |
| 1228 break; | 1231 break; |
| 1229 case GL_UNPACK_ALIGNMENT: | 1232 case GL_UNPACK_ALIGNMENT: |
| 1230 unpack_alignment_ = param; | 1233 unpack_alignment_ = param; |
| 1231 break; | 1234 break; |
| 1235 case GL_UNPACK_ROW_LENGTH: |
| 1236 unpack_row_length_ = param; |
| 1237 return; |
| 1238 case GL_UNPACK_SKIP_ROWS: |
| 1239 unpack_skip_rows_ = param; |
| 1240 return; |
| 1241 case GL_UNPACK_SKIP_PIXELS: |
| 1242 unpack_skip_pixels_ = param; |
| 1243 return; |
| 1232 case GL_UNPACK_FLIP_Y_CHROMIUM: | 1244 case GL_UNPACK_FLIP_Y_CHROMIUM: |
| 1233 unpack_flip_y_ = (param != 0); | 1245 unpack_flip_y_ = (param != 0); |
| 1234 return; | 1246 return; |
| 1235 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: | 1247 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: |
| 1236 pack_reverse_row_order_ = | 1248 pack_reverse_row_order_ = |
| 1237 IsAnglePackReverseRowOrderAvailable() ? (param != 0) : false; | 1249 IsAnglePackReverseRowOrderAvailable() ? (param != 0) : false; |
| 1238 break; | 1250 break; |
| 1239 default: | 1251 default: |
| 1240 break; | 1252 break; |
| 1241 } | 1253 } |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1494 } | 1506 } |
| 1495 SetBucketContents(kResultBucketId, data, image_size); | 1507 SetBucketContents(kResultBucketId, data, image_size); |
| 1496 helper_->CompressedTexSubImage2DBucket( | 1508 helper_->CompressedTexSubImage2DBucket( |
| 1497 target, level, xoffset, yoffset, width, height, format, kResultBucketId); | 1509 target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
| 1498 // Free the bucket. This is not required but it does free up the memory. | 1510 // Free the bucket. This is not required but it does free up the memory. |
| 1499 // and we don't have to wait for the result so from the client's perspective | 1511 // and we don't have to wait for the result so from the client's perspective |
| 1500 // it's cheap. | 1512 // it's cheap. |
| 1501 helper_->SetBucketSize(kResultBucketId, 0); | 1513 helper_->SetBucketSize(kResultBucketId, 0); |
| 1502 } | 1514 } |
| 1503 | 1515 |
| 1504 bool GLES2Implementation::CopyRectToBufferFlipped( | 1516 namespace { |
| 1517 |
| 1518 void CopyRectToBuffer( |
| 1505 const void* pixels, | 1519 const void* pixels, |
| 1506 GLsizei width, | 1520 uint32 height, |
| 1507 GLsizei height, | 1521 uint32 unpadded_row_size, |
| 1508 GLenum format, | 1522 uint32 pixels_padded_row_size, |
| 1509 GLenum type, | 1523 bool flip_y, |
| 1510 void* buffer) { | 1524 void* buffer, |
| 1511 if (width == 0 || height == 0) { | 1525 uint32 buffer_padded_row_size) { |
| 1512 return true; | 1526 const int8* source = static_cast<const int8*>(pixels); |
| 1527 int8* dest = static_cast<int8*>(buffer); |
| 1528 if (flip_y || pixels_padded_row_size != buffer_padded_row_size) { |
| 1529 if (flip_y) { |
| 1530 dest += buffer_padded_row_size * (height - 1); |
| 1531 } |
| 1532 // the last row is copied unpadded at the end |
| 1533 for (; height > 1; --height) { |
| 1534 memcpy(dest, source, buffer_padded_row_size); |
| 1535 if (flip_y) { |
| 1536 dest -= buffer_padded_row_size; |
| 1537 } else { |
| 1538 dest += buffer_padded_row_size; |
| 1539 } |
| 1540 source += pixels_padded_row_size; |
| 1541 } |
| 1542 memcpy(dest, source, unpadded_row_size); |
| 1543 } else { |
| 1544 uint32 size = (height - 1) * pixels_padded_row_size + unpadded_row_size; |
| 1545 memcpy(dest, source, size); |
| 1513 } | 1546 } |
| 1547 } |
| 1514 | 1548 |
| 1515 uint32 temp_size; | 1549 } // anonymous namespace |
| 1516 if (!GLES2Util::ComputeImageDataSize( | |
| 1517 width, 1, format, type, unpack_alignment_, &temp_size)) { | |
| 1518 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); | |
| 1519 return false; | |
| 1520 } | |
| 1521 GLsizeiptr unpadded_row_size = temp_size; | |
| 1522 if (!GLES2Util::ComputeImageDataSize( | |
| 1523 width, 2, format, type, unpack_alignment_, &temp_size)) { | |
| 1524 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); | |
| 1525 return false; | |
| 1526 } | |
| 1527 GLsizeiptr padded_row_size = temp_size - unpadded_row_size; | |
| 1528 if (padded_row_size < 0 || unpadded_row_size < 0) { | |
| 1529 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); | |
| 1530 return false; | |
| 1531 } | |
| 1532 | |
| 1533 const int8* source = static_cast<const int8*>(pixels); | |
| 1534 int8* dest = static_cast<int8*>(buffer) + padded_row_size * (height - 1); | |
| 1535 for (; height; --height) { | |
| 1536 memcpy(dest, source, unpadded_row_size); | |
| 1537 dest -= padded_row_size; | |
| 1538 source += padded_row_size; | |
| 1539 } | |
| 1540 return true; | |
| 1541 } | |
| 1542 | 1550 |
| 1543 void GLES2Implementation::TexImage2D( | 1551 void GLES2Implementation::TexImage2D( |
| 1544 GLenum target, GLint level, GLint internalformat, GLsizei width, | 1552 GLenum target, GLint level, GLint internalformat, GLsizei width, |
| 1545 GLsizei height, GLint border, GLenum format, GLenum type, | 1553 GLsizei height, GLint border, GLenum format, GLenum type, |
| 1546 const void* pixels) { | 1554 const void* pixels) { |
| 1547 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1555 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1548 GPU_CLIENT_LOG("[" << this << "] glTexImage2D(" | 1556 GPU_CLIENT_LOG("[" << this << "] glTexImage2D(" |
| 1549 << GLES2Util::GetStringTextureTarget(target) << ", " | 1557 << GLES2Util::GetStringTextureTarget(target) << ", " |
| 1550 << level << ", " | 1558 << level << ", " |
| 1551 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " | 1559 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " |
| 1552 << width << ", " << height << ", " << border << ", " | 1560 << width << ", " << height << ", " << border << ", " |
| 1553 << GLES2Util::GetStringTextureFormat(format) << ", " | 1561 << GLES2Util::GetStringTextureFormat(format) << ", " |
| 1554 << GLES2Util::GetStringPixelType(type) << ", " | 1562 << GLES2Util::GetStringPixelType(type) << ", " |
| 1555 << static_cast<const void*>(pixels) << ")"); | 1563 << static_cast<const void*>(pixels) << ")"); |
| 1556 if (level < 0 || height < 0 || width < 0) { | 1564 if (level < 0 || height < 0 || width < 0) { |
| 1557 SetGLError(GL_INVALID_VALUE, "glTexImage2D dimension < 0"); | 1565 SetGLError(GL_INVALID_VALUE, "glTexImage2D dimension < 0"); |
| 1558 return; | 1566 return; |
| 1559 } | 1567 } |
| 1560 uint32 size; | 1568 uint32 size; |
| 1561 if (!GLES2Util::ComputeImageDataSize( | 1569 uint32 unpadded_row_size; |
| 1562 width, height, format, type, unpack_alignment_, &size)) { | 1570 uint32 padded_row_size; |
| 1571 if (!GLES2Util::ComputeImageDataSizes( |
| 1572 width, height, format, type, unpack_alignment_, &size, |
| 1573 &unpadded_row_size, &padded_row_size)) { |
| 1563 SetGLError(GL_INVALID_VALUE, "glTexImage2D: image size too large"); | 1574 SetGLError(GL_INVALID_VALUE, "glTexImage2D: image size too large"); |
| 1564 return; | 1575 return; |
| 1565 } | 1576 } |
| 1566 | 1577 |
| 1567 // If there's no data just issue TexImage2D | 1578 // If there's no data just issue TexImage2D |
| 1568 if (!pixels) { | 1579 if (!pixels) { |
| 1569 helper_->TexImage2D( | 1580 helper_->TexImage2D( |
| 1570 target, level, internalformat, width, height, border, format, type, | 1581 target, level, internalformat, width, height, border, format, type, |
| 1571 0, 0); | 1582 0, 0); |
| 1572 return; | 1583 return; |
| 1573 } | 1584 } |
| 1574 | 1585 |
| 1586 // compute the advance bytes per row for the src pixels |
| 1587 uint32 src_padded_row_size; |
| 1588 if (unpack_row_length_ > 0) { |
| 1589 if (!GLES2Util::ComputeImagePaddedRowSize( |
| 1590 unpack_row_length_, format, type, unpack_alignment_, |
| 1591 &src_padded_row_size)) { |
| 1592 SetGLError(GL_INVALID_VALUE, "glTexImage2D: unpack row length too large"); |
| 1593 return; |
| 1594 } |
| 1595 } else { |
| 1596 src_padded_row_size = padded_row_size; |
| 1597 } |
| 1598 |
| 1599 // advance pixels pointer past the skip rows and skip pixels |
| 1600 pixels = reinterpret_cast<const int8*>(pixels) + |
| 1601 unpack_skip_rows_ * src_padded_row_size; |
| 1602 if (unpack_skip_pixels_) { |
| 1603 uint32 group_size = GLES2Util::ComputeImageGroupSize(format, type); |
| 1604 pixels = reinterpret_cast<const int8*>(pixels) + |
| 1605 unpack_skip_pixels_ * group_size; |
| 1606 } |
| 1607 |
| 1575 // Check if we can send it all at once. | 1608 // Check if we can send it all at once. |
| 1576 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); | 1609 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
| 1577 if (!buffer.valid()) { | 1610 if (!buffer.valid()) { |
| 1578 return; | 1611 return; |
| 1579 } | 1612 } |
| 1580 | 1613 |
| 1581 if (buffer.size() >= size) { | 1614 if (buffer.size() >= size) { |
| 1582 bool copy_success = true; | 1615 CopyRectToBuffer( |
| 1583 if (unpack_flip_y_) { | 1616 pixels, height, unpadded_row_size, src_padded_row_size, unpack_flip_y_, |
| 1584 copy_success = CopyRectToBufferFlipped( | 1617 buffer.address(), padded_row_size); |
| 1585 pixels, width, height, format, type, buffer.address()); | 1618 helper_->TexImage2D( |
| 1586 } else { | 1619 target, level, internalformat, width, height, border, format, type, |
| 1587 memcpy(buffer.address(), pixels, size); | 1620 buffer.shm_id(), buffer.offset()); |
| 1588 } | |
| 1589 | |
| 1590 if (copy_success) { | |
| 1591 helper_->TexImage2D( | |
| 1592 target, level, internalformat, width, height, border, format, type, | |
| 1593 buffer.shm_id(), buffer.offset()); | |
| 1594 } | |
| 1595 return; | 1621 return; |
| 1596 } | 1622 } |
| 1597 | 1623 |
| 1598 // No, so send it using TexSubImage2D. | 1624 // No, so send it using TexSubImage2D. |
| 1599 helper_->TexImage2D( | 1625 helper_->TexImage2D( |
| 1600 target, level, internalformat, width, height, border, format, type, | 1626 target, level, internalformat, width, height, border, format, type, |
| 1601 0, 0); | 1627 0, 0); |
| 1602 TexSubImage2DImpl( | 1628 TexSubImage2DImpl( |
| 1603 target, level, 0, 0, width, height, format, type, pixels, GL_TRUE, | 1629 target, level, 0, 0, width, height, format, type, unpadded_row_size, |
| 1604 &buffer); | 1630 pixels, src_padded_row_size, GL_TRUE, &buffer, padded_row_size); |
| 1605 } | 1631 } |
| 1606 | 1632 |
| 1607 void GLES2Implementation::TexSubImage2D( | 1633 void GLES2Implementation::TexSubImage2D( |
| 1608 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 1634 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
| 1609 GLsizei height, GLenum format, GLenum type, const void* pixels) { | 1635 GLsizei height, GLenum format, GLenum type, const void* pixels) { |
| 1610 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1636 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1611 GPU_CLIENT_LOG("[" << this << "] glTexSubImage2D(" | 1637 GPU_CLIENT_LOG("[" << this << "] glTexSubImage2D(" |
| 1612 << GLES2Util::GetStringTextureTarget(target) << ", " | 1638 << GLES2Util::GetStringTextureTarget(target) << ", " |
| 1613 << level << ", " | 1639 << level << ", " |
| 1614 << xoffset << ", " << yoffset << ", " | 1640 << xoffset << ", " << yoffset << ", " |
| 1615 << width << ", " << height << ", " | 1641 << width << ", " << height << ", " |
| 1616 << GLES2Util::GetStringTextureFormat(format) << ", " | 1642 << GLES2Util::GetStringTextureFormat(format) << ", " |
| 1617 << GLES2Util::GetStringPixelType(type) << ", " | 1643 << GLES2Util::GetStringPixelType(type) << ", " |
| 1618 << static_cast<const void*>(pixels) << ")"); | 1644 << static_cast<const void*>(pixels) << ")"); |
| 1619 | 1645 |
| 1620 if (level < 0 || height < 0 || width < 0) { | 1646 if (level < 0 || height < 0 || width < 0) { |
| 1621 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D dimension < 0"); | 1647 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D dimension < 0"); |
| 1622 return; | 1648 return; |
| 1623 } | 1649 } |
| 1624 if (height == 0 || width == 0) { | 1650 if (height == 0 || width == 0) { |
| 1625 return; | 1651 return; |
| 1626 } | 1652 } |
| 1627 | 1653 |
| 1628 uint32 temp_size; | 1654 uint32 temp_size; |
| 1629 if (!GLES2Util::ComputeImageDataSize( | 1655 uint32 unpadded_row_size; |
| 1630 width, height, format, type, unpack_alignment_, &temp_size)) { | 1656 uint32 padded_row_size; |
| 1657 if (!GLES2Util::ComputeImageDataSizes( |
| 1658 width, height, format, type, unpack_alignment_, &temp_size, |
| 1659 &unpadded_row_size, &padded_row_size)) { |
| 1631 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); | 1660 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); |
| 1632 return; | 1661 return; |
| 1633 } | 1662 } |
| 1634 | 1663 |
| 1664 // compute the advance bytes per row for the src pixels |
| 1665 uint32 src_padded_row_size; |
| 1666 if (unpack_row_length_ > 0) { |
| 1667 if (!GLES2Util::ComputeImagePaddedRowSize( |
| 1668 unpack_row_length_, format, type, unpack_alignment_, |
| 1669 &src_padded_row_size)) { |
| 1670 SetGLError(GL_INVALID_VALUE, "glTexImage2D: unpack row length too large"); |
| 1671 return; |
| 1672 } |
| 1673 } else { |
| 1674 src_padded_row_size = padded_row_size; |
| 1675 } |
| 1676 |
| 1677 // advance pixels pointer past the skip rows and skip pixels |
| 1678 pixels = reinterpret_cast<const int8*>(pixels) + |
| 1679 unpack_skip_rows_ * src_padded_row_size; |
| 1680 if (unpack_skip_pixels_) { |
| 1681 uint32 group_size = GLES2Util::ComputeImageGroupSize(format, type); |
| 1682 pixels = reinterpret_cast<const int8*>(pixels) + |
| 1683 unpack_skip_pixels_ * group_size; |
| 1684 } |
| 1685 |
| 1635 ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_); | 1686 ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_); |
| 1636 TexSubImage2DImpl( | 1687 TexSubImage2DImpl( |
| 1637 target, level, xoffset, yoffset, width, height, format, type, pixels, | 1688 target, level, xoffset, yoffset, width, height, format, type, |
| 1638 GL_FALSE, &buffer); | 1689 unpadded_row_size, pixels, src_padded_row_size, GL_FALSE, &buffer, |
| 1690 padded_row_size); |
| 1639 } | 1691 } |
| 1640 | 1692 |
| 1641 static GLint ComputeNumRowsThatFitInBuffer( | 1693 static GLint ComputeNumRowsThatFitInBuffer( |
| 1642 GLsizeiptr padded_row_size, GLsizeiptr unpadded_row_size, | 1694 GLsizeiptr padded_row_size, GLsizeiptr unpadded_row_size, |
| 1643 unsigned int size) { | 1695 unsigned int size) { |
| 1644 GPU_DCHECK_GE(unpadded_row_size, 0); | 1696 GPU_DCHECK_GE(unpadded_row_size, 0); |
| 1645 if (padded_row_size == 0) { | 1697 if (padded_row_size == 0) { |
| 1646 return 1; | 1698 return 1; |
| 1647 } | 1699 } |
| 1648 GLint num_rows = size / padded_row_size; | 1700 GLint num_rows = size / padded_row_size; |
| 1649 return num_rows + (size - num_rows * padded_row_size) / unpadded_row_size; | 1701 return num_rows + (size - num_rows * padded_row_size) / unpadded_row_size; |
| 1650 } | 1702 } |
| 1651 | 1703 |
| 1652 void GLES2Implementation::TexSubImage2DImpl( | 1704 void GLES2Implementation::TexSubImage2DImpl( |
| 1653 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 1705 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
| 1654 GLsizei height, GLenum format, GLenum type, const void* pixels, | 1706 GLsizei height, GLenum format, GLenum type, uint32 unpadded_row_size, |
| 1655 GLboolean internal, ScopedTransferBufferPtr* buffer) { | 1707 const void* pixels, uint32 pixels_padded_row_size, GLboolean internal, |
| 1708 ScopedTransferBufferPtr* buffer, uint32 buffer_padded_row_size) { |
| 1656 GPU_DCHECK(buffer); | 1709 GPU_DCHECK(buffer); |
| 1657 GPU_DCHECK_GE(level, 0); | 1710 GPU_DCHECK_GE(level, 0); |
| 1658 GPU_DCHECK_GT(height, 0); | 1711 GPU_DCHECK_GT(height, 0); |
| 1659 GPU_DCHECK_GT(width, 0); | 1712 GPU_DCHECK_GT(width, 0); |
| 1660 | 1713 |
| 1661 const int8* source = static_cast<const int8*>(pixels); | 1714 const int8* source = reinterpret_cast<const int8*>(pixels); |
| 1662 uint32 temp_size; | |
| 1663 if (!GLES2Util::ComputeImageDataSize( | |
| 1664 width, 1, format, type, unpack_alignment_, &temp_size)) { | |
| 1665 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); | |
| 1666 return; | |
| 1667 } | |
| 1668 GLsizeiptr unpadded_row_size = temp_size; | |
| 1669 if (!GLES2Util::ComputeImageDataSize( | |
| 1670 width, 2, format, type, unpack_alignment_, &temp_size)) { | |
| 1671 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); | |
| 1672 return; | |
| 1673 } | |
| 1674 GLsizeiptr padded_row_size = temp_size - unpadded_row_size; | |
| 1675 if (padded_row_size < 0 || unpadded_row_size < 0) { | |
| 1676 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); | |
| 1677 return; | |
| 1678 } | |
| 1679 | |
| 1680 GLint original_yoffset = yoffset; | 1715 GLint original_yoffset = yoffset; |
| 1681 // Transfer by rows. | 1716 // Transfer by rows. |
| 1682 while (height) { | 1717 while (height) { |
| 1683 unsigned int desired_size = | 1718 unsigned int desired_size = |
| 1684 padded_row_size * (height - 1) + unpadded_row_size; | 1719 buffer_padded_row_size * (height - 1) + unpadded_row_size; |
| 1685 if (!buffer->valid() || buffer->size() == 0) { | 1720 if (!buffer->valid() || buffer->size() == 0) { |
| 1686 buffer->Reset(desired_size); | 1721 buffer->Reset(desired_size); |
| 1687 if (!buffer->valid()) { | 1722 if (!buffer->valid()) { |
| 1688 return; | 1723 return; |
| 1689 } | 1724 } |
| 1690 } | 1725 } |
| 1691 | 1726 |
| 1692 GLint num_rows = ComputeNumRowsThatFitInBuffer( | 1727 GLint num_rows = ComputeNumRowsThatFitInBuffer( |
| 1693 padded_row_size, unpadded_row_size, buffer->size()); | 1728 buffer_padded_row_size, unpadded_row_size, buffer->size()); |
| 1694 num_rows = std::min(num_rows, height); | 1729 num_rows = std::min(num_rows, height); |
| 1695 GLint y; | 1730 CopyRectToBuffer( |
| 1696 if (unpack_flip_y_) { | 1731 source, num_rows, unpadded_row_size, pixels_padded_row_size, |
| 1697 CopyRectToBufferFlipped( | 1732 unpack_flip_y_, buffer->address(), buffer_padded_row_size); |
| 1698 source, width, num_rows, format, type, buffer->address()); | 1733 GLint y = unpack_flip_y_ ? original_yoffset + height - num_rows : yoffset; |
| 1699 y = original_yoffset + height - num_rows; | |
| 1700 } else { | |
| 1701 temp_size = padded_row_size * (num_rows - 1) + unpadded_row_size; | |
| 1702 memcpy(buffer->address(), source, temp_size); | |
| 1703 y = yoffset; | |
| 1704 } | |
| 1705 helper_->TexSubImage2D( | 1734 helper_->TexSubImage2D( |
| 1706 target, level, xoffset, y, width, num_rows, format, type, | 1735 target, level, xoffset, y, width, num_rows, format, type, |
| 1707 buffer->shm_id(), buffer->offset(), internal); | 1736 buffer->shm_id(), buffer->offset(), internal); |
| 1708 buffer->Release(); | 1737 buffer->Release(); |
| 1709 yoffset += num_rows; | 1738 yoffset += num_rows; |
| 1710 source += num_rows * padded_row_size; | 1739 source += num_rows * pixels_padded_row_size; |
| 1711 height -= num_rows; | 1740 height -= num_rows; |
| 1712 } | 1741 } |
| 1713 } | 1742 } |
| 1714 | 1743 |
| 1715 bool GLES2Implementation::GetActiveAttribHelper( | 1744 bool GLES2Implementation::GetActiveAttribHelper( |
| 1716 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, | 1745 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, |
| 1717 GLenum* type, char* name) { | 1746 GLenum* type, char* name) { |
| 1718 // Clear the bucket so if the command fails nothing will be in it. | 1747 // Clear the bucket so if the command fails nothing will be in it. |
| 1719 helper_->SetBucketSize(kResultBucketId, 0); | 1748 helper_->SetBucketSize(kResultBucketId, 0); |
| 1720 typedef gles2::GetActiveAttrib::Result Result; | 1749 typedef gles2::GetActiveAttrib::Result Result; |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1927 // Clears the bucket so if the command fails nothing will be in it. | 1956 // Clears the bucket so if the command fails nothing will be in it. |
| 1928 helper_->SetBucketSize(kResultBucketId, 0); | 1957 helper_->SetBucketSize(kResultBucketId, 0); |
| 1929 helper_->GetString(name, kResultBucketId); | 1958 helper_->GetString(name, kResultBucketId); |
| 1930 std::string str; | 1959 std::string str; |
| 1931 if (GetBucketAsString(kResultBucketId, &str)) { | 1960 if (GetBucketAsString(kResultBucketId, &str)) { |
| 1932 // Adds extensions implemented on client side only. | 1961 // Adds extensions implemented on client side only. |
| 1933 switch (name) { | 1962 switch (name) { |
| 1934 case GL_EXTENSIONS: | 1963 case GL_EXTENSIONS: |
| 1935 str += std::string(str.empty() ? "" : " ") + | 1964 str += std::string(str.empty() ? "" : " ") + |
| 1936 "GL_CHROMIUM_map_sub " | 1965 "GL_CHROMIUM_map_sub " |
| 1937 "GL_CHROMIUM_flipy"; | 1966 "GL_CHROMIUM_flipy " |
| 1967 "GL_EXT_unpack_subimage"; |
| 1938 break; | 1968 break; |
| 1939 default: | 1969 default: |
| 1940 break; | 1970 break; |
| 1941 } | 1971 } |
| 1942 | 1972 |
| 1943 // Because of WebGL the extensions can change. We have to cache each unique | 1973 // Because of WebGL the extensions can change. We have to cache each unique |
| 1944 // result since we don't know when the client will stop referring to a | 1974 // result since we don't know when the client will stop referring to a |
| 1945 // previous one it queries. | 1975 // previous one it queries. |
| 1946 GLStringMap::iterator it = gl_strings_.find(name); | 1976 GLStringMap::iterator it = gl_strings_.find(name); |
| 1947 if (it == gl_strings_.end()) { | 1977 if (it == gl_strings_.end()) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2044 // glPixelStorei. So, we have to take that into account both in the fact that | 2074 // glPixelStorei. So, we have to take that into account both in the fact that |
| 2045 // the pixels returned from the ReadPixel command will include that padding | 2075 // the pixels returned from the ReadPixel command will include that padding |
| 2046 // and that when we copy the results to the user's buffer we need to not | 2076 // and that when we copy the results to the user's buffer we need to not |
| 2047 // write those padding bytes but leave them as they are. | 2077 // write those padding bytes but leave them as they are. |
| 2048 | 2078 |
| 2049 TRACE_EVENT0("gpu", "GLES2::ReadPixels"); | 2079 TRACE_EVENT0("gpu", "GLES2::ReadPixels"); |
| 2050 typedef gles2::ReadPixels::Result Result; | 2080 typedef gles2::ReadPixels::Result Result; |
| 2051 | 2081 |
| 2052 int8* dest = reinterpret_cast<int8*>(pixels); | 2082 int8* dest = reinterpret_cast<int8*>(pixels); |
| 2053 uint32 temp_size; | 2083 uint32 temp_size; |
| 2054 if (!GLES2Util::ComputeImageDataSize( | 2084 uint32 unpadded_row_size; |
| 2055 width, 1, format, type, pack_alignment_, &temp_size)) { | 2085 uint32 padded_row_size; |
| 2056 SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large."); | 2086 if (!GLES2Util::ComputeImageDataSizes( |
| 2057 return; | 2087 width, 2, format, type, pack_alignment_, &temp_size, &unpadded_row_size, |
| 2058 } | 2088 &padded_row_size)) { |
| 2059 GLsizeiptr unpadded_row_size = temp_size; | |
| 2060 if (!GLES2Util::ComputeImageDataSize( | |
| 2061 width, 2, format, type, pack_alignment_, &temp_size)) { | |
| 2062 SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large."); | |
| 2063 return; | |
| 2064 } | |
| 2065 GLsizei padded_row_size = temp_size - unpadded_row_size; | |
| 2066 if (padded_row_size < 0 || unpadded_row_size < 0) { | |
| 2067 SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large."); | 2089 SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large."); |
| 2068 return; | 2090 return; |
| 2069 } | 2091 } |
| 2070 // Transfer by rows. | 2092 // Transfer by rows. |
| 2071 // The max rows we can transfer. | 2093 // The max rows we can transfer. |
| 2072 while (height) { | 2094 while (height) { |
| 2073 GLsizei desired_size = padded_row_size * height - 1 + unpadded_row_size; | 2095 GLsizei desired_size = padded_row_size * height - 1 + unpadded_row_size; |
| 2074 ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_); | 2096 ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_); |
| 2075 if (!buffer.valid()) { | 2097 if (!buffer.valid()) { |
| 2076 return; | 2098 return; |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2564 SetGLError(GL_INVALID_ENUM, "MapTexSubImage2DCHROMIUM: bad access mode"); | 2586 SetGLError(GL_INVALID_ENUM, "MapTexSubImage2DCHROMIUM: bad access mode"); |
| 2565 return NULL; | 2587 return NULL; |
| 2566 } | 2588 } |
| 2567 // NOTE: target is NOT checked because the service will check it | 2589 // NOTE: target is NOT checked because the service will check it |
| 2568 // and we don't know what targets are valid. | 2590 // and we don't know what targets are valid. |
| 2569 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) { | 2591 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) { |
| 2570 SetGLError(GL_INVALID_VALUE, "MapTexSubImage2DCHROMIUM: bad dimensions"); | 2592 SetGLError(GL_INVALID_VALUE, "MapTexSubImage2DCHROMIUM: bad dimensions"); |
| 2571 return NULL; | 2593 return NULL; |
| 2572 } | 2594 } |
| 2573 uint32 size; | 2595 uint32 size; |
| 2574 if (!GLES2Util::ComputeImageDataSize( | 2596 if (!GLES2Util::ComputeImageDataSizes( |
| 2575 width, height, format, type, unpack_alignment_, &size)) { | 2597 width, height, format, type, unpack_alignment_, &size, NULL, NULL)) { |
| 2576 SetGLError( | 2598 SetGLError( |
| 2577 GL_INVALID_VALUE, "MapTexSubImage2DCHROMIUM: image size too large"); | 2599 GL_INVALID_VALUE, "MapTexSubImage2DCHROMIUM: image size too large"); |
| 2578 return NULL; | 2600 return NULL; |
| 2579 } | 2601 } |
| 2580 int32 shm_id; | 2602 int32 shm_id; |
| 2581 unsigned int shm_offset; | 2603 unsigned int shm_offset; |
| 2582 void* mem = mapped_memory_->Alloc(size, &shm_id, &shm_offset); | 2604 void* mem = mapped_memory_->Alloc(size, &shm_id, &shm_offset); |
| 2583 if (!mem) { | 2605 if (!mem) { |
| 2584 SetGLError(GL_OUT_OF_MEMORY, "MapTexSubImage2DCHROMIUM: out of memory"); | 2606 SetGLError(GL_OUT_OF_MEMORY, "MapTexSubImage2DCHROMIUM: out of memory"); |
| 2585 return NULL; | 2607 return NULL; |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3100 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | 3122 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
| 3101 } | 3123 } |
| 3102 #else | 3124 #else |
| 3103 helper_->DrawElementsInstancedANGLE( | 3125 helper_->DrawElementsInstancedANGLE( |
| 3104 mode, count, type, ToGLuint(indices), primcount); | 3126 mode, count, type, ToGLuint(indices), primcount); |
| 3105 #endif | 3127 #endif |
| 3106 } | 3128 } |
| 3107 | 3129 |
| 3108 } // namespace gles2 | 3130 } // namespace gles2 |
| 3109 } // namespace gpu | 3131 } // namespace gpu |
| OLD | NEW |