Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: gpu/command_buffer/client/gles2_implementation.cc

Issue 12892005: Implement client side PBOs for glReadPixel (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more comments, GL_STREAM_READ added Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698