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) return; |
piman
2013/03/28 20:22:27
nit: return on its own line
hubbe
2013/03/28 20:52:35
Done.
| |
1254 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); | |
1255 return; | |
1256 } | |
1257 | 1258 |
1258 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | 1259 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
1259 if (buffer) { | 1260 if (buffer) { |
1260 // Free buffer memory, pending the passage of a token. | 1261 // Free buffer memory, pending the passage of a token. |
1261 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | 1262 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
1262 | 1263 |
1263 // Remove old buffer. | 1264 // Remove old buffer. |
1264 buffer_tracker_->RemoveBuffer(buffer_id); | 1265 buffer_tracker_->RemoveBuffer(buffer_id); |
1265 } | 1266 } |
1266 | 1267 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1321 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1322 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
1322 if (size == 0) { | 1323 if (size == 0) { |
1323 return; | 1324 return; |
1324 } | 1325 } |
1325 | 1326 |
1326 if (size < 0) { | 1327 if (size < 0) { |
1327 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "size < 0"); | 1328 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "size < 0"); |
1328 return; | 1329 return; |
1329 } | 1330 } |
1330 | 1331 |
1331 if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | 1332 GLuint buffer_id; |
1332 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | 1333 if (GetBoundPixelTransferBuffer(target, "glBufferSubData", &buffer_id)) { |
1333 bound_pixel_unpack_transfer_buffer_id_); | 1334 if (!buffer_id) return; |
piman
2013/03/28 20:22:27
nit: put return on its own line
hubbe
2013/03/28 20:52:35
Done.
| |
1335 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | |
1334 if (!buffer) { | 1336 if (!buffer) { |
1335 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer"); | 1337 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer"); |
1336 return; | 1338 return; |
1337 } | 1339 } |
1338 | 1340 |
1339 int32 end = 0; | 1341 int32 end = 0; |
1340 int32 buffer_size = buffer->size(); | 1342 int32 buffer_size = buffer->size(); |
1341 if (!SafeAddInt32(offset, size, &end) || end > buffer_size) { | 1343 if (!SafeAddInt32(offset, size, &end) || end > buffer_size) { |
1342 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); | 1344 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); |
1343 return; | 1345 return; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1380 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1382 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
1381 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1383 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1382 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" | 1384 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" |
1383 << GLES2Util::GetStringBufferTarget(target) << ", " | 1385 << GLES2Util::GetStringBufferTarget(target) << ", " |
1384 << offset << ", " << size << ", " | 1386 << offset << ", " << size << ", " |
1385 << static_cast<const void*>(data) << ")"); | 1387 << static_cast<const void*>(data) << ")"); |
1386 BufferSubDataHelper(target, offset, size, data); | 1388 BufferSubDataHelper(target, offset, size, data); |
1387 CheckGLError(); | 1389 CheckGLError(); |
1388 } | 1390 } |
1389 | 1391 |
1392 bool GLES2Implementation::GetBoundPixelTransferBuffer( | |
1393 GLenum target, | |
1394 const char* function_name, | |
1395 GLuint* buffer_id) { | |
1396 *buffer_id = 0; | |
1397 | |
1398 switch (target) { | |
1399 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | |
1400 *buffer_id = bound_pixel_pack_transfer_buffer_id_; | |
1401 break; | |
1402 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | |
1403 *buffer_id = bound_pixel_unpack_transfer_buffer_id_; | |
1404 break; | |
1405 default: | |
1406 // Unknown target | |
piman
2013/03/28 20:22:27
Set error here, rather than the callsites.
hubbe
2013/03/28 20:52:35
The idea is for this function to handle certain ta
| |
1407 return false; | |
1408 } | |
1409 if (!*buffer_id) { | |
1410 SetGLError(GL_INVALID_VALUE, function_name, "no buffer bound"); | |
piman
2013/03/28 20:22:27
GL_INVALID_OPERATION (according to spec).
Should
hubbe
2013/03/28 20:52:35
See explanation above.
Also, could you point me to
| |
1411 } | |
1412 return true; | |
1413 } | |
1414 | |
1390 BufferTracker::Buffer* | 1415 BufferTracker::Buffer* |
1391 GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid( | 1416 GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid( |
1392 const char* function_name, GLuint offset, GLsizei size) | 1417 GLuint buffer_id, |
1418 const char* function_name, | |
1419 GLuint offset, GLsizei size) | |
1393 { | 1420 { |
1394 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | 1421 DCHECK(buffer_id); |
1395 bound_pixel_unpack_transfer_buffer_id_); | 1422 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
1396 if (!buffer) { | 1423 if (!buffer) { |
1397 SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer"); | 1424 SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer"); |
1398 return NULL; | 1425 return NULL; |
1399 } | 1426 } |
1400 if (buffer->mapped()) { | 1427 if (buffer->mapped()) { |
1401 SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped"); | 1428 SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped"); |
1402 return NULL; | 1429 return NULL; |
1403 } | 1430 } |
1404 if ((buffer->size() - offset) < static_cast<GLuint>(size)) { | 1431 if ((buffer->size() - offset) < static_cast<GLuint>(size)) { |
1405 SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large"); | 1432 SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large"); |
(...skipping 18 matching lines...) Expand all Loading... | |
1424 return; | 1451 return; |
1425 } | 1452 } |
1426 if (height == 0 || width == 0) { | 1453 if (height == 0 || width == 0) { |
1427 return; | 1454 return; |
1428 } | 1455 } |
1429 // If there's a pixel unpack buffer bound use it when issuing | 1456 // If there's a pixel unpack buffer bound use it when issuing |
1430 // CompressedTexImage2D. | 1457 // CompressedTexImage2D. |
1431 if (bound_pixel_unpack_transfer_buffer_id_) { | 1458 if (bound_pixel_unpack_transfer_buffer_id_) { |
1432 GLuint offset = ToGLuint(data); | 1459 GLuint offset = ToGLuint(data); |
1433 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1460 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
1461 bound_pixel_unpack_transfer_buffer_id_, | |
1434 "glCompressedTexImage2D", offset, image_size); | 1462 "glCompressedTexImage2D", offset, image_size); |
1435 if (buffer) | 1463 if (buffer) { |
1436 helper_->CompressedTexImage2D( | 1464 helper_->CompressedTexImage2D( |
1437 target, level, internalformat, width, height, border, image_size, | 1465 target, level, internalformat, width, height, border, image_size, |
1438 buffer->shm_id(), buffer->shm_offset() + offset); | 1466 buffer->shm_id(), buffer->shm_offset() + offset); |
1467 buffer->set_transfer_ready_token(helper_->InsertToken()); | |
1468 } else { | |
1469 SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "invalid buffer"); | |
piman
2013/03/28 20:22:27
GetBoundPixelUnpackTransferBufferIfValid already s
hubbe
2013/03/28 20:52:35
Done.
| |
1470 } | |
1439 return; | 1471 return; |
1440 } | 1472 } |
1441 SetBucketContents(kResultBucketId, data, image_size); | 1473 SetBucketContents(kResultBucketId, data, image_size); |
1442 helper_->CompressedTexImage2DBucket( | 1474 helper_->CompressedTexImage2DBucket( |
1443 target, level, internalformat, width, height, border, kResultBucketId); | 1475 target, level, internalformat, width, height, border, kResultBucketId); |
1444 // Free the bucket. This is not required but it does free up the memory. | 1476 // 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 | 1477 // and we don't have to wait for the result so from the client's perspective |
1446 // it's cheap. | 1478 // it's cheap. |
1447 helper_->SetBucketSize(kResultBucketId, 0); | 1479 helper_->SetBucketSize(kResultBucketId, 0); |
1448 CheckGLError(); | 1480 CheckGLError(); |
(...skipping 13 matching lines...) Expand all Loading... | |
1462 << static_cast<const void*>(data) << ")"); | 1494 << static_cast<const void*>(data) << ")"); |
1463 if (width < 0 || height < 0 || level < 0) { | 1495 if (width < 0 || height < 0 || level < 0) { |
1464 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); | 1496 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); |
1465 return; | 1497 return; |
1466 } | 1498 } |
1467 // If there's a pixel unpack buffer bound use it when issuing | 1499 // If there's a pixel unpack buffer bound use it when issuing |
1468 // CompressedTexSubImage2D. | 1500 // CompressedTexSubImage2D. |
1469 if (bound_pixel_unpack_transfer_buffer_id_) { | 1501 if (bound_pixel_unpack_transfer_buffer_id_) { |
1470 GLuint offset = ToGLuint(data); | 1502 GLuint offset = ToGLuint(data); |
1471 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1503 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
1504 bound_pixel_unpack_transfer_buffer_id_, | |
1472 "glCompressedTexSubImage2D", offset, image_size); | 1505 "glCompressedTexSubImage2D", offset, image_size); |
1473 if (buffer) | 1506 if (buffer) { |
1474 helper_->CompressedTexSubImage2D( | 1507 helper_->CompressedTexSubImage2D( |
1475 target, level, xoffset, yoffset, width, height, format, image_size, | 1508 target, level, xoffset, yoffset, width, height, format, image_size, |
1476 buffer->shm_id(), buffer->shm_offset() + offset); | 1509 buffer->shm_id(), buffer->shm_offset() + offset); |
1510 buffer->set_transfer_ready_token(helper_->InsertToken()); | |
1511 CheckGLError(); | |
1512 } else { | |
1513 SetGLError(GL_INVALID_VALUE, | |
piman
2013/03/28 20:22:27
GetBoundPixelUnpackTransferBufferIfValid already s
hubbe
2013/03/28 20:52:35
Done.
| |
1514 "glCompressedTexSubImage2D", "invalid buffer"); | |
1515 } | |
1477 return; | 1516 return; |
1478 } | 1517 } |
1479 SetBucketContents(kResultBucketId, data, image_size); | 1518 SetBucketContents(kResultBucketId, data, image_size); |
1480 helper_->CompressedTexSubImage2DBucket( | 1519 helper_->CompressedTexSubImage2DBucket( |
1481 target, level, xoffset, yoffset, width, height, format, kResultBucketId); | 1520 target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
1482 // Free the bucket. This is not required but it does free up the memory. | 1521 // 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 | 1522 // and we don't have to wait for the result so from the client's perspective |
1484 // it's cheap. | 1523 // it's cheap. |
1485 helper_->SetBucketSize(kResultBucketId, 0); | 1524 helper_->SetBucketSize(kResultBucketId, 0); |
1486 CheckGLError(); | 1525 CheckGLError(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1545 width, height, format, type, unpack_alignment_, &size, | 1584 width, height, format, type, unpack_alignment_, &size, |
1546 &unpadded_row_size, &padded_row_size)) { | 1585 &unpadded_row_size, &padded_row_size)) { |
1547 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); | 1586 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
1548 return; | 1587 return; |
1549 } | 1588 } |
1550 | 1589 |
1551 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. | 1590 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
1552 if (bound_pixel_unpack_transfer_buffer_id_) { | 1591 if (bound_pixel_unpack_transfer_buffer_id_) { |
1553 GLuint offset = ToGLuint(pixels); | 1592 GLuint offset = ToGLuint(pixels); |
1554 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1593 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
1594 bound_pixel_unpack_transfer_buffer_id_, | |
1555 "glTexImage2D", offset, size); | 1595 "glTexImage2D", offset, size); |
1556 if (buffer) | 1596 if (buffer) { |
1557 helper_->TexImage2D( | 1597 helper_->TexImage2D( |
1558 target, level, internalformat, width, height, border, format, type, | 1598 target, level, internalformat, width, height, border, format, type, |
1559 buffer->shm_id(), buffer->shm_offset() + offset); | 1599 buffer->shm_id(), buffer->shm_offset() + offset); |
1560 CheckGLError(); | 1600 buffer->set_transfer_ready_token(helper_->InsertToken()); |
1601 CheckGLError(); | |
1602 } else { | |
1603 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "invalid buffer"); | |
piman
2013/03/28 20:22:27
GetBoundPixelUnpackTransferBufferIfValid already s
hubbe
2013/03/28 20:52:35
Done.
| |
1604 } | |
1561 return; | 1605 return; |
1562 } | 1606 } |
1563 | 1607 |
1564 // If there's no data just issue TexImage2D | 1608 // If there's no data just issue TexImage2D |
1565 if (!pixels) { | 1609 if (!pixels) { |
1566 helper_->TexImage2D( | 1610 helper_->TexImage2D( |
1567 target, level, internalformat, width, height, border, format, type, | 1611 target, level, internalformat, width, height, border, format, type, |
1568 0, 0); | 1612 0, 0); |
1569 CheckGLError(); | 1613 CheckGLError(); |
1570 return; | 1614 return; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1648 width, height, format, type, unpack_alignment_, &temp_size, | 1692 width, height, format, type, unpack_alignment_, &temp_size, |
1649 &unpadded_row_size, &padded_row_size)) { | 1693 &unpadded_row_size, &padded_row_size)) { |
1650 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); | 1694 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); |
1651 return; | 1695 return; |
1652 } | 1696 } |
1653 | 1697 |
1654 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | 1698 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
1655 if (bound_pixel_unpack_transfer_buffer_id_) { | 1699 if (bound_pixel_unpack_transfer_buffer_id_) { |
1656 GLuint offset = ToGLuint(pixels); | 1700 GLuint offset = ToGLuint(pixels); |
1657 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 1701 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
1702 bound_pixel_unpack_transfer_buffer_id_, | |
1658 "glTexSubImage2D", offset, temp_size); | 1703 "glTexSubImage2D", offset, temp_size); |
1659 if (buffer) | 1704 if (buffer) { |
1660 helper_->TexSubImage2D( | 1705 helper_->TexSubImage2D( |
1661 target, level, xoffset, yoffset, width, height, format, type, | 1706 target, level, xoffset, yoffset, width, height, format, type, |
1662 buffer->shm_id(), buffer->shm_offset() + offset, false); | 1707 buffer->shm_id(), buffer->shm_offset() + offset, false); |
1663 CheckGLError(); | 1708 buffer->set_transfer_ready_token(helper_->InsertToken()); |
1709 CheckGLError(); | |
1710 } else { | |
1711 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "invalid buffer"); | |
piman
2013/03/28 20:22:27
GetBoundPixelUnpackTransferBufferIfValid already s
hubbe
2013/03/28 20:52:35
Done.
| |
1712 } | |
1664 return; | 1713 return; |
1665 } | 1714 } |
1666 | 1715 |
1667 // compute the advance bytes per row for the src pixels | 1716 // compute the advance bytes per row for the src pixels |
1668 uint32 src_padded_row_size; | 1717 uint32 src_padded_row_size; |
1669 if (unpack_row_length_ > 0) { | 1718 if (unpack_row_length_ > 0) { |
1670 if (!GLES2Util::ComputeImagePaddedRowSize( | 1719 if (!GLES2Util::ComputeImagePaddedRowSize( |
1671 unpack_row_length_, format, type, unpack_alignment_, | 1720 unpack_row_length_, format, type, unpack_alignment_, |
1672 &src_padded_row_size)) { | 1721 &src_padded_row_size)) { |
1673 SetGLError( | 1722 SetGLError( |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2096 int8* dest = reinterpret_cast<int8*>(pixels); | 2145 int8* dest = reinterpret_cast<int8*>(pixels); |
2097 uint32 temp_size; | 2146 uint32 temp_size; |
2098 uint32 unpadded_row_size; | 2147 uint32 unpadded_row_size; |
2099 uint32 padded_row_size; | 2148 uint32 padded_row_size; |
2100 if (!GLES2Util::ComputeImageDataSizes( | 2149 if (!GLES2Util::ComputeImageDataSizes( |
2101 width, 2, format, type, pack_alignment_, &temp_size, &unpadded_row_size, | 2150 width, 2, format, type, pack_alignment_, &temp_size, &unpadded_row_size, |
2102 &padded_row_size)) { | 2151 &padded_row_size)) { |
2103 SetGLError(GL_INVALID_VALUE, "glReadPixels", "size too large."); | 2152 SetGLError(GL_INVALID_VALUE, "glReadPixels", "size too large."); |
2104 return; | 2153 return; |
2105 } | 2154 } |
2155 | |
2156 if (bound_pixel_pack_transfer_buffer_id_) { | |
2157 GLuint offset = ToGLuint(pixels); | |
2158 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | |
2159 bound_pixel_pack_transfer_buffer_id_, | |
2160 "glReadPixels", offset, temp_size); | |
2161 if (buffer) { | |
2162 helper_->ReadPixels(xoffset, yoffset, width, height, format, type, | |
2163 buffer->shm_id(), buffer->shm_offset(), | |
2164 0, 0); | |
2165 buffer->set_transfer_ready_token(helper_->InsertToken()); | |
2166 CheckGLError(); | |
2167 } else { | |
2168 SetGLError(GL_INVALID_VALUE, "glReadPixels", "invalid readback buffer"); | |
piman
2013/03/28 20:22:27
GetBoundPixelUnpackTransferBufferIfValid already s
hubbe
2013/03/28 20:52:35
Done.
| |
2169 } | |
2170 return; | |
2171 } | |
2172 | |
2173 if (!pixels) { | |
2174 SetGLError(GL_INVALID_VALUE, "glReadPixels", "pixels = NULL"); | |
piman
2013/03/28 20:22:27
note: spec doesn't say that an error would be gene
hubbe
2013/03/28 20:52:35
Changed to GL_INVALID_OPERATION.
| |
2175 return; | |
2176 } | |
2177 | |
2106 // Transfer by rows. | 2178 // Transfer by rows. |
2107 // The max rows we can transfer. | 2179 // The max rows we can transfer. |
2108 while (height) { | 2180 while (height) { |
2109 GLsizei desired_size = padded_row_size * height - 1 + unpadded_row_size; | 2181 GLsizei desired_size = padded_row_size * height - 1 + unpadded_row_size; |
2110 ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_); | 2182 ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_); |
2111 if (!buffer.valid()) { | 2183 if (!buffer.valid()) { |
2112 return; | 2184 return; |
2113 } | 2185 } |
2114 GLint num_rows = ComputeNumRowsThatFitInBuffer( | 2186 GLint num_rows = ComputeNumRowsThatFitInBuffer( |
2115 padded_row_size, unpadded_row_size, buffer.size()); | 2187 padded_row_size, unpadded_row_size, buffer.size()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2213 switch (target) { | 2285 switch (target) { |
2214 case GL_ARRAY_BUFFER: | 2286 case GL_ARRAY_BUFFER: |
2215 if (bound_array_buffer_id_ != buffer) { | 2287 if (bound_array_buffer_id_ != buffer) { |
2216 bound_array_buffer_id_ = buffer; | 2288 bound_array_buffer_id_ = buffer; |
2217 changed = true; | 2289 changed = true; |
2218 } | 2290 } |
2219 break; | 2291 break; |
2220 case GL_ELEMENT_ARRAY_BUFFER: | 2292 case GL_ELEMENT_ARRAY_BUFFER: |
2221 changed = vertex_array_object_manager_->BindElementArray(buffer); | 2293 changed = vertex_array_object_manager_->BindElementArray(buffer); |
2222 break; | 2294 break; |
2295 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | |
2296 bound_pixel_pack_transfer_buffer_id_ = buffer; | |
2297 break; | |
2223 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | 2298 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
2224 bound_pixel_unpack_transfer_buffer_id_ = buffer; | 2299 bound_pixel_unpack_transfer_buffer_id_ = buffer; |
2225 break; | 2300 break; |
2226 default: | 2301 default: |
2227 changed = true; | 2302 changed = true; |
2228 break; | 2303 break; |
2229 } | 2304 } |
2230 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2305 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
2231 // used even though it's marked it as used here. | 2306 // used even though it's marked it as used here. |
2232 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2307 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); |
(...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3292 } | 3367 } |
3293 helper_->TraceEndCHROMIUM(); | 3368 helper_->TraceEndCHROMIUM(); |
3294 TRACE_EVENT_COPY_ASYNC_END0("gpu", current_trace_name_->c_str(), this); | 3369 TRACE_EVENT_COPY_ASYNC_END0("gpu", current_trace_name_->c_str(), this); |
3295 current_trace_name_.reset(); | 3370 current_trace_name_.reset(); |
3296 } | 3371 } |
3297 | 3372 |
3298 void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { | 3373 void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { |
3299 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3374 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
3300 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferCHROMIUM(" | 3375 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferCHROMIUM(" |
3301 << target << ", " << GLES2Util::GetStringEnum(access) << ")"); | 3376 << target << ", " << GLES2Util::GetStringEnum(access) << ")"); |
3302 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | 3377 switch (target) { |
3303 SetGLError( | 3378 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
3304 GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target"); | 3379 if (access != GL_READ_ONLY) { |
3305 return NULL; | 3380 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); |
3381 return NULL; | |
3382 } | |
3383 break; | |
3384 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | |
3385 if (access != GL_WRITE_ONLY) { | |
3386 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); | |
3387 return NULL; | |
3388 } | |
3389 break; | |
3390 default: | |
3391 SetGLError( | |
3392 GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target"); | |
3393 return NULL; | |
3306 } | 3394 } |
3307 if (access != GL_WRITE_ONLY) { | 3395 GLuint buffer_id; |
3308 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); | 3396 GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id); |
3309 return NULL; | 3397 if (!buffer_id) return NULL; |
piman
2013/03/28 20:22:27
nit: return on its own line
hubbe
2013/03/28 20:52:35
Done.
| |
3310 } | 3398 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
3311 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | |
3312 bound_pixel_unpack_transfer_buffer_id_); | |
3313 if (!buffer) { | 3399 if (!buffer) { |
3314 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); | 3400 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); |
3315 return NULL; | 3401 return NULL; |
3316 } | 3402 } |
3317 if (buffer->mapped()) { | 3403 if (buffer->mapped()) { |
3318 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); | 3404 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); |
3319 return NULL; | 3405 return NULL; |
3320 } | 3406 } |
3407 // Here we wait for previous transfer operations to be finished. | |
3408 // TODO(hubbe): AsyncTex(Sub)Image2dCHROMIUM does not currently work | |
3409 // with this method of synchronization. Until this is fixed, | |
3410 // MapBufferCHROMIUM will not block even if the transfer is not ready | |
3411 // for these calls. | |
3412 if (buffer->transfer_ready_token()) { | |
3413 helper_->WaitForToken(buffer->transfer_ready_token()); | |
3414 buffer->set_transfer_ready_token(0); | |
3415 } | |
3321 buffer->set_mapped(true); | 3416 buffer->set_mapped(true); |
3322 | 3417 |
3323 GPU_DCHECK(buffer->address()); | 3418 GPU_DCHECK(buffer->address()); |
3324 GPU_CLIENT_LOG(" returned " << buffer->address()); | 3419 GPU_CLIENT_LOG(" returned " << buffer->address()); |
3325 CheckGLError(); | 3420 CheckGLError(); |
3326 return buffer->address(); | 3421 return buffer->address(); |
3327 } | 3422 } |
3328 | 3423 |
3329 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { | 3424 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
3330 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3425 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
3331 GPU_CLIENT_LOG( | 3426 GPU_CLIENT_LOG( |
3332 "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); | 3427 "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); |
3333 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { | 3428 GLuint buffer_id; |
3429 if (!GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id)) { | |
3334 SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); | 3430 SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); |
3335 return false; | |
3336 } | 3431 } |
3337 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | 3432 if (!buffer_id) return false; |
piman
2013/03/28 20:22:27
nit: return on its own line
hubbe
2013/03/28 20:52:35
Done.
| |
3338 bound_pixel_unpack_transfer_buffer_id_); | 3433 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
3339 if (!buffer) { | 3434 if (!buffer) { |
3340 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); | 3435 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); |
3341 return false; | 3436 return false; |
3342 } | 3437 } |
3343 if (!buffer->mapped()) { | 3438 if (!buffer->mapped()) { |
3344 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); | 3439 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); |
3345 return false; | 3440 return false; |
3346 } | 3441 } |
3347 buffer->set_mapped(false); | 3442 buffer->set_mapped(false); |
3348 CheckGLError(); | 3443 CheckGLError(); |
(...skipping 29 matching lines...) Expand all Loading... | |
3378 | 3473 |
3379 // If there's no data/buffer just issue the AsyncTexImage2D | 3474 // If there's no data/buffer just issue the AsyncTexImage2D |
3380 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { | 3475 if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { |
3381 helper_->AsyncTexImage2DCHROMIUM( | 3476 helper_->AsyncTexImage2DCHROMIUM( |
3382 target, level, internalformat, width, height, border, format, type, | 3477 target, level, internalformat, width, height, border, format, type, |
3383 0, 0); | 3478 0, 0); |
3384 return; | 3479 return; |
3385 } | 3480 } |
3386 | 3481 |
3387 // Otherwise, async uploads require a transfer buffer to be bound. | 3482 // Otherwise, async uploads require a transfer buffer to be bound. |
3483 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use | |
3484 // the buffer before the transfer is finished. (Currently sunch | |
piman
2013/03/28 20:22:27
typo: sunch
hubbe
2013/03/28 20:52:35
Done.
| |
3485 // synchronization has to be handled manually.) | |
3388 GLuint offset = ToGLuint(pixels); | 3486 GLuint offset = ToGLuint(pixels); |
3389 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3487 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
3488 bound_pixel_unpack_transfer_buffer_id_, | |
3390 "glAsyncTexImage2DCHROMIUM", offset, size); | 3489 "glAsyncTexImage2DCHROMIUM", offset, size); |
3391 if (!buffer) | 3490 if (!buffer) |
3392 return; | 3491 return; |
3393 | 3492 |
3394 helper_->AsyncTexImage2DCHROMIUM( | 3493 helper_->AsyncTexImage2DCHROMIUM( |
3395 target, level, internalformat, width, height, border, format, type, | 3494 target, level, internalformat, width, height, border, format, type, |
3396 buffer->shm_id(), buffer->shm_offset() + offset); | 3495 buffer->shm_id(), buffer->shm_offset() + offset); |
3397 return; | 3496 return; |
3398 } | 3497 } |
3399 | 3498 |
(...skipping 20 matching lines...) Expand all Loading... | |
3420 uint32 padded_row_size; | 3519 uint32 padded_row_size; |
3421 if (!GLES2Util::ComputeImageDataSizes( | 3520 if (!GLES2Util::ComputeImageDataSizes( |
3422 width, height, format, type, unpack_alignment_, &size, | 3521 width, height, format, type, unpack_alignment_, &size, |
3423 &unpadded_row_size, &padded_row_size)) { | 3522 &unpadded_row_size, &padded_row_size)) { |
3424 SetGLError( | 3523 SetGLError( |
3425 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); | 3524 GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); |
3426 return; | 3525 return; |
3427 } | 3526 } |
3428 | 3527 |
3429 // Async uploads require a transfer buffer to be bound. | 3528 // Async uploads require a transfer buffer to be bound. |
3529 // TODO(hubbe): Make MapBufferCHROMIUM block if someone tries to re-use | |
3530 // the buffer before the transfer is finished. (Currently sunch | |
piman
2013/03/28 20:22:27
typo: sunch
hubbe
2013/03/28 20:52:35
Done.
| |
3531 // synchronization has to be handled manually.) | |
3430 GLuint offset = ToGLuint(pixels); | 3532 GLuint offset = ToGLuint(pixels); |
3431 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3533 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
3534 bound_pixel_unpack_transfer_buffer_id_, | |
3432 "glAsyncTexSubImage2DCHROMIUM", offset, size); | 3535 "glAsyncTexSubImage2DCHROMIUM", offset, size); |
3433 if (!buffer) | 3536 if (!buffer) |
3434 return; | 3537 return; |
3435 | 3538 |
3436 helper_->AsyncTexSubImage2DCHROMIUM( | 3539 helper_->AsyncTexSubImage2DCHROMIUM( |
3437 target, level, xoffset, yoffset, width, height, format, type, | 3540 target, level, xoffset, yoffset, width, height, format, type, |
3438 buffer->shm_id(), buffer->shm_offset() + offset); | 3541 buffer->shm_id(), buffer->shm_offset() + offset); |
3439 return; | 3542 return; |
3440 } | 3543 } |
3441 | 3544 |
(...skipping 11 matching lines...) Expand all Loading... | |
3453 return helper_->InsertSyncPointCHROMIUM(); | 3556 return helper_->InsertSyncPointCHROMIUM(); |
3454 } | 3557 } |
3455 | 3558 |
3456 // Include the auto-generated part of this file. We split this because it means | 3559 // Include the auto-generated part of this file. We split this because it means |
3457 // we can easily edit the non-auto generated parts right here in this file | 3560 // we can easily edit the non-auto generated parts right here in this file |
3458 // instead of having to edit some template or the code generator. | 3561 // instead of having to edit some template or the code generator. |
3459 #include "../client/gles2_implementation_impl_autogen.h" | 3562 #include "../client/gles2_implementation_impl_autogen.h" |
3460 | 3563 |
3461 } // namespace gles2 | 3564 } // namespace gles2 |
3462 } // namespace gpu | 3565 } // namespace gpu |
OLD | NEW |