OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // A class to emulate GLES2 over command buffers. | 5 // A class to emulate GLES2 over command buffers. |
6 | 6 |
7 #include "../client/gles2_implementation.h" | 7 #include "../client/gles2_implementation.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
11 #include <queue> | 11 #include <queue> |
12 #include <set> | 12 #include <set> |
13 #include <limits> | 13 #include <limits> |
14 #include <stdio.h> | 14 #include <stdio.h> |
15 #include <string.h> | 15 #include <string.h> |
16 #include <GLES2/gl2ext.h> | 16 #include <GLES2/gl2ext.h> |
17 #include <GLES2/gl2extchromium.h> | 17 #include <GLES2/gl2extchromium.h> |
18 #include "../client/buffer_tracker.h" | 18 #include "../client/buffer_tracker.h" |
| 19 #include "../client/gpu_memory_buffer.h" |
| 20 #include "../client/gpu_memory_buffer_factory.h" |
| 21 #include "../client/gpu_memory_buffer_tracker.h" |
19 #include "../client/mapped_memory.h" | 22 #include "../client/mapped_memory.h" |
20 #include "../client/program_info_manager.h" | 23 #include "../client/program_info_manager.h" |
21 #include "../client/query_tracker.h" | 24 #include "../client/query_tracker.h" |
22 #include "../client/transfer_buffer.h" | 25 #include "../client/transfer_buffer.h" |
23 #include "../client/vertex_array_object_manager.h" | 26 #include "../client/vertex_array_object_manager.h" |
24 #include "../common/gles2_cmd_utils.h" | 27 #include "../common/gles2_cmd_utils.h" |
25 #include "../common/trace_event.h" | 28 #include "../common/trace_event.h" |
26 | 29 |
27 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 30 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
28 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS | 31 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 GLES2Implementation::SingleThreadChecker::~SingleThreadChecker() { | 80 GLES2Implementation::SingleThreadChecker::~SingleThreadChecker() { |
78 --gles2_implementation_->use_count_; | 81 --gles2_implementation_->use_count_; |
79 GPU_CHECK_EQ(0, gles2_implementation_->use_count_); | 82 GPU_CHECK_EQ(0, gles2_implementation_->use_count_); |
80 } | 83 } |
81 | 84 |
82 GLES2Implementation::GLES2Implementation( | 85 GLES2Implementation::GLES2Implementation( |
83 GLES2CmdHelper* helper, | 86 GLES2CmdHelper* helper, |
84 ShareGroup* share_group, | 87 ShareGroup* share_group, |
85 TransferBufferInterface* transfer_buffer, | 88 TransferBufferInterface* transfer_buffer, |
86 bool share_resources, | 89 bool share_resources, |
87 bool bind_generates_resource) | 90 bool bind_generates_resource, |
| 91 ImageFactory* image_factory) |
88 : helper_(helper), | 92 : helper_(helper), |
89 transfer_buffer_(transfer_buffer), | 93 transfer_buffer_(transfer_buffer), |
90 angle_pack_reverse_row_order_status_(kUnknownExtensionStatus), | 94 angle_pack_reverse_row_order_status_(kUnknownExtensionStatus), |
91 chromium_framebuffer_multisample_(kUnknownExtensionStatus), | 95 chromium_framebuffer_multisample_(kUnknownExtensionStatus), |
92 pack_alignment_(4), | 96 pack_alignment_(4), |
93 unpack_alignment_(4), | 97 unpack_alignment_(4), |
94 unpack_flip_y_(false), | 98 unpack_flip_y_(false), |
95 unpack_row_length_(0), | 99 unpack_row_length_(0), |
96 unpack_skip_rows_(0), | 100 unpack_skip_rows_(0), |
97 unpack_skip_pixels_(0), | 101 unpack_skip_pixels_(0), |
98 pack_reverse_row_order_(false), | 102 pack_reverse_row_order_(false), |
99 active_texture_unit_(0), | 103 active_texture_unit_(0), |
100 bound_framebuffer_(0), | 104 bound_framebuffer_(0), |
101 bound_read_framebuffer_(0), | 105 bound_read_framebuffer_(0), |
102 bound_renderbuffer_(0), | 106 bound_renderbuffer_(0), |
103 current_program_(0), | 107 current_program_(0), |
104 bound_array_buffer_id_(0), | 108 bound_array_buffer_id_(0), |
105 bound_pixel_pack_transfer_buffer_id_(0), | 109 bound_pixel_pack_transfer_buffer_id_(0), |
106 bound_pixel_unpack_transfer_buffer_id_(0), | 110 bound_pixel_unpack_transfer_buffer_id_(0), |
107 error_bits_(0), | 111 error_bits_(0), |
108 debug_(false), | 112 debug_(false), |
109 use_count_(0), | 113 use_count_(0), |
110 current_query_(NULL), | 114 current_query_(NULL), |
111 error_message_callback_(NULL) { | 115 error_message_callback_(NULL), |
| 116 image_factory_(image_factory) { |
112 GPU_DCHECK(helper); | 117 GPU_DCHECK(helper); |
113 GPU_DCHECK(transfer_buffer); | 118 GPU_DCHECK(transfer_buffer); |
114 | 119 |
115 char temp[128]; | 120 char temp[128]; |
116 sprintf(temp, "%p", static_cast<void*>(this)); | 121 sprintf(temp, "%p", static_cast<void*>(this)); |
117 this_in_hex_ = std::string(temp); | 122 this_in_hex_ = std::string(temp); |
118 | 123 |
119 GPU_CLIENT_LOG_CODE_BLOCK({ | 124 GPU_CLIENT_LOG_CODE_BLOCK({ |
120 debug_ = CommandLine::ForCurrentProcess()->HasSwitch( | 125 debug_ = CommandLine::ForCurrentProcess()->HasSwitch( |
121 switches::kEnableGPUClientLogging); | 126 switches::kEnableGPUClientLogging); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 static_state_.int_state.num_compressed_texture_formats); | 160 static_state_.int_state.num_compressed_texture_formats); |
156 util_.set_num_shader_binary_formats( | 161 util_.set_num_shader_binary_formats( |
157 static_state_.int_state.num_shader_binary_formats); | 162 static_state_.int_state.num_shader_binary_formats); |
158 | 163 |
159 texture_units_.reset( | 164 texture_units_.reset( |
160 new TextureUnit[ | 165 new TextureUnit[ |
161 static_state_.int_state.max_combined_texture_image_units]); | 166 static_state_.int_state.max_combined_texture_image_units]); |
162 | 167 |
163 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 168 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
164 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); | 169 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); |
| 170 gpu_memory_buffer_tracker_.reset(new GpuMemoryBufferTracker(image_factory_)); |
165 | 171 |
166 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 172 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
167 GetIdHandler(id_namespaces::kBuffers)->MakeIds( | 173 GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
168 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); | 174 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); |
169 #endif | 175 #endif |
170 | 176 |
171 vertex_array_object_manager_.reset(new VertexArrayObjectManager( | 177 vertex_array_object_manager_.reset(new VertexArrayObjectManager( |
172 static_state_.int_state.max_vertex_attribs, | 178 static_state_.int_state.max_vertex_attribs, |
173 reserved_ids_[0], | 179 reserved_ids_[0], |
174 reserved_ids_[1])); | 180 reserved_ids_[1])); |
(...skipping 1912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2087 std::string str; | 2093 std::string str; |
2088 if (GetBucketAsString(kResultBucketId, &str)) { | 2094 if (GetBucketAsString(kResultBucketId, &str)) { |
2089 // Adds extensions implemented on client side only. | 2095 // Adds extensions implemented on client side only. |
2090 switch (name) { | 2096 switch (name) { |
2091 case GL_EXTENSIONS: | 2097 case GL_EXTENSIONS: |
2092 str += std::string(str.empty() ? "" : " ") + | 2098 str += std::string(str.empty() ? "" : " ") + |
2093 "GL_CHROMIUM_flipy " | 2099 "GL_CHROMIUM_flipy " |
2094 "GL_CHROMIUM_map_sub " | 2100 "GL_CHROMIUM_map_sub " |
2095 "GL_CHROMIUM_shallow_flush " | 2101 "GL_CHROMIUM_shallow_flush " |
2096 "GL_EXT_unpack_subimage"; | 2102 "GL_EXT_unpack_subimage"; |
| 2103 if (image_factory_ != NULL) { |
| 2104 // The first space character is intentional. |
| 2105 str += " GL_CHROMIUM_map_image"; |
| 2106 } |
2097 break; | 2107 break; |
2098 default: | 2108 default: |
2099 break; | 2109 break; |
2100 } | 2110 } |
2101 | 2111 |
2102 // Because of WebGL the extensions can change. We have to cache each unique | 2112 // Because of WebGL the extensions can change. We have to cache each unique |
2103 // result since we don't know when the client will stop referring to a | 2113 // result since we don't know when the client will stop referring to a |
2104 // previous one it queries. | 2114 // previous one it queries. |
2105 GLStringMap::iterator it = gl_strings_.find(name); | 2115 GLStringMap::iterator it = gl_strings_.find(name); |
2106 if (it == gl_strings_.end()) { | 2116 if (it == gl_strings_.end()) { |
(...skipping 1453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3560 "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); | 3570 "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); |
3561 GLuint buffer_id; | 3571 GLuint buffer_id; |
3562 if (!GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id)) { | 3572 if (!GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id)) { |
3563 SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); | 3573 SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); |
3564 } | 3574 } |
3565 if (!buffer_id) { | 3575 if (!buffer_id) { |
3566 return false; | 3576 return false; |
3567 } | 3577 } |
3568 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | 3578 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
3569 if (!buffer) { | 3579 if (!buffer) { |
3570 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); | 3580 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "invalid buffer"); |
3571 return false; | 3581 return false; |
3572 } | 3582 } |
3573 if (!buffer->mapped()) { | 3583 if (!buffer->mapped()) { |
3574 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); | 3584 SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); |
3575 return false; | 3585 return false; |
3576 } | 3586 } |
3577 buffer->set_mapped(false); | 3587 buffer->set_mapped(false); |
3578 CheckGLError(); | 3588 CheckGLError(); |
3579 return true; | 3589 return true; |
3580 } | 3590 } |
3581 | 3591 |
3582 void GLES2Implementation::AsyncTexImage2DCHROMIUM( | 3592 void GLES2Implementation::AsyncTexImage2DCHROMIUM( |
3583 GLenum target, GLint level, GLint internalformat, GLsizei width, | 3593 GLenum target, GLint level, GLint internalformat, GLsizei width, |
3584 GLsizei height, GLint border, GLenum format, GLenum type, | 3594 GLsizei height, GLint border, GLenum format, GLenum type, |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3680 helper_->WaitAsyncTexImage2DCHROMIUM(target); | 3690 helper_->WaitAsyncTexImage2DCHROMIUM(target); |
3681 CheckGLError(); | 3691 CheckGLError(); |
3682 } | 3692 } |
3683 | 3693 |
3684 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { | 3694 GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { |
3685 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3695 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
3686 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM"); | 3696 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertSyncPointCHROMIUM"); |
3687 return helper_->InsertSyncPointCHROMIUM(); | 3697 return helper_->InsertSyncPointCHROMIUM(); |
3688 } | 3698 } |
3689 | 3699 |
| 3700 GLuint GLES2Implementation::CreateImageCHROMIUMHelper( |
| 3701 GLsizei width, GLsizei height, GLenum internalformat) { |
| 3702 if (width <= 0) { |
| 3703 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "width <= 0"); |
| 3704 return 0; |
| 3705 } |
| 3706 |
| 3707 if (height <= 0) { |
| 3708 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "height <= 0"); |
| 3709 return 0; |
| 3710 } |
| 3711 // Flush the command stream to ensure ordering in case the newly |
| 3712 // returned image_id has recently been in use with a different buffer. |
| 3713 helper_->CommandBufferHelper::Flush(); |
| 3714 |
| 3715 // Create new buffer. |
| 3716 return gpu_memory_buffer_tracker_->CreateBuffer( |
| 3717 width, height, internalformat); |
| 3718 } |
| 3719 |
| 3720 GLuint GLES2Implementation::CreateImageCHROMIUM( |
| 3721 GLsizei width, GLsizei height, GLenum internalformat) { |
| 3722 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3723 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateImageCHROMIUM(" |
| 3724 << width << ", " |
| 3725 << height << ", " |
| 3726 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ")"); |
| 3727 GLuint image_id = CreateImageCHROMIUMHelper(width, height, internalformat); |
| 3728 CheckGLError(); |
| 3729 return image_id; |
| 3730 } |
| 3731 |
| 3732 void GLES2Implementation::DestroyImageCHROMIUMHelper(GLuint image_id) { |
| 3733 GpuMemoryBuffer* gpu_buffer = |
| 3734 gpu_memory_buffer_tracker_->GetBuffer(image_id); |
| 3735 if (!gpu_buffer) { |
| 3736 SetGLError(GL_INVALID_OPERATION, "glDestroyImageCHROMIUM", |
| 3737 "invalid image"); |
| 3738 return; |
| 3739 } |
| 3740 |
| 3741 // Flush the command stream to make sure all pending commands |
| 3742 // that may refer to the image_id are executed on the service side. |
| 3743 helper_->CommandBufferHelper::Flush(); |
| 3744 gpu_memory_buffer_tracker_->RemoveBuffer(image_id); |
| 3745 } |
| 3746 |
| 3747 void GLES2Implementation::DestroyImageCHROMIUM(GLuint image_id) { |
| 3748 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3749 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDestroyImageCHROMIUM(" |
| 3750 << image_id << ")"); |
| 3751 DestroyImageCHROMIUMHelper(image_id); |
| 3752 CheckGLError(); |
| 3753 } |
| 3754 |
| 3755 void GLES2Implementation::UnmapImageCHROMIUMHelper(GLuint image_id) { |
| 3756 GpuMemoryBuffer* gpu_buffer = |
| 3757 gpu_memory_buffer_tracker_->GetBuffer(image_id); |
| 3758 if (!gpu_buffer) { |
| 3759 SetGLError(GL_INVALID_OPERATION, "glUnmapImageCHROMIUM", "invalid image"); |
| 3760 return; |
| 3761 } |
| 3762 |
| 3763 if (!gpu_buffer->IsMapped()) { |
| 3764 SetGLError(GL_INVALID_OPERATION, "glUnmapImageCHROMIUM", "not mapped"); |
| 3765 return; |
| 3766 } |
| 3767 gpu_buffer->Unmap(); |
| 3768 } |
| 3769 |
| 3770 void GLES2Implementation::UnmapImageCHROMIUM(GLuint image_id) { |
| 3771 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3772 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUnmapImageCHROMIUM(" |
| 3773 << image_id << ")"); |
| 3774 |
| 3775 UnmapImageCHROMIUMHelper(image_id); |
| 3776 CheckGLError(); |
| 3777 } |
| 3778 |
| 3779 void* GLES2Implementation::MapImageCHROMIUMHelper(GLuint image_id, |
| 3780 GLenum access) { |
| 3781 GpuMemoryBuffer* gpu_buffer = |
| 3782 gpu_memory_buffer_tracker_->GetBuffer(image_id); |
| 3783 if (!gpu_buffer) { |
| 3784 SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "invalid image"); |
| 3785 return NULL; |
| 3786 } |
| 3787 GpuMemoryBuffer::AccessMode mode; |
| 3788 switch(access) { |
| 3789 case GL_WRITE_ONLY: |
| 3790 mode = GpuMemoryBuffer::WRITE_ONLY; |
| 3791 break; |
| 3792 case GL_READ_ONLY: |
| 3793 mode = GpuMemoryBuffer::READ_ONLY; |
| 3794 break; |
| 3795 case GL_READ_WRITE: |
| 3796 mode = GpuMemoryBuffer::READ_WRITE; |
| 3797 break; |
| 3798 default: |
| 3799 SetGLError(GL_INVALID_ENUM, "glMapImageCHROMIUM", |
| 3800 "invalid GPU access mode"); |
| 3801 return NULL; |
| 3802 } |
| 3803 |
| 3804 if (gpu_buffer->IsMapped()) { |
| 3805 SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "already mapped"); |
| 3806 return NULL; |
| 3807 } |
| 3808 |
| 3809 void* mapped_buffer = NULL; |
| 3810 gpu_buffer->Map(mode, &mapped_buffer); |
| 3811 return mapped_buffer; |
| 3812 } |
| 3813 |
| 3814 void* GLES2Implementation::MapImageCHROMIUM( |
| 3815 GLuint image_id, GLenum access) { |
| 3816 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3817 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapImageCHROMIUM(" |
| 3818 << image_id << ", " |
| 3819 << GLES2Util::GetStringEnum(access) << ")"); |
| 3820 |
| 3821 void* mapped = MapImageCHROMIUMHelper(image_id, access); |
| 3822 CheckGLError(); |
| 3823 return mapped; |
| 3824 } |
| 3825 |
| 3826 void GLES2Implementation::GetImageParameterivCHROMIUMHelper( |
| 3827 GLuint image_id, GLenum pname, GLint* params) { |
| 3828 if (pname != GL_IMAGE_ROWBYTES_CHROMIUM) { |
| 3829 SetGLError(GL_INVALID_ENUM, "glGetImageParameterivCHROMIUM", |
| 3830 "invalid parameter"); |
| 3831 return; |
| 3832 } |
| 3833 |
| 3834 GpuMemoryBuffer* gpu_buffer = |
| 3835 gpu_memory_buffer_tracker_->GetBuffer(image_id); |
| 3836 if (!gpu_buffer) { |
| 3837 SetGLError(GL_INVALID_OPERATION, "glGetImageParameterivCHROMIUM", |
| 3838 "invalid image"); |
| 3839 return; |
| 3840 } |
| 3841 |
| 3842 *params = gpu_buffer->GetStride(); |
| 3843 } |
| 3844 |
| 3845 void GLES2Implementation::GetImageParameterivCHROMIUM( |
| 3846 GLuint image_id, GLenum pname, GLint* params) { |
| 3847 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3848 GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params); |
| 3849 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapImageCHROMIUM(" |
| 3850 << image_id << ", " |
| 3851 << GLES2Util::GetStringBufferParameter(pname) << ", " |
| 3852 << static_cast<const void*>(params) << ")"); |
| 3853 GetImageParameterivCHROMIUM(image_id, pname, params); |
| 3854 CheckGLError(); |
| 3855 } |
| 3856 |
3690 // Include the auto-generated part of this file. We split this because it means | 3857 // Include the auto-generated part of this file. We split this because it means |
3691 // we can easily edit the non-auto generated parts right here in this file | 3858 // we can easily edit the non-auto generated parts right here in this file |
3692 // instead of having to edit some template or the code generator. | 3859 // instead of having to edit some template or the code generator. |
3693 #include "../client/gles2_implementation_impl_autogen.h" | 3860 #include "../client/gles2_implementation_impl_autogen.h" |
3694 | 3861 |
3695 } // namespace gles2 | 3862 } // namespace gles2 |
3696 } // namespace gpu | 3863 } // namespace gpu |
OLD | NEW |