| 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 |