OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // A class to emulate GLES2 over command buffers. | 5 // A class to emulate GLES2 over command buffers. |
6 | 6 |
7 #include "../client/gles2_implementation.h" | 7 #include "../client/gles2_implementation.h" |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 unpack_flip_y_(false), | 391 unpack_flip_y_(false), |
392 unpack_row_length_(0), | 392 unpack_row_length_(0), |
393 unpack_skip_rows_(0), | 393 unpack_skip_rows_(0), |
394 unpack_skip_pixels_(0), | 394 unpack_skip_pixels_(0), |
395 pack_reverse_row_order_(false), | 395 pack_reverse_row_order_(false), |
396 active_texture_unit_(0), | 396 active_texture_unit_(0), |
397 bound_framebuffer_(0), | 397 bound_framebuffer_(0), |
398 bound_renderbuffer_(0), | 398 bound_renderbuffer_(0), |
399 bound_array_buffer_id_(0), | 399 bound_array_buffer_id_(0), |
400 bound_element_array_buffer_id_(0), | 400 bound_element_array_buffer_id_(0), |
401 bound_pixel_pack_transfer_buffer_id_(0), | |
402 bound_pixel_unpack_transfer_buffer_id_(0), | |
401 client_side_array_id_(0), | 403 client_side_array_id_(0), |
402 client_side_element_array_id_(0), | 404 client_side_element_array_id_(0), |
403 error_bits_(0), | 405 error_bits_(0), |
404 debug_(false), | 406 debug_(false), |
405 use_count_(0), | 407 use_count_(0), |
406 current_query_(NULL), | 408 current_query_(NULL), |
407 error_message_callback_(NULL) { | 409 error_message_callback_(NULL) { |
408 GPU_DCHECK(helper); | 410 GPU_DCHECK(helper); |
409 GPU_DCHECK(transfer_buffer); | 411 GPU_DCHECK(transfer_buffer); |
410 GPU_CLIENT_LOG_CODE_BLOCK({ | 412 GPU_CLIENT_LOG_CODE_BLOCK({ |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 | 463 |
462 util_.set_num_compressed_texture_formats( | 464 util_.set_num_compressed_texture_formats( |
463 gl_state_.int_state.num_compressed_texture_formats); | 465 gl_state_.int_state.num_compressed_texture_formats); |
464 util_.set_num_shader_binary_formats( | 466 util_.set_num_shader_binary_formats( |
465 gl_state_.int_state.num_shader_binary_formats); | 467 gl_state_.int_state.num_shader_binary_formats); |
466 | 468 |
467 texture_units_.reset( | 469 texture_units_.reset( |
468 new TextureUnit[gl_state_.int_state.max_combined_texture_image_units]); | 470 new TextureUnit[gl_state_.int_state.max_combined_texture_image_units]); |
469 | 471 |
470 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 472 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
473 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); | |
471 | 474 |
472 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 475 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
473 GetIdHandler(id_namespaces::kBuffers)->MakeIds( | 476 GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
474 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); | 477 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); |
475 | 478 |
476 client_side_buffer_helper_.reset(new ClientSideBufferHelper( | 479 client_side_buffer_helper_.reset(new ClientSideBufferHelper( |
477 gl_state_.int_state.max_vertex_attribs, | 480 gl_state_.int_state.max_vertex_attribs, |
478 reserved_ids_[0], | 481 reserved_ids_[0], |
479 reserved_ids_[1])); | 482 reserved_ids_[1])); |
480 #endif | 483 #endif |
481 | 484 |
482 return true; | 485 return true; |
483 } | 486 } |
484 | 487 |
485 GLES2Implementation::~GLES2Implementation() { | 488 GLES2Implementation::~GLES2Implementation() { |
486 // Make sure the queries are finished otherwise we'll delete the | 489 // Make sure the queries are finished otherwise we'll delete the |
487 // shared memory (mapped_memory_) which will free the memory used | 490 // shared memory (mapped_memory_) which will free the memory used |
488 // by the queries. The GPU process when validating that memory is still | 491 // by the queries. The GPU process when validating that memory is still |
489 // shared will fail and abort (ie, it will stop running). | 492 // shared will fail and abort (ie, it will stop running). |
490 Finish(); | 493 Finish(); |
491 query_tracker_.reset(); | 494 query_tracker_.reset(); |
495 buffer_tracker_.reset(); | |
492 | 496 |
493 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 497 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
494 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); | 498 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); |
495 #endif | 499 #endif |
496 // The share group needs to be able to use a command buffer to talk | 500 // The share group needs to be able to use a command buffer to talk |
497 // to service if it's destroyed so set one for it then release the reference. | 501 // to service if it's destroyed so set one for it then release the reference. |
498 // If it's destroyed it will use this GLES2Implemenation. | 502 // If it's destroyed it will use this GLES2Implemenation. |
499 share_group_->SetGLES2ImplementationForDestruction(this); | 503 share_group_->SetGLES2ImplementationForDestruction(this); |
500 share_group_ = NULL; | 504 share_group_ = NULL; |
501 // Make sure the commands make it the service. | 505 // Make sure the commands make it the service. |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
878 *params = bound_array_buffer_id_; | 882 *params = bound_array_buffer_id_; |
879 return true; | 883 return true; |
880 } | 884 } |
881 return false; | 885 return false; |
882 case GL_ELEMENT_ARRAY_BUFFER_BINDING: | 886 case GL_ELEMENT_ARRAY_BUFFER_BINDING: |
883 if (share_group_->bind_generates_resource()) { | 887 if (share_group_->bind_generates_resource()) { |
884 *params = bound_element_array_buffer_id_; | 888 *params = bound_element_array_buffer_id_; |
885 return true; | 889 return true; |
886 } | 890 } |
887 return false; | 891 return false; |
892 case GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM: | |
893 if (share_group_->bind_generates_resource()) { | |
894 *params = bound_pixel_pack_transfer_buffer_id_; | |
895 return true; | |
896 } | |
897 return false; | |
898 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: | |
899 if (share_group_->bind_generates_resource()) { | |
900 *params = bound_pixel_unpack_transfer_buffer_id_; | |
901 return true; | |
902 } | |
903 return false; | |
888 case GL_ACTIVE_TEXTURE: | 904 case GL_ACTIVE_TEXTURE: |
889 *params = active_texture_unit_ + GL_TEXTURE0; | 905 *params = active_texture_unit_ + GL_TEXTURE0; |
890 return true; | 906 return true; |
891 case GL_TEXTURE_BINDING_2D: | 907 case GL_TEXTURE_BINDING_2D: |
892 if (share_group_->bind_generates_resource()) { | 908 if (share_group_->bind_generates_resource()) { |
893 *params = texture_units_[active_texture_unit_].bound_texture_2d; | 909 *params = texture_units_[active_texture_unit_].bound_texture_2d; |
894 return true; | 910 return true; |
895 } | 911 } |
896 return false; | 912 return false; |
897 case GL_TEXTURE_BINDING_CUBE_MAP: | 913 case GL_TEXTURE_BINDING_CUBE_MAP: |
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1484 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { | 1500 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { |
1485 if (size == 0) { | 1501 if (size == 0) { |
1486 return; | 1502 return; |
1487 } | 1503 } |
1488 | 1504 |
1489 if (size < 0) { | 1505 if (size < 0) { |
1490 SetGLError(GL_INVALID_VALUE, "glBufferData: size < 0"); | 1506 SetGLError(GL_INVALID_VALUE, "glBufferData: size < 0"); |
1491 return; | 1507 return; |
1492 } | 1508 } |
1493 | 1509 |
1510 switch (target) { | |
1511 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | |
greggman
2012/05/24 20:56:00
style: case is indented from switch
| |
1512 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: { | |
1513 GLuint buffer_id = target != GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM ? | |
1514 bound_pixel_unpack_transfer_buffer_id_ : | |
1515 bound_pixel_pack_transfer_buffer_id_; | |
1516 if (!buffer_id) { | |
1517 SetGLError(GL_INVALID_VALUE, "glBufferData: unknown buffer"); | |
1518 return; | |
1519 } | |
1520 // Remove old buffer. | |
1521 buffer_tracker_->RemoveBuffer(buffer_id); | |
greggman
2012/05/24 20:56:00
Should this happen inside buffer_tracker as in som
reveman
2012/05/25 15:45:10
I agree. will fix this.
| |
1522 | |
1523 // Creat new buffer. | |
1524 BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer( | |
1525 buffer_id, size); | |
1526 GPU_DCHECK(buffer); | |
1527 if (data) | |
1528 memcpy(buffer->address(), data, size); | |
1529 helper_->BufferData( | |
1530 target, size, buffer->shm_id(), buffer->shm_offset(), usage); | |
1531 return; | |
1532 } break; | |
1533 } | |
1534 | |
1494 // If there is no data just send BufferData | 1535 // If there is no data just send BufferData |
1495 if (!data) { | 1536 if (!data) { |
1496 helper_->BufferData(target, size, 0, 0, usage); | 1537 helper_->BufferData(target, size, 0, 0, usage); |
1497 return; | 1538 return; |
1498 } | 1539 } |
1499 | 1540 |
1500 // See if we can send all at once. | 1541 // See if we can send all at once. |
1501 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); | 1542 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
1502 if (!buffer.valid()) { | 1543 if (!buffer.valid()) { |
1503 return; | 1544 return; |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1762 << static_cast<const void*>(pixels) << ")"); | 1803 << static_cast<const void*>(pixels) << ")"); |
1763 | 1804 |
1764 if (level < 0 || height < 0 || width < 0) { | 1805 if (level < 0 || height < 0 || width < 0) { |
1765 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D dimension < 0"); | 1806 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D dimension < 0"); |
1766 return; | 1807 return; |
1767 } | 1808 } |
1768 if (height == 0 || width == 0) { | 1809 if (height == 0 || width == 0) { |
1769 return; | 1810 return; |
1770 } | 1811 } |
1771 | 1812 |
1813 if (bound_pixel_unpack_transfer_buffer_id_) { | |
1814 helper_->TexSubImage2D( | |
1815 target, level, xoffset, yoffset, width, height, format, type, | |
1816 0, ToGLuint(pixels), false); | |
1817 return; | |
1818 } | |
1819 | |
1772 uint32 temp_size; | 1820 uint32 temp_size; |
1773 uint32 unpadded_row_size; | 1821 uint32 unpadded_row_size; |
1774 uint32 padded_row_size; | 1822 uint32 padded_row_size; |
1775 if (!GLES2Util::ComputeImageDataSizes( | 1823 if (!GLES2Util::ComputeImageDataSizes( |
1776 width, height, format, type, unpack_alignment_, &temp_size, | 1824 width, height, format, type, unpack_alignment_, &temp_size, |
1777 &unpadded_row_size, &padded_row_size)) { | 1825 &unpadded_row_size, &padded_row_size)) { |
1778 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); | 1826 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large"); |
1779 return; | 1827 return; |
1780 } | 1828 } |
1781 | 1829 |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2285 void GLES2Implementation::BindBufferHelper( | 2333 void GLES2Implementation::BindBufferHelper( |
2286 GLenum target, GLuint buffer) { | 2334 GLenum target, GLuint buffer) { |
2287 // TODO(gman): See note #1 above. | 2335 // TODO(gman): See note #1 above. |
2288 switch (target) { | 2336 switch (target) { |
2289 case GL_ARRAY_BUFFER: | 2337 case GL_ARRAY_BUFFER: |
2290 bound_array_buffer_id_ = buffer; | 2338 bound_array_buffer_id_ = buffer; |
2291 break; | 2339 break; |
2292 case GL_ELEMENT_ARRAY_BUFFER: | 2340 case GL_ELEMENT_ARRAY_BUFFER: |
2293 bound_element_array_buffer_id_ = buffer; | 2341 bound_element_array_buffer_id_ = buffer; |
2294 break; | 2342 break; |
2343 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: | |
2344 bound_pixel_pack_transfer_buffer_id_ = buffer; | |
2345 break; | |
2346 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | |
2347 bound_pixel_unpack_transfer_buffer_id_ = buffer; | |
2348 break; | |
2295 default: | 2349 default: |
2296 break; | 2350 break; |
2297 } | 2351 } |
2298 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2352 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
2299 // used even though it's marked it as used here. | 2353 // used even though it's marked it as used here. |
2300 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2354 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); |
2301 } | 2355 } |
2302 | 2356 |
2303 void GLES2Implementation::BindFramebufferHelper( | 2357 void GLES2Implementation::BindFramebufferHelper( |
2304 GLenum target, GLuint framebuffer) { | 2358 GLenum target, GLuint framebuffer) { |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2636 // NOTE: target is NOT checked because the service will check it | 2690 // NOTE: target is NOT checked because the service will check it |
2637 // and we don't know what targets are valid. | 2691 // and we don't know what targets are valid. |
2638 if (access != GL_WRITE_ONLY) { | 2692 if (access != GL_WRITE_ONLY) { |
2639 SetGLError(GL_INVALID_ENUM, "MapBufferSubDataCHROMIUM: bad access mode"); | 2693 SetGLError(GL_INVALID_ENUM, "MapBufferSubDataCHROMIUM: bad access mode"); |
2640 return NULL; | 2694 return NULL; |
2641 } | 2695 } |
2642 if (offset < 0 || size < 0) { | 2696 if (offset < 0 || size < 0) { |
2643 SetGLError(GL_INVALID_VALUE, "MapBufferSubDataCHROMIUM: bad range"); | 2697 SetGLError(GL_INVALID_VALUE, "MapBufferSubDataCHROMIUM: bad range"); |
2644 return NULL; | 2698 return NULL; |
2645 } | 2699 } |
2646 int32 shm_id; | 2700 int32 shm_id = 0; |
2647 unsigned int shm_offset; | 2701 unsigned int shm_offset = 0; |
2648 void* mem = mapped_memory_->Alloc(size, &shm_id, &shm_offset); | 2702 void* mem = 0; |
2649 if (!mem) { | 2703 switch (target) { |
2650 SetGLError(GL_OUT_OF_MEMORY, "MapBufferSubDataCHROMIUM: out of memory"); | 2704 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
greggman
2012/05/24 20:56:00
style: indent
| |
2651 return NULL; | 2705 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: { |
2706 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( | |
2707 target == GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM ? | |
2708 bound_pixel_pack_transfer_buffer_id_ : | |
2709 bound_pixel_unpack_transfer_buffer_id_); | |
2710 if (!buffer) { | |
2711 SetGLError(GL_INVALID_VALUE, "MapBufferSubDataCHROMIUM: invalid buffer"); | |
2712 return NULL; | |
2713 } | |
2714 mem = static_cast<uint8*>(buffer->address()) + offset; | |
2715 } break; | |
greggman
2012/05/24 20:56:00
style: breaks go inside case blocks
greggman
2012/05/24 20:56:00
style: break goes inside case block
| |
2716 default: | |
2717 mem = mapped_memory_->Alloc(size, &shm_id, &shm_offset); | |
2718 if (!mem) { | |
2719 SetGLError(GL_OUT_OF_MEMORY, "MapBufferSubDataCHROMIUM: out of memory"); | |
2720 return NULL; | |
2721 } | |
2722 break; | |
2652 } | 2723 } |
2653 | 2724 |
2654 std::pair<MappedBufferMap::iterator, bool> result = | 2725 std::pair<MappedBufferMap::iterator, bool> result = |
2655 mapped_buffers_.insert(std::make_pair( | 2726 mapped_buffers_.insert(std::make_pair( |
2656 mem, | 2727 mem, |
2657 MappedBuffer( | 2728 MappedBuffer( |
2658 access, shm_id, mem, shm_offset, target, offset, size))); | 2729 access, shm_id, mem, shm_offset, target, offset, size))); |
2659 GPU_DCHECK(result.second); | 2730 GPU_DCHECK(result.second); |
2660 GPU_CLIENT_LOG(" returned " << mem); | 2731 GPU_CLIENT_LOG(" returned " << mem); |
2661 return mem; | 2732 return mem; |
2662 } | 2733 } |
2663 | 2734 |
2664 void GLES2Implementation::UnmapBufferSubDataCHROMIUM(const void* mem) { | 2735 void GLES2Implementation::UnmapBufferSubDataCHROMIUM(const void* mem) { |
2665 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2736 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
2666 GPU_CLIENT_LOG( | 2737 GPU_CLIENT_LOG( |
2667 "[" << this << "] glUnmapBufferSubDataCHROMIUM(" << mem << ")"); | 2738 "[" << this << "] glUnmapBufferSubDataCHROMIUM(" << mem << ")"); |
2668 MappedBufferMap::iterator it = mapped_buffers_.find(mem); | 2739 MappedBufferMap::iterator it = mapped_buffers_.find(mem); |
2669 if (it == mapped_buffers_.end()) { | 2740 if (it == mapped_buffers_.end()) { |
2670 SetGLError( | 2741 SetGLError( |
2671 GL_INVALID_VALUE, "UnmapBufferSubDataCHROMIUM: buffer not mapped"); | 2742 GL_INVALID_VALUE, "UnmapBufferSubDataCHROMIUM: buffer not mapped"); |
2672 return; | 2743 return; |
2673 } | 2744 } |
2674 const MappedBuffer& mb = it->second; | 2745 const MappedBuffer& mb = it->second; |
2675 helper_->BufferSubData( | 2746 switch (mb.target) { |
2676 mb.target, mb.offset, mb.size, mb.shm_id, mb.shm_offset); | 2747 case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
greggman
2012/05/24 20:56:00
indent
| |
2677 mapped_memory_->FreePendingToken(mb.shm_memory, helper_->InsertToken()); | 2748 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
2678 // Flushing after unmap lets the service side start processing commands | 2749 break; |
2679 // sooner. However, on lowend devices, the thread thrashing causes is | 2750 default: |
2680 // worse than the latency hit. | 2751 helper_->BufferSubData( |
2752 mb.target, mb.offset, mb.size, mb.shm_id, mb.shm_offset); | |
2753 mapped_memory_->FreePendingToken(mb.shm_memory, helper_->InsertToken()); | |
2754 // Flushing after unmap lets the service side start processing commands | |
2755 // sooner. However, on lowend devices, the thread thrashing causes is | |
2756 // worse than the latency hit. | |
2681 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) | 2757 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) |
2682 helper_->CommandBufferHelper::Flush(); | 2758 helper_->CommandBufferHelper::Flush(); |
2683 #endif | 2759 #endif |
2760 break; | |
2761 } | |
2684 mapped_buffers_.erase(it); | 2762 mapped_buffers_.erase(it); |
greggman
2012/05/24 20:56:00
I'm not sure why you'd erase the buffer here but t
| |
2685 } | 2763 } |
2686 | 2764 |
2687 void* GLES2Implementation::MapTexSubImage2DCHROMIUM( | 2765 void* GLES2Implementation::MapTexSubImage2DCHROMIUM( |
2688 GLenum target, | 2766 GLenum target, |
2689 GLint level, | 2767 GLint level, |
2690 GLint xoffset, | 2768 GLint xoffset, |
2691 GLint yoffset, | 2769 GLint yoffset, |
2692 GLsizei width, | 2770 GLsizei width, |
2693 GLsizei height, | 2771 GLsizei height, |
2694 GLenum format, | 2772 GLenum format, |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3257 helper_->GenMailboxCHROMIUM(kResultBucketId); | 3335 helper_->GenMailboxCHROMIUM(kResultBucketId); |
3258 | 3336 |
3259 std::vector<GLbyte> result; | 3337 std::vector<GLbyte> result; |
3260 GetBucketContents(kResultBucketId, &result); | 3338 GetBucketContents(kResultBucketId, &result); |
3261 | 3339 |
3262 std::copy(result.begin(), result.end(), mailbox); | 3340 std::copy(result.begin(), result.end(), mailbox); |
3263 } | 3341 } |
3264 | 3342 |
3265 } // namespace gles2 | 3343 } // namespace gles2 |
3266 } // namespace gpu | 3344 } // namespace gpu |
OLD | NEW |