| 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 <algorithm> | 9 #include <algorithm> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 unpack_row_length_(0), | 89 unpack_row_length_(0), |
| 90 unpack_skip_rows_(0), | 90 unpack_skip_rows_(0), |
| 91 unpack_skip_pixels_(0), | 91 unpack_skip_pixels_(0), |
| 92 pack_reverse_row_order_(false), | 92 pack_reverse_row_order_(false), |
| 93 active_texture_unit_(0), | 93 active_texture_unit_(0), |
| 94 bound_framebuffer_(0), | 94 bound_framebuffer_(0), |
| 95 bound_read_framebuffer_(0), | 95 bound_read_framebuffer_(0), |
| 96 bound_renderbuffer_(0), | 96 bound_renderbuffer_(0), |
| 97 current_program_(0), | 97 current_program_(0), |
| 98 bound_array_buffer_id_(0), | 98 bound_array_buffer_id_(0), |
| 99 bound_pixel_pack_transfer_buffer_id_(0), |
| 99 bound_pixel_unpack_transfer_buffer_id_(0), | 100 bound_pixel_unpack_transfer_buffer_id_(0), |
| 100 error_bits_(0), | 101 error_bits_(0), |
| 101 debug_(false), | 102 debug_(false), |
| 102 use_count_(0), | 103 use_count_(0), |
| 103 current_query_(NULL), | 104 current_query_(NULL), |
| 104 error_message_callback_(NULL) { | 105 error_message_callback_(NULL) { |
| 105 GPU_DCHECK(helper); | 106 GPU_DCHECK(helper); |
| 106 GPU_DCHECK(transfer_buffer); | 107 GPU_DCHECK(transfer_buffer); |
| 107 | 108 |
| 108 char temp[128]; | 109 char temp[128]; |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 return true; | 583 return true; |
| 583 } | 584 } |
| 584 return false; | 585 return false; |
| 585 case GL_ELEMENT_ARRAY_BUFFER_BINDING: | 586 case GL_ELEMENT_ARRAY_BUFFER_BINDING: |
| 586 if (share_group_->bind_generates_resource()) { | 587 if (share_group_->bind_generates_resource()) { |
| 587 *params = | 588 *params = |
| 588 vertex_array_object_manager_->bound_element_array_buffer(); | 589 vertex_array_object_manager_->bound_element_array_buffer(); |
| 589 return true; | 590 return true; |
| 590 } | 591 } |
| 591 return false; | 592 return false; |
| 593 case GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
| 594 *params = bound_pixel_pack_transfer_buffer_id_; |
| 595 return true; |
| 592 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: | 596 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
| 593 *params = bound_pixel_unpack_transfer_buffer_id_; | 597 *params = bound_pixel_unpack_transfer_buffer_id_; |
| 594 return true; | 598 return true; |
| 595 case GL_ACTIVE_TEXTURE: | 599 case GL_ACTIVE_TEXTURE: |
| 596 *params = active_texture_unit_ + GL_TEXTURE0; | 600 *params = active_texture_unit_ + GL_TEXTURE0; |
| 597 return true; | 601 return true; |
| 598 case GL_TEXTURE_BINDING_2D: | 602 case GL_TEXTURE_BINDING_2D: |
| 599 if (share_group_->bind_generates_resource()) { | 603 if (share_group_->bind_generates_resource()) { |
| 600 *params = texture_units_[active_texture_unit_].bound_texture_2d; | 604 *params = texture_units_[active_texture_unit_].bound_texture_2d; |
| 601 return true; | 605 return true; |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 CheckGLError(); | 1245 CheckGLError(); |
| 1242 } | 1246 } |
| 1243 | 1247 |
| 1244 void GLES2Implementation::BufferDataHelper( | 1248 void GLES2Implementation::BufferDataHelper( |
| 1245 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { | 1249 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { |
| 1246 if (size < 0) { | 1250 if (size < 0) { |
| 1247 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); | 1251 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); |
| 1248 return; | 1252 return; |
| 1249 } | 1253 } |
| 1250 | 1254 |
| 1251 if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | 1255 GLuint buffer_id; |
| 1252 GLuint buffer_id = bound_pixel_unpack_transfer_buffer_id_; | 1256 if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) { |
| 1253 if (!buffer_id) { | 1257 if (!buffer_id) { |
| 1254 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); | |
| 1255 return; | 1258 return; |
| 1256 } | 1259 } |
| 1257 | 1260 |
| 1258 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | 1261 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 1259 if (buffer) { | 1262 if (buffer) { |
| 1260 // Free buffer memory, pending the passage of a token. | 1263 // Free buffer memory, pending the passage of a token. |
| 1261 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | 1264 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
| 1262 | 1265 |
| 1263 // Remove old buffer. | 1266 // Remove old buffer. |
| 1264 buffer_tracker_->RemoveBuffer(buffer_id); | 1267 buffer_tracker_->RemoveBuffer(buffer_id); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1321 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1324 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
| 1322 if (size == 0) { | 1325 if (size == 0) { |
| 1323 return; | 1326 return; |
| 1324 } | 1327 } |
| 1325 | 1328 |
| 1326 if (size < 0) { | 1329 if (size < 0) { |
| 1327 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "size < 0"); | 1330 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "size < 0"); |
| 1328 return; | 1331 return; |
| 1329 } | 1332 } |
| 1330 | 1333 |
| 1331 if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | 1334 GLuint buffer_id; |
| 1332 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | 1335 if (GetBoundPixelTransferBuffer(target, "glBufferSubData", &buffer_id)) { |
| 1333 bound_pixel_unpack_transfer_buffer_id_); | 1336 if (!buffer_id) { |
| 1337 return; |
| 1338 } |
| 1339 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 1334 if (!buffer) { | 1340 if (!buffer) { |
| 1335 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer"); | 1341 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer"); |
| 1336 return; | 1342 return; |
| 1337 } | 1343 } |
| 1338 | 1344 |
| 1339 int32 end = 0; | 1345 int32 end = 0; |
| 1340 int32 buffer_size = buffer->size(); | 1346 int32 buffer_size = buffer->size(); |
| 1341 if (!SafeAddInt32(offset, size, &end) || end > buffer_size) { | 1347 if (!SafeAddInt32(offset, size, &end) || end > buffer_size) { |
| 1342 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); | 1348 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); |
| 1343 return; | 1349 return; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1380 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1386 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
| 1381 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1387 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1382 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" | 1388 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" |
| 1383 << GLES2Util::GetStringBufferTarget(target) << ", " | 1389 << GLES2Util::GetStringBufferTarget(target) << ", " |
| 1384 << offset << ", " << size << ", " | 1390 << offset << ", " << size << ", " |
| 1385 << static_cast<const void*>(data) << ")"); | 1391 << static_cast<const void*>(data) << ")"); |
| 1386 BufferSubDataHelper(target, offset, size, data); | 1392 BufferSubDataHelper(target, offset, size, data); |
| 1387 CheckGLError(); | 1393 CheckGLError(); |
| 1388 } | 1394 } |
| 1389 | 1395 |
| 1396 bool GLES2Implementation::GetBoundPixelTransferBuffer( |
| 1397 GLenum target, |
| 1398 const char* function_name, |
| 1399 GLuint* buffer_id) { |
| 1400 *buffer_id = 0; |
| 1401 |
| 1402 switch (target) { |
| 1403 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| 1404 *buffer_id = bound_pixel_pack_transfer_buffer_id_; |
| 1405 break; |
| 1406 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| 1407 *buffer_id = bound_pixel_unpack_transfer_buffer_id_; |
| 1408 break; |
| 1409 default: |
| 1410 // Unknown target |
| 1411 return false; |
| 1412 } |
| 1413 if (!*buffer_id) { |
| 1414 SetGLError(GL_INVALID_OPERATION, function_name, "no buffer bound"); |
| 1415 } |
| 1416 return true; |
| 1417 } |
| 1418 |
| 1390 BufferTracker::Buffer* | 1419 BufferTracker::Buffer* |
| 1391 GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid( | 1420 GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid( |
| 1392 const char* function_name, GLuint offset, GLsizei size) | 1421 GLuint buffer_id, |
| 1422 const char* function_name, |
| 1423 GLuint offset, GLsizei size) |
| 1393 { | 1424 { |
| 1394 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | 1425 DCHECK(buffer_id); |
| 1395 bound_pixel_unpack_transfer_buffer_id_); | 1426 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 1396 if (!buffer) { | 1427 if (!buffer) { |
| 1397 SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer"); | 1428 SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer"); |
| 1398 return NULL; | 1429 return NULL; |
| 1399 } | 1430 } |
| 1400 if (buffer->mapped()) { | 1431 if (buffer->mapped()) { |
| 1401 SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped"); | 1432 SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped"); |
| 1402 return NULL; | 1433 return NULL; |
| 1403 } | 1434 } |
| 1404 if ((buffer->size() - offset) < static_cast<GLuint>(size)) { | 1435 if ((buffer->size() - offset) < static_cast<GLuint>(size)) { |
| 1405 SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large"); | 1436 SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large"); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1424 return; | 1455 return; |
| 1425 } | 1456 } |
| 1426 if (height == 0 || width == 0) { | 1457 if (height == 0 || width == 0) { |
| 1427 return; | 1458 return; |
| 1428 } | 1459 } |
| 1429 // If there's a pixel unpack buffer bound use it when issuing | 1460 // If there's a pixel unpack buffer bound use it when issuing |
| 1430 // CompressedTexImage2D. | 1461 // CompressedTexImage2D. |
| 1431 if (bound_pixel_unpack_transfer_buffer_id_) { | 1462 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1432 GLuint offset = ToGLuint(data); | 1463 GLuint offset = ToGLuint(data); |
| 1433 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1464 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1465 bound_pixel_unpack_transfer_buffer_id_, |
| 1434 "glCompressedTexImage2D", offset, image_size); | 1466 "glCompressedTexImage2D", offset, image_size); |
| 1435 if (buffer) | 1467 if (buffer) { |
| 1436 helper_->CompressedTexImage2D( | 1468 helper_->CompressedTexImage2D( |
| 1437 target, level, internalformat, width, height, border, image_size, | 1469 target, level, internalformat, width, height, border, image_size, |
| 1438 buffer->shm_id(), buffer->shm_offset() + offset); | 1470 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1471 buffer->set_transfer_ready_token(helper_->InsertToken()); |
| 1472 } |
| 1439 return; | 1473 return; |
| 1440 } | 1474 } |
| 1441 SetBucketContents(kResultBucketId, data, image_size); | 1475 SetBucketContents(kResultBucketId, data, image_size); |
| 1442 helper_->CompressedTexImage2DBucket( | 1476 helper_->CompressedTexImage2DBucket( |
| 1443 target, level, internalformat, width, height, border, kResultBucketId); | 1477 target, level, internalformat, width, height, border, kResultBucketId); |
| 1444 // Free the bucket. This is not required but it does free up the memory. | 1478 // Free the bucket. This is not required but it does free up the memory. |
| 1445 // and we don't have to wait for the result so from the client's perspective | 1479 // and we don't have to wait for the result so from the client's perspective |
| 1446 // it's cheap. | 1480 // it's cheap. |
| 1447 helper_->SetBucketSize(kResultBucketId, 0); | 1481 helper_->SetBucketSize(kResultBucketId, 0); |
| 1448 CheckGLError(); | 1482 CheckGLError(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1462 << static_cast<const void*>(data) << ")"); | 1496 << static_cast<const void*>(data) << ")"); |
| 1463 if (width < 0 || height < 0 || level < 0) { | 1497 if (width < 0 || height < 0 || level < 0) { |
| 1464 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); | 1498 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); |
| 1465 return; | 1499 return; |
| 1466 } | 1500 } |
| 1467 // If there's a pixel unpack buffer bound use it when issuing | 1501 // If there's a pixel unpack buffer bound use it when issuing |
| 1468 // CompressedTexSubImage2D. | 1502 // CompressedTexSubImage2D. |
| 1469 if (bound_pixel_unpack_transfer_buffer_id_) { | 1503 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1470 GLuint offset = ToGLuint(data); | 1504 GLuint offset = ToGLuint(data); |
| 1471 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1505 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1506 bound_pixel_unpack_transfer_buffer_id_, |
| 1472 "glCompressedTexSubImage2D", offset, image_size); | 1507 "glCompressedTexSubImage2D", offset, image_size); |
| 1473 if (buffer) | 1508 if (buffer) { |
| 1474 helper_->CompressedTexSubImage2D( | 1509 helper_->CompressedTexSubImage2D( |
| 1475 target, level, xoffset, yoffset, width, height, format, image_size, | 1510 target, level, xoffset, yoffset, width, height, format, image_size, |
| 1476 buffer->shm_id(), buffer->shm_offset() + offset); | 1511 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1512 buffer->set_transfer_ready_token(helper_->InsertToken()); |
| 1513 CheckGLError(); |
| 1514 } |
| 1477 return; | 1515 return; |
| 1478 } | 1516 } |
| 1479 SetBucketContents(kResultBucketId, data, image_size); | 1517 SetBucketContents(kResultBucketId, data, image_size); |
| 1480 helper_->CompressedTexSubImage2DBucket( | 1518 helper_->CompressedTexSubImage2DBucket( |
| 1481 target, level, xoffset, yoffset, width, height, format, kResultBucketId); | 1519 target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
| 1482 // Free the bucket. This is not required but it does free up the memory. | 1520 // Free the bucket. This is not required but it does free up the memory. |
| 1483 // and we don't have to wait for the result so from the client's perspective | 1521 // and we don't have to wait for the result so from the client's perspective |
| 1484 // it's cheap. | 1522 // it's cheap. |
| 1485 helper_->SetBucketSize(kResultBucketId, 0); | 1523 helper_->SetBucketSize(kResultBucketId, 0); |
| 1486 CheckGLError(); | 1524 CheckGLError(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1545 width, height, format, type, unpack_alignment_, &size, | 1583 width, height, format, type, unpack_alignment_, &size, |
| 1546 &unpadded_row_size, &padded_row_size)) { | 1584 &unpadded_row_size, &padded_row_size)) { |
| 1547 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); | 1585 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
| 1548 return; | 1586 return; |
| 1549 } | 1587 } |
| 1550 | 1588 |
| 1551 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. | 1589 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
| 1552 if (bound_pixel_unpack_transfer_buffer_id_) { | 1590 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1553 GLuint offset = ToGLuint(pixels); | 1591 GLuint offset = ToGLuint(pixels); |
| 1554 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1592 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1593 bound_pixel_unpack_transfer_buffer_id_, |
| 1555 "glTexImage2D", offset, size); | 1594 "glTexImage2D", offset, size); |
| 1556 if (buffer) | 1595 if (buffer) { |
| 1557 helper_->TexImage2D( | 1596 helper_->TexImage2D( |
| 1558 target, level, internalformat, width, height, border, format, type, | 1597 target, level, internalformat, width, height, border, format, type, |
| 1559 buffer->shm_id(), buffer->shm_offset() + offset); | 1598 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1560 CheckGLError(); | 1599 buffer->set_transfer_ready_token(helper_->InsertToken()); |
| 1600 CheckGLError(); |
| 1601 } |
| 1561 return; | 1602 return; |
| 1562 } | 1603 } |
| 1563 | 1604 |
| 1564 // If there's no data just issue TexImage2D | 1605 // If there's no data just issue TexImage2D |
| 1565 if (!pixels) { | 1606 if (!pixels) { |
| 1566 helper_->TexImage2D( | 1607 helper_->TexImage2D( |
| 1567 target, level, internalformat, width, height, border, format, type, | 1608 target, level, internalformat, width, height, border, format, type, |
| 1568 0, 0); | 1609 0, 0); |
| 1569 CheckGLError(); | 1610 CheckGLError(); |
| 1570 return; | 1611 return; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1648 width, height, format, type, unpack_alignment_, &temp_size, | 1689 width, height, format, type, unpack_alignment_, &temp_size, |
| 1649 &unpadded_row_size, &padded_row_size)) { | 1690 &unpadded_row_size, &padded_row_size)) { |
| 1650 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); | 1691 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); |
| 1651 return; | 1692 return; |
| 1652 } | 1693 } |
| 1653 | 1694 |
| 1654 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | 1695 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
| 1655 if (bound_pixel_unpack_transfer_buffer_id_) { | 1696 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1656 GLuint offset = ToGLuint(pixels); | 1697 GLuint offset = ToGLuint(pixels); |
| 1657 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1698 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1699 bound_pixel_unpack_transfer_buffer_id_, |
| 1658 "glTexSubImage2D", offset, temp_size); | 1700 "glTexSubImage2D", offset, temp_size); |
| 1659 if (buffer) | 1701 if (buffer) { |
| 1660 helper_->TexSubImage2D( | 1702 helper_->TexSubImage2D( |
| 1661 target, level, xoffset, yoffset, width, height, format, type, | 1703 target, level, xoffset, yoffset, width, height, format, type, |
| 1662 buffer->shm_id(), buffer->shm_offset() + offset, false); | 1704 buffer->shm_id(), buffer->shm_offset() + offset, false); |
| 1663 CheckGLError(); | 1705 buffer->set_transfer_ready_token(helper_->InsertToken()); |
| 1706 CheckGLError(); |
| 1707 } |
| 1664 return; | 1708 return; |
| 1665 } | 1709 } |
| 1666 | 1710 |
| 1667 // compute the advance bytes per row for the src pixels | 1711 // compute the advance bytes per row for the src pixels |
| 1668 uint32 src_padded_row_size; | 1712 uint32 src_padded_row_size; |
| 1669 if (unpack_row_length_ > 0) { | 1713 if (unpack_row_length_ > 0) { |
| 1670 if (!GLES2Util::ComputeImagePaddedRowSize( | 1714 if (!GLES2Util::ComputeImagePaddedRowSize( |
| 1671 unpack_row_length_, format, type, unpack_alignment_, | 1715 unpack_row_length_, format, type, unpack_alignment_, |
| 1672 &src_padded_row_size)) { | 1716 &src_padded_row_size)) { |
| 1673 SetGLError( | 1717 SetGLError( |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2106 int8* dest = reinterpret_cast<int8*>(pixels); | 2150 int8* dest = reinterpret_cast<int8*>(pixels); |
| 2107 uint32 temp_size; | 2151 uint32 temp_size; |
| 2108 uint32 unpadded_row_size; | 2152 uint32 unpadded_row_size; |
| 2109 uint32 padded_row_size; | 2153 uint32 padded_row_size; |
| 2110 if (!GLES2Util::ComputeImageDataSizes( | 2154 if (!GLES2Util::ComputeImageDataSizes( |
| 2111 width, 2, format, type, pack_alignment_, &temp_size, &unpadded_row_size, | 2155 width, 2, format, type, pack_alignment_, &temp_size, &unpadded_row_size, |
| 2112 &padded_row_size)) { | 2156 &padded_row_size)) { |
| 2113 SetGLError(GL_INVALID_VALUE, "glReadPixels", "size too large."); | 2157 SetGLError(GL_INVALID_VALUE, "glReadPixels", "size too large."); |
| 2114 return; | 2158 return; |
| 2115 } | 2159 } |
| 2160 |
| 2161 if (bound_pixel_pack_transfer_buffer_id_) { |
| 2162 GLuint offset = ToGLuint(pixels); |
| 2163 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 2164 bound_pixel_pack_transfer_buffer_id_, |
| 2165 "glReadPixels", offset, temp_size); |
| 2166 if (buffer) { |
| 2167 helper_->ReadPixels(xoffset, yoffset, width, height, format, type, |
| 2168 buffer->shm_id(), buffer->shm_offset(), |
| 2169 0, 0); |
| 2170 buffer->set_transfer_ready_token(helper_->InsertToken()); |
| 2171 CheckGLError(); |
| 2172 } |
| 2173 return; |
| 2174 } |
| 2175 |
| 2176 if (!pixels) { |
| 2177 SetGLError(GL_INVALID_OPERATION, "glReadPixels", "pixels = NULL"); |
| 2178 return; |
| 2179 } |
| 2180 |
| 2116 // Transfer by rows. | 2181 // Transfer by rows. |
| 2117 // The max rows we can transfer. | 2182 // The max rows we can transfer. |
| 2118 while (height) { | 2183 while (height) { |
| 2119 GLsizei desired_size = padded_row_size * height - 1 + unpadded_row_size; | 2184 GLsizei desired_size = padded_row_size * height - 1 + unpadded_row_size; |
| 2120 ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_); | 2185 ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_); |
| 2121 if (!buffer.valid()) { | 2186 if (!buffer.valid()) { |
| 2122 return; | 2187 return; |
| 2123 } | 2188 } |
| 2124 GLint num_rows = ComputeNumRowsThatFitInBuffer( | 2189 GLint num_rows = ComputeNumRowsThatFitInBuffer( |
| 2125 padded_row_size, unpadded_row_size, buffer.size()); | 2190 padded_row_size, unpadded_row_size, buffer.size()); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2223 switch (target) { | 2288 switch (target) { |
| 2224 case GL_ARRAY_BUFFER: | 2289 case GL_ARRAY_BUFFER: |
| 2225 if (bound_array_buffer_id_ != buffer) { | 2290 if (bound_array_buffer_id_ != buffer) { |
| 2226 bound_array_buffer_id_ = buffer; | 2291 bound_array_buffer_id_ = buffer; |
| 2227 changed = true; | 2292 changed = true; |
| 2228 } | 2293 } |
| 2229 break; | 2294 break; |
| 2230 case GL_ELEMENT_ARRAY_BUFFER: | 2295 case GL_ELEMENT_ARRAY_BUFFER: |
| 2231 changed = vertex_array_object_manager_->BindElementArray(buffer); | 2296 changed = vertex_array_object_manager_->BindElementArray(buffer); |
| 2232 break; | 2297 break; |
| 2298 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| 2299 bound_pixel_pack_transfer_buffer_id_ = buffer; |
| 2300 break; |
| 2233 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | 2301 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| 2234 bound_pixel_unpack_transfer_buffer_id_ = buffer; | 2302 bound_pixel_unpack_transfer_buffer_id_ = buffer; |
| 2235 break; | 2303 break; |
| 2236 default: | 2304 default: |
| 2237 changed = true; | 2305 changed = true; |
| 2238 break; | 2306 break; |
| 2239 } | 2307 } |
| 2240 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2308 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
| 2241 // used even though it's marked it as used here. | 2309 // used even though it's marked it as used here. |
| 2242 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2310 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3302 } | 3370 } |
| 3303 helper_->TraceEndCHROMIUM(); | 3371 helper_->TraceEndCHROMIUM(); |
| 3304 TRACE_EVENT_COPY_ASYNC_END0("gpu", current_trace_name_->c_str(), this); | 3372 TRACE_EVENT_COPY_ASYNC_END0("gpu", current_trace_name_->c_str(), this); |
| 3305 current_trace_name_.reset(); | 3373 current_trace_name_.reset(); |
| 3306 } | 3374 } |
| 3307 | 3375 |
| 3308 void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { | 3376 void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { |
| 3309 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3377 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3310 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferCHROMIUM(" | 3378 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferCHROMIUM(" |
| 3311 << target << ", " << GLES2Util::GetStringEnum(access) << ")"); | 3379 << target << ", " << GLES2Util::GetStringEnum(access) << ")"); |
| 3312 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | 3380 switch (target) { |
| 3313 SetGLError( | 3381 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
| 3314 GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target"); | 3382 if (access != GL_READ_ONLY) { |
| 3383 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); |
| 3384 return NULL; |
| 3385 } |
| 3386 break; |
| 3387 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| 3388 if (access != GL_WRITE_ONLY) { |
| 3389 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); |
| 3390 return NULL; |
| 3391 } |
| 3392 break; |
| 3393 default: |
| 3394 SetGLError( |
| 3395 GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target"); |
| 3396 return NULL; |
| 3397 } |
| 3398 GLuint buffer_id; |
| 3399 GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id); |
| 3400 if (!buffer_id) { |
| 3315 return NULL; | 3401 return NULL; |
| 3316 } | 3402 } |
| 3317 if (access != GL_WRITE_ONLY) { | 3403 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 3318 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); | |
| 3319 return NULL; | |
| 3320 } | |
| 3321 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | |
| 3322 bound_pixel_unpack_transfer_buffer_id_); | |
| 3323 if (!buffer) { | 3404 if (!buffer) { |
| 3324 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); | 3405 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); |
| 3325 return NULL; | 3406 return NULL; |
| 3326 } | 3407 } |
| 3327 if (buffer->mapped()) { | 3408 if (buffer->mapped()) { |
| 3328 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); | 3409 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); |
| 3329 return NULL; | 3410 return NULL; |
| 3330 } | 3411 } |
| 3412 // Here we wait for previous transfer operations to be finished. |
| 3413 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work |
| 3414 // with this method of synchronization. Until this is fixed, |
| 3415 // MapBufferCHROMIUM will not block even if the transfer is not ready |
| 3416 // for these calls. |
| 3417 if (buffer->transfer_ready_token()) { |
| 3418 helper_->WaitForToken(buffer->transfer_ready_token()); |
| 3419 buffer->set_transfer_ready_token(0); |
| 3420 } |
| 3331 buffer->set_mapped(true); | 3421 buffer->set_mapped(true); |
| 3332 | 3422 |
| 3333 GPU_DCHECK(buffer->address()); | 3423 GPU_DCHECK(buffer->address()); |
| 3334 GPU_CLIENT_LOG(" returned " << buffer->address()); | 3424 GPU_CLIENT_LOG(" returned " << buffer->address()); |
| 3335 CheckGLError(); | 3425 CheckGLError(); |
| 3336 return buffer->address(); | 3426 return buffer->address(); |
| 3337 } | 3427 } |
| 3338 | 3428 |
| 3339 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { | 3429 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
| 3340 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3430 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3341 GPU_CLIENT_LOG( | 3431 GPU_CLIENT_LOG( |
| 3342 "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); | 3432 "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); |
| 3343 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | 3433 GLuint buffer_id; |
| 3434 if (!GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id)) { |
| 3344 SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); | 3435 SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); |
| 3436 } |
| 3437 if (!buffer_id) { |
| 3345 return false; | 3438 return false; |
| 3346 } | 3439 } |
| 3347 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | 3440 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 3348 bound_pixel_unpack_transfer_buffer_id_); | |
| 3349 if (!buffer) { | 3441 if (!buffer) { |
| 3350 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); | 3442 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); |
| 3351 return false; | 3443 return false; |
| 3352 } | 3444 } |
| 3353 if (!buffer->mapped()) { | 3445 if (!buffer->mapped()) { |
| 3354 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); | 3446 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); |
| 3355 return false; | 3447 return false; |
| 3356 } | 3448 } |
| 3357 buffer->set_mapped(false); | 3449 buffer->set_mapped(false); |
| 3358 CheckGLError(); | 3450 CheckGLError(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3388 | 3480 |
| 3389 // If there's no data/buffer just issue the AsyncTexImage2D | 3481 // If there's no data/buffer just issue the AsyncTexImage2D |
| 3390 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { | 3482 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { |
| 3391 helper_->AsyncTexImage2DCHROMIUM( | 3483 helper_->AsyncTexImage2DCHROMIUM( |
| 3392 target, level, internalformat, width, height, border, format, type, | 3484 target, level, internalformat, width, height, border, format, type, |
| 3393 0, 0); | 3485 0, 0); |
| 3394 return; | 3486 return; |
| 3395 } | 3487 } |
| 3396 | 3488 |
| 3397 // Otherwise, async uploads require a transfer buffer to be bound. | 3489 // Otherwise, async uploads require a transfer buffer to be bound. |
| 3490 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use |
| 3491 // the buffer before the transfer is finished. (Currently such |
| 3492 // synchronization has to be handled manually.) |
| 3398 GLuint offset = ToGLuint(pixels); | 3493 GLuint offset = ToGLuint(pixels); |
| 3399 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3494 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 3495 bound_pixel_unpack_transfer_buffer_id_, |
| 3400 "glAsyncTexImage2DCHROMIUM", offset, size); | 3496 "glAsyncTexImage2DCHROMIUM", offset, size); |
| 3401 if (!buffer) | 3497 if (!buffer) |
| 3402 return; | 3498 return; |
| 3403 | 3499 |
| 3404 helper_->AsyncTexImage2DCHROMIUM( | 3500 helper_->AsyncTexImage2DCHROMIUM( |
| 3405 target, level, internalformat, width, height, border, format, type, | 3501 target, level, internalformat, width, height, border, format, type, |
| 3406 buffer->shm_id(), buffer->shm_offset() + offset); | 3502 buffer->shm_id(), buffer->shm_offset() + offset); |
| 3407 return; | 3503 return; |
| 3408 } | 3504 } |
| 3409 | 3505 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3430 uint32 padded_row_size; | 3526 uint32 padded_row_size; |
| 3431 if (!GLES2Util::ComputeImageDataSizes( | 3527 if (!GLES2Util::ComputeImageDataSizes( |
| 3432 width, height, format, type, unpack_alignment_, &size, | 3528 width, height, format, type, unpack_alignment_, &size, |
| 3433 &unpadded_row_size, &padded_row_size)) { | 3529 &unpadded_row_size, &padded_row_size)) { |
| 3434 SetGLError( | 3530 SetGLError( |
| 3435 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); | 3531 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); |
| 3436 return; | 3532 return; |
| 3437 } | 3533 } |
| 3438 | 3534 |
| 3439 // Async uploads require a transfer buffer to be bound. | 3535 // Async uploads require a transfer buffer to be bound. |
| 3536 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use |
| 3537 // the buffer before the transfer is finished. (Currently such |
| 3538 // synchronization has to be handled manually.) |
| 3440 GLuint offset = ToGLuint(pixels); | 3539 GLuint offset = ToGLuint(pixels); |
| 3441 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3540 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 3541 bound_pixel_unpack_transfer_buffer_id_, |
| 3442 "glAsyncTexSubImage2DCHROMIUM", offset, size); | 3542 "glAsyncTexSubImage2DCHROMIUM", offset, size); |
| 3443 if (!buffer) | 3543 if (!buffer) |
| 3444 return; | 3544 return; |
| 3445 | 3545 |
| 3446 helper_->AsyncTexSubImage2DCHROMIUM( | 3546 helper_->AsyncTexSubImage2DCHROMIUM( |
| 3447 target, level, xoffset, yoffset, width, height, format, type, | 3547 target, level, xoffset, yoffset, width, height, format, type, |
| 3448 buffer->shm_id(), buffer->shm_offset() + offset); | 3548 buffer->shm_id(), buffer->shm_offset() + offset); |
| 3449 return; | 3549 return; |
| 3450 } | 3550 } |
| 3451 | 3551 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3463 return helper_->InsertSyncPointCHROMIUM(); | 3563 return helper_->InsertSyncPointCHROMIUM(); |
| 3464 } | 3564 } |
| 3465 | 3565 |
| 3466 // Include the auto-generated part of this file. We split this because it means | 3566 // Include the auto-generated part of this file. We split this because it means |
| 3467 // we can easily edit the non-auto generated parts right here in this file | 3567 // we can easily edit the non-auto generated parts right here in this file |
| 3468 // instead of having to edit some template or the code generator. | 3568 // instead of having to edit some template or the code generator. |
| 3469 #include "../client/gles2_implementation_impl_autogen.h" | 3569 #include "../client/gles2_implementation_impl_autogen.h" |
| 3470 | 3570 |
| 3471 } // namespace gles2 | 3571 } // namespace gles2 |
| 3472 } // namespace gpu | 3572 } // namespace gpu |
| OLD | NEW |