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 "gpu/command_buffer/client/gles2_implementation.h" | 7 #include "gpu/command_buffer/client/gles2_implementation.h" |
8 | 8 |
9 #include <GLES2/gl2ext.h> | 9 #include <GLES2/gl2ext.h> |
10 #include <GLES2/gl2extchromium.h> | 10 #include <GLES2/gl2extchromium.h> |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 // shared will fail and abort (ie, it will stop running). | 215 // shared will fail and abort (ie, it will stop running). |
216 WaitForCmd(); | 216 WaitForCmd(); |
217 query_tracker_.reset(); | 217 query_tracker_.reset(); |
218 | 218 |
219 // GLES2Implementation::Initialize() could fail before allocating | 219 // GLES2Implementation::Initialize() could fail before allocating |
220 // reserved_ids_, so we need delete them carefully. | 220 // reserved_ids_, so we need delete them carefully. |
221 if (support_client_side_arrays_ && reserved_ids_[0]) { | 221 if (support_client_side_arrays_ && reserved_ids_[0]) { |
222 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); | 222 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); |
223 } | 223 } |
224 | 224 |
| 225 // Release remaining BufferRange mem; This is when a MapBufferRange() is |
| 226 // called but not the UnmapBuffer() pair. |
| 227 ClearMappedBufferRangeMap(); |
| 228 |
225 // Release any per-context data in share group. | 229 // Release any per-context data in share group. |
226 share_group_->FreeContext(this); | 230 share_group_->FreeContext(this); |
227 | 231 |
228 buffer_tracker_.reset(); | 232 buffer_tracker_.reset(); |
229 | 233 |
230 FreeAllAsyncUploadBuffers(); | 234 FreeAllAsyncUploadBuffers(); |
231 | 235 |
232 if (async_upload_sync_) { | 236 if (async_upload_sync_) { |
233 mapped_memory_->Free(async_upload_sync_); | 237 mapped_memory_->Free(async_upload_sync_); |
234 async_upload_sync_ = NULL; | 238 async_upload_sync_ = NULL; |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 WaitForCmd(); | 602 WaitForCmd(); |
599 state = (*result) != 0; | 603 state = (*result) != 0; |
600 } | 604 } |
601 | 605 |
602 GPU_CLIENT_LOG("returned " << state); | 606 GPU_CLIENT_LOG("returned " << state); |
603 CheckGLError(); | 607 CheckGLError(); |
604 return state; | 608 return state; |
605 } | 609 } |
606 | 610 |
607 bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { | 611 bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { |
| 612 // TODO(zmo): For all the BINDING points, there is a possibility where |
| 613 // resources are shared among multiple contexts, that the cached points |
| 614 // are invalid. It is not a problem for now, but once we allow resource |
| 615 // sharing in WebGL, we need to implement a mechanism to allow correct |
| 616 // client side binding points tracking. crbug.com/465562. |
608 switch (pname) { | 617 switch (pname) { |
609 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: | 618 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: |
610 *params = capabilities_.max_combined_texture_image_units; | 619 *params = capabilities_.max_combined_texture_image_units; |
611 return true; | 620 return true; |
612 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: | 621 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: |
613 *params = capabilities_.max_cube_map_texture_size; | 622 *params = capabilities_.max_cube_map_texture_size; |
614 return true; | 623 return true; |
615 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: | 624 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: |
616 *params = capabilities_.max_fragment_uniform_vectors; | 625 *params = capabilities_.max_fragment_uniform_vectors; |
617 return true; | 626 return true; |
(...skipping 18 matching lines...) Expand all Loading... |
636 case GL_MAX_VERTEX_UNIFORM_VECTORS: | 645 case GL_MAX_VERTEX_UNIFORM_VECTORS: |
637 *params = capabilities_.max_vertex_uniform_vectors; | 646 *params = capabilities_.max_vertex_uniform_vectors; |
638 return true; | 647 return true; |
639 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: | 648 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: |
640 *params = capabilities_.num_compressed_texture_formats; | 649 *params = capabilities_.num_compressed_texture_formats; |
641 return true; | 650 return true; |
642 case GL_NUM_SHADER_BINARY_FORMATS: | 651 case GL_NUM_SHADER_BINARY_FORMATS: |
643 *params = capabilities_.num_shader_binary_formats; | 652 *params = capabilities_.num_shader_binary_formats; |
644 return true; | 653 return true; |
645 case GL_ARRAY_BUFFER_BINDING: | 654 case GL_ARRAY_BUFFER_BINDING: |
646 if (share_group_->bind_generates_resource()) { | 655 *params = bound_array_buffer_id_; |
647 *params = bound_array_buffer_id_; | 656 return true; |
648 return true; | |
649 } | |
650 return false; | |
651 case GL_ELEMENT_ARRAY_BUFFER_BINDING: | 657 case GL_ELEMENT_ARRAY_BUFFER_BINDING: |
652 if (share_group_->bind_generates_resource()) { | 658 *params = |
653 *params = | 659 vertex_array_object_manager_->bound_element_array_buffer(); |
654 vertex_array_object_manager_->bound_element_array_buffer(); | 660 return true; |
655 return true; | |
656 } | |
657 return false; | |
658 case GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM: | 661 case GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
659 *params = bound_pixel_pack_transfer_buffer_id_; | 662 *params = bound_pixel_pack_transfer_buffer_id_; |
660 return true; | 663 return true; |
661 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: | 664 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
662 *params = bound_pixel_unpack_transfer_buffer_id_; | 665 *params = bound_pixel_unpack_transfer_buffer_id_; |
663 return true; | 666 return true; |
664 case GL_ACTIVE_TEXTURE: | 667 case GL_ACTIVE_TEXTURE: |
665 *params = active_texture_unit_ + GL_TEXTURE0; | 668 *params = active_texture_unit_ + GL_TEXTURE0; |
666 return true; | 669 return true; |
667 case GL_TEXTURE_BINDING_2D: | 670 case GL_TEXTURE_BINDING_2D: |
668 if (share_group_->bind_generates_resource()) { | 671 *params = texture_units_[active_texture_unit_].bound_texture_2d; |
669 *params = texture_units_[active_texture_unit_].bound_texture_2d; | 672 return true; |
670 return true; | |
671 } | |
672 return false; | |
673 case GL_TEXTURE_BINDING_CUBE_MAP: | 673 case GL_TEXTURE_BINDING_CUBE_MAP: |
674 if (share_group_->bind_generates_resource()) { | 674 *params = texture_units_[active_texture_unit_].bound_texture_cube_map; |
675 *params = texture_units_[active_texture_unit_].bound_texture_cube_map; | 675 return true; |
676 return true; | |
677 } | |
678 return false; | |
679 case GL_TEXTURE_BINDING_EXTERNAL_OES: | 676 case GL_TEXTURE_BINDING_EXTERNAL_OES: |
680 if (share_group_->bind_generates_resource()) { | 677 *params = |
681 *params = | 678 texture_units_[active_texture_unit_].bound_texture_external_oes; |
682 texture_units_[active_texture_unit_].bound_texture_external_oes; | 679 return true; |
683 return true; | |
684 } | |
685 return false; | |
686 case GL_FRAMEBUFFER_BINDING: | 680 case GL_FRAMEBUFFER_BINDING: |
687 if (share_group_->bind_generates_resource()) { | 681 *params = bound_framebuffer_; |
688 *params = bound_framebuffer_; | 682 return true; |
689 return true; | |
690 } | |
691 return false; | |
692 case GL_READ_FRAMEBUFFER_BINDING: | 683 case GL_READ_FRAMEBUFFER_BINDING: |
693 if (IsChromiumFramebufferMultisampleAvailable() && | 684 if (IsChromiumFramebufferMultisampleAvailable()) { |
694 share_group_->bind_generates_resource()) { | |
695 *params = bound_read_framebuffer_; | 685 *params = bound_read_framebuffer_; |
696 return true; | 686 return true; |
697 } | 687 } |
698 return false; | 688 return false; |
699 case GL_RENDERBUFFER_BINDING: | 689 case GL_RENDERBUFFER_BINDING: |
700 if (share_group_->bind_generates_resource()) { | 690 *params = bound_renderbuffer_; |
701 *params = bound_renderbuffer_; | 691 return true; |
702 return true; | |
703 } | |
704 return false; | |
705 case GL_MAX_UNIFORM_BUFFER_BINDINGS: | 692 case GL_MAX_UNIFORM_BUFFER_BINDINGS: |
706 *params = capabilities_.max_uniform_buffer_bindings; | 693 *params = capabilities_.max_uniform_buffer_bindings; |
707 return true; | 694 return true; |
708 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: | 695 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: |
709 *params = capabilities_.max_transform_feedback_separate_attribs; | 696 *params = capabilities_.max_transform_feedback_separate_attribs; |
710 return true; | 697 return true; |
711 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: | 698 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: |
712 *params = capabilities_.uniform_buffer_offset_alignment; | 699 *params = capabilities_.uniform_buffer_offset_alignment; |
713 return true; | 700 return true; |
| 701 // TODO(zmo): Support ES3 pnames. |
714 default: | 702 default: |
715 return false; | 703 return false; |
716 } | 704 } |
717 } | 705 } |
718 | 706 |
719 bool GLES2Implementation::GetBooleanvHelper(GLenum pname, GLboolean* params) { | 707 bool GLES2Implementation::GetBooleanvHelper(GLenum pname, GLboolean* params) { |
720 // TODO(gman): Make this handle pnames that return more than 1 value. | 708 // TODO(gman): Make this handle pnames that return more than 1 value. |
721 GLint value; | 709 GLint value; |
722 if (!GetHelper(pname, &value)) { | 710 if (!GetHelper(pname, &value)) { |
723 return false; | 711 return false; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 } | 809 } |
822 | 810 |
823 void GLES2Implementation::DrawElements( | 811 void GLES2Implementation::DrawElements( |
824 GLenum mode, GLsizei count, GLenum type, const void* indices) { | 812 GLenum mode, GLsizei count, GLenum type, const void* indices) { |
825 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 813 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
826 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements(" | 814 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements(" |
827 << GLES2Util::GetStringDrawMode(mode) << ", " | 815 << GLES2Util::GetStringDrawMode(mode) << ", " |
828 << count << ", " | 816 << count << ", " |
829 << GLES2Util::GetStringIndexType(type) << ", " | 817 << GLES2Util::GetStringIndexType(type) << ", " |
830 << static_cast<const void*>(indices) << ")"); | 818 << static_cast<const void*>(indices) << ")"); |
831 if (count < 0) { | 819 DrawElementsImpl(mode, count, type, indices, "glDrawRangeElements"); |
832 SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0."); | 820 } |
| 821 |
| 822 void GLES2Implementation::DrawRangeElements( |
| 823 GLenum mode, GLuint start, GLuint end, |
| 824 GLsizei count, GLenum type, const void* indices) { |
| 825 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 826 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawRangeElements(" |
| 827 << GLES2Util::GetStringDrawMode(mode) << ", " |
| 828 << start << ", " << end << ", " << count << ", " |
| 829 << GLES2Util::GetStringIndexType(type) << ", " |
| 830 << static_cast<const void*>(indices) << ")"); |
| 831 if (end < start) { |
| 832 SetGLError(GL_INVALID_VALUE, "glDrawRangeElements", "end < start"); |
833 return; | 833 return; |
834 } | 834 } |
835 if (count == 0) { | 835 DrawElementsImpl(mode, count, type, indices, "glDrawRangeElements"); |
| 836 } |
| 837 |
| 838 void GLES2Implementation::DrawElementsImpl( |
| 839 GLenum mode, GLsizei count, GLenum type, const void* indices, |
| 840 const char* func_name) { |
| 841 if (count < 0) { |
| 842 SetGLError(GL_INVALID_VALUE, func_name, "count < 0"); |
836 return; | 843 return; |
837 } | 844 } |
838 if (vertex_array_object_manager_->bound_element_array_buffer() != 0 && | |
839 !ValidateOffset("glDrawElements", reinterpret_cast<GLintptr>(indices))) { | |
840 return; | |
841 } | |
842 GLuint offset = 0; | |
843 bool simulated = false; | 845 bool simulated = false; |
844 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers( | 846 GLuint offset = ToGLuint(indices); |
845 "glDrawElements", this, helper_, count, type, 0, indices, | 847 if (count > 0) { |
846 &offset, &simulated)) { | 848 if (vertex_array_object_manager_->bound_element_array_buffer() != 0 && |
847 return; | 849 !ValidateOffset(func_name, reinterpret_cast<GLintptr>(indices))) { |
| 850 return; |
| 851 } |
| 852 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers( |
| 853 func_name, this, helper_, count, type, 0, indices, |
| 854 &offset, &simulated)) { |
| 855 return; |
| 856 } |
848 } | 857 } |
849 helper_->DrawElements(mode, count, type, offset); | 858 helper_->DrawElements(mode, count, type, offset); |
850 RestoreElementAndArrayBuffers(simulated); | 859 RestoreElementAndArrayBuffers(simulated); |
851 CheckGLError(); | 860 CheckGLError(); |
852 } | 861 } |
853 | 862 |
854 void GLES2Implementation::Flush() { | 863 void GLES2Implementation::Flush() { |
855 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 864 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
856 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()"); | 865 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()"); |
857 // Insert the cmd to call glFlush | 866 // Insert the cmd to call glFlush |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1377 RemoveTransferBuffer(buffer); | 1386 RemoveTransferBuffer(buffer); |
1378 | 1387 |
1379 // Create new buffer. | 1388 // Create new buffer. |
1380 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); | 1389 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); |
1381 DCHECK(buffer); | 1390 DCHECK(buffer); |
1382 if (buffer->address() && data) | 1391 if (buffer->address() && data) |
1383 memcpy(buffer->address(), data, size); | 1392 memcpy(buffer->address(), data, size); |
1384 return; | 1393 return; |
1385 } | 1394 } |
1386 | 1395 |
1387 if (size == 0) { | 1396 RemoveMappedBufferRangeByTarget(target); |
1388 return; | |
1389 } | |
1390 | 1397 |
1391 // If there is no data just send BufferData | 1398 // If there is no data just send BufferData |
1392 if (!data) { | 1399 if (size == 0 || !data) { |
1393 helper_->BufferData(target, size, 0, 0, usage); | 1400 helper_->BufferData(target, size, 0, 0, usage); |
1394 return; | 1401 return; |
1395 } | 1402 } |
1396 | 1403 |
1397 // See if we can send all at once. | 1404 // See if we can send all at once. |
1398 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); | 1405 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
1399 if (!buffer.valid()) { | 1406 if (!buffer.valid()) { |
1400 return; | 1407 return; |
1401 } | 1408 } |
1402 | 1409 |
(...skipping 1881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3284 } | 3291 } |
3285 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); | 3292 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); |
3286 | 3293 |
3287 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); | 3294 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
3288 if (buffer) | 3295 if (buffer) |
3289 RemoveTransferBuffer(buffer); | 3296 RemoveTransferBuffer(buffer); |
3290 | 3297 |
3291 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { | 3298 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
3292 bound_pixel_unpack_transfer_buffer_id_ = 0; | 3299 bound_pixel_unpack_transfer_buffer_id_ = 0; |
3293 } | 3300 } |
| 3301 |
| 3302 RemoveMappedBufferRangeById(buffers[ii]); |
3294 } | 3303 } |
3295 } | 3304 } |
3296 | 3305 |
3297 void GLES2Implementation::DeleteBuffersStub( | 3306 void GLES2Implementation::DeleteBuffersStub( |
3298 GLsizei n, const GLuint* buffers) { | 3307 GLsizei n, const GLuint* buffers) { |
3299 helper_->DeleteBuffersImmediate(n, buffers); | 3308 helper_->DeleteBuffersImmediate(n, buffers); |
3300 } | 3309 } |
3301 | 3310 |
3302 | 3311 |
3303 void GLES2Implementation::DeleteFramebuffersHelper( | 3312 void GLES2Implementation::DeleteFramebuffersHelper( |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3665 return; | 3674 return; |
3666 } | 3675 } |
3667 const MappedBuffer& mb = it->second; | 3676 const MappedBuffer& mb = it->second; |
3668 helper_->BufferSubData( | 3677 helper_->BufferSubData( |
3669 mb.target, mb.offset, mb.size, mb.shm_id, mb.shm_offset); | 3678 mb.target, mb.offset, mb.size, mb.shm_id, mb.shm_offset); |
3670 mapped_memory_->FreePendingToken(mb.shm_memory, helper_->InsertToken()); | 3679 mapped_memory_->FreePendingToken(mb.shm_memory, helper_->InsertToken()); |
3671 mapped_buffers_.erase(it); | 3680 mapped_buffers_.erase(it); |
3672 CheckGLError(); | 3681 CheckGLError(); |
3673 } | 3682 } |
3674 | 3683 |
| 3684 GLuint GLES2Implementation::GetBoundBufferHelper(GLenum target) { |
| 3685 GLenum binding = GLES2Util::MapBufferTargetToBindingEnum(target); |
| 3686 GLint id = 0; |
| 3687 bool cached = GetHelper(binding, &id); |
| 3688 DCHECK(cached); |
| 3689 return static_cast<GLuint>(id); |
| 3690 } |
| 3691 |
| 3692 void GLES2Implementation::RemoveMappedBufferRangeByTarget(GLenum target) { |
| 3693 GLuint buffer = GetBoundBufferHelper(target); |
| 3694 RemoveMappedBufferRangeById(buffer); |
| 3695 } |
| 3696 |
| 3697 void GLES2Implementation::RemoveMappedBufferRangeById(GLuint buffer) { |
| 3698 if (buffer > 0) { |
| 3699 auto iter = mapped_buffer_range_map_.find(buffer); |
| 3700 if (iter != mapped_buffer_range_map_.end() && iter->second.shm_memory) { |
| 3701 mapped_memory_->FreePendingToken( |
| 3702 iter->second.shm_memory, helper_->InsertToken()); |
| 3703 mapped_buffer_range_map_.erase(iter); |
| 3704 } |
| 3705 } |
| 3706 } |
| 3707 |
| 3708 void GLES2Implementation::ClearMappedBufferRangeMap() { |
| 3709 for (auto& buffer_range : mapped_buffer_range_map_) { |
| 3710 if (buffer_range.second.shm_memory) { |
| 3711 mapped_memory_->FreePendingToken( |
| 3712 buffer_range.second.shm_memory, helper_->InsertToken()); |
| 3713 } |
| 3714 } |
| 3715 mapped_buffer_range_map_.clear(); |
| 3716 } |
| 3717 |
| 3718 void* GLES2Implementation::MapBufferRange( |
| 3719 GLenum target, GLintptr offset, GLsizeiptr size, GLbitfield access) { |
| 3720 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3721 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferRange(" |
| 3722 << GLES2Util::GetStringEnum(target) << ", " << offset << ", " |
| 3723 << size << ", " << access << ")"); |
| 3724 if (!ValidateSize("glMapBufferRange", size) || |
| 3725 !ValidateOffset("glMapBufferRange", offset)) { |
| 3726 return nullptr; |
| 3727 } |
| 3728 |
| 3729 int32 shm_id; |
| 3730 unsigned int shm_offset; |
| 3731 void* mem = mapped_memory_->Alloc(size, &shm_id, &shm_offset); |
| 3732 if (!mem) { |
| 3733 SetGLError(GL_OUT_OF_MEMORY, "glMapBufferRange", "out of memory"); |
| 3734 return nullptr; |
| 3735 } |
| 3736 |
| 3737 typedef cmds::MapBufferRange::Result Result; |
| 3738 Result* result = GetResultAs<Result*>(); |
| 3739 *result = 0; |
| 3740 helper_->MapBufferRange(target, offset, size, access, shm_id, shm_offset, |
| 3741 GetResultShmId(), GetResultShmOffset()); |
| 3742 // TODO(zmo): For write only mode with MAP_INVALID_*_BIT, we should |
| 3743 // consider an early return without WaitForCmd(). crbug.com/465804. |
| 3744 WaitForCmd(); |
| 3745 if (*result) { |
| 3746 const GLbitfield kInvalidateBits = |
| 3747 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT; |
| 3748 if ((access & kInvalidateBits) != 0) { |
| 3749 // We do not read back from the buffer, therefore, we set the client |
| 3750 // side memory to zero to avoid uninitialized data. |
| 3751 memset(mem, 0, size); |
| 3752 } |
| 3753 GLuint buffer = GetBoundBufferHelper(target); |
| 3754 DCHECK_NE(0u, buffer); |
| 3755 // glMapBufferRange fails on an already mapped buffer. |
| 3756 DCHECK(mapped_buffer_range_map_.find(buffer) == |
| 3757 mapped_buffer_range_map_.end()); |
| 3758 auto iter = mapped_buffer_range_map_.insert(std::make_pair( |
| 3759 buffer, |
| 3760 MappedBuffer(access, shm_id, mem, shm_offset, target, offset, size))); |
| 3761 DCHECK(iter.second); |
| 3762 } else { |
| 3763 mapped_memory_->Free(mem); |
| 3764 mem = nullptr; |
| 3765 } |
| 3766 |
| 3767 GPU_CLIENT_LOG(" returned " << mem); |
| 3768 CheckGLError(); |
| 3769 return mem; |
| 3770 } |
| 3771 |
| 3772 GLboolean GLES2Implementation::UnmapBuffer(GLenum target) { |
| 3773 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3774 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUnmapBuffer(" |
| 3775 << GLES2Util::GetStringEnum(target) << ")"); |
| 3776 switch (target) { |
| 3777 case GL_ARRAY_BUFFER: |
| 3778 case GL_ELEMENT_ARRAY_BUFFER: |
| 3779 case GL_COPY_READ_BUFFER: |
| 3780 case GL_COPY_WRITE_BUFFER: |
| 3781 case GL_PIXEL_PACK_BUFFER: |
| 3782 case GL_PIXEL_UNPACK_BUFFER: |
| 3783 case GL_TRANSFORM_FEEDBACK_BUFFER: |
| 3784 case GL_UNIFORM_BUFFER: |
| 3785 break; |
| 3786 default: |
| 3787 SetGLError(GL_INVALID_ENUM, "glUnmapBuffer", "invalid target"); |
| 3788 return GL_FALSE; |
| 3789 } |
| 3790 GLuint buffer = GetBoundBufferHelper(target); |
| 3791 if (buffer == 0) { |
| 3792 SetGLError(GL_INVALID_OPERATION, "glUnmapBuffer", "no buffer bound"); |
| 3793 return GL_FALSE; |
| 3794 } |
| 3795 auto iter = mapped_buffer_range_map_.find(buffer); |
| 3796 if (iter == mapped_buffer_range_map_.end()) { |
| 3797 SetGLError(GL_INVALID_OPERATION, "glUnmapBuffer", "buffer is unmapped"); |
| 3798 return GL_FALSE; |
| 3799 } |
| 3800 |
| 3801 helper_->UnmapBuffer(target); |
| 3802 RemoveMappedBufferRangeById(buffer); |
| 3803 // TODO(zmo): There is a rare situation that data might be corrupted and |
| 3804 // GL_FALSE should be returned. We lose context on that sitatuon, so we |
| 3805 // don't have to WaitForCmd(). |
| 3806 GPU_CLIENT_LOG(" returned " << GL_TRUE); |
| 3807 CheckGLError(); |
| 3808 return GL_TRUE; |
| 3809 } |
| 3810 |
3675 void* GLES2Implementation::MapTexSubImage2DCHROMIUM( | 3811 void* GLES2Implementation::MapTexSubImage2DCHROMIUM( |
3676 GLenum target, | 3812 GLenum target, |
3677 GLint level, | 3813 GLint level, |
3678 GLint xoffset, | 3814 GLint xoffset, |
3679 GLint yoffset, | 3815 GLint yoffset, |
3680 GLsizei width, | 3816 GLsizei width, |
3681 GLsizei height, | 3817 GLsizei height, |
3682 GLenum format, | 3818 GLenum format, |
3683 GLenum type, | 3819 GLenum type, |
3684 GLenum access) { | 3820 GLenum access) { |
(...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4991 CheckGLError(); | 5127 CheckGLError(); |
4992 } | 5128 } |
4993 | 5129 |
4994 // Include the auto-generated part of this file. We split this because it means | 5130 // Include the auto-generated part of this file. We split this because it means |
4995 // we can easily edit the non-auto generated parts right here in this file | 5131 // we can easily edit the non-auto generated parts right here in this file |
4996 // instead of having to edit some template or the code generator. | 5132 // instead of having to edit some template or the code generator. |
4997 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 5133 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
4998 | 5134 |
4999 } // namespace gles2 | 5135 } // namespace gles2 |
5000 } // namespace gpu | 5136 } // namespace gpu |
OLD | NEW |