| 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> |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <limits> | 12 #include <limits> |
| 13 #include <map> | 13 #include <map> |
| 14 #include <queue> | 14 #include <queue> |
| 15 #include <set> | 15 #include <set> |
| 16 #include <sstream> | 16 #include <sstream> |
| 17 #include <string> | 17 #include <string> |
| 18 #include "base/bind.h" | 18 #include "base/bind.h" |
| 19 #include "gpu/command_buffer/client/buffer_tracker.h" | 19 #include "gpu/command_buffer/client/buffer_tracker.h" |
| 20 #include "gpu/command_buffer/client/gpu_control.h" | 20 #include "gpu/command_buffer/client/gpu_control.h" |
| 21 #include "gpu/command_buffer/client/program_info_manager.h" | 21 #include "gpu/command_buffer/client/program_info_manager.h" |
| 22 #include "gpu/command_buffer/client/query_tracker.h" | 22 #include "gpu/command_buffer/client/query_tracker.h" |
| 23 #include "gpu/command_buffer/client/transfer_buffer.h" | 23 #include "gpu/command_buffer/client/transfer_buffer.h" |
| 24 #include "gpu/command_buffer/client/vertex_array_object_manager.h" | 24 #include "gpu/command_buffer/client/vertex_array_object_manager.h" |
| 25 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 25 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 26 #include "gpu/command_buffer/common/trace_event.h" | 26 #include "gpu/command_buffer/common/trace_event.h" |
| 27 | 27 |
| 28 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 29 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS | |
| 30 #endif | |
| 31 | |
| 32 #if defined(GPU_CLIENT_DEBUG) | 28 #if defined(GPU_CLIENT_DEBUG) |
| 33 #include "base/command_line.h" | 29 #include "base/command_line.h" |
| 34 #include "gpu/command_buffer/client/gpu_switches.h" | 30 #include "gpu/command_buffer/client/gpu_switches.h" |
| 35 #endif | 31 #endif |
| 36 | 32 |
| 37 namespace gpu { | 33 namespace gpu { |
| 38 namespace gles2 { | 34 namespace gles2 { |
| 39 | 35 |
| 40 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. | 36 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. |
| 41 static GLuint ToGLuint(const void* ptr) { | 37 static GLuint ToGLuint(const void* ptr) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 --gles2_implementation_->use_count_; | 75 --gles2_implementation_->use_count_; |
| 80 CHECK_EQ(0, gles2_implementation_->use_count_); | 76 CHECK_EQ(0, gles2_implementation_->use_count_); |
| 81 } | 77 } |
| 82 | 78 |
| 83 GLES2Implementation::GLES2Implementation( | 79 GLES2Implementation::GLES2Implementation( |
| 84 GLES2CmdHelper* helper, | 80 GLES2CmdHelper* helper, |
| 85 ShareGroup* share_group, | 81 ShareGroup* share_group, |
| 86 TransferBufferInterface* transfer_buffer, | 82 TransferBufferInterface* transfer_buffer, |
| 87 bool bind_generates_resource, | 83 bool bind_generates_resource, |
| 88 bool lose_context_when_out_of_memory, | 84 bool lose_context_when_out_of_memory, |
| 85 bool support_client_side_arrays, |
| 89 GpuControl* gpu_control) | 86 GpuControl* gpu_control) |
| 90 : helper_(helper), | 87 : helper_(helper), |
| 91 transfer_buffer_(transfer_buffer), | 88 transfer_buffer_(transfer_buffer), |
| 92 angle_pack_reverse_row_order_status_(kUnknownExtensionStatus), | 89 angle_pack_reverse_row_order_status_(kUnknownExtensionStatus), |
| 93 chromium_framebuffer_multisample_(kUnknownExtensionStatus), | 90 chromium_framebuffer_multisample_(kUnknownExtensionStatus), |
| 94 pack_alignment_(4), | 91 pack_alignment_(4), |
| 95 unpack_alignment_(4), | 92 unpack_alignment_(4), |
| 96 unpack_flip_y_(false), | 93 unpack_flip_y_(false), |
| 97 unpack_row_length_(0), | 94 unpack_row_length_(0), |
| 98 unpack_skip_rows_(0), | 95 unpack_skip_rows_(0), |
| 99 unpack_skip_pixels_(0), | 96 unpack_skip_pixels_(0), |
| 100 pack_reverse_row_order_(false), | 97 pack_reverse_row_order_(false), |
| 101 active_texture_unit_(0), | 98 active_texture_unit_(0), |
| 102 bound_framebuffer_(0), | 99 bound_framebuffer_(0), |
| 103 bound_read_framebuffer_(0), | 100 bound_read_framebuffer_(0), |
| 104 bound_renderbuffer_(0), | 101 bound_renderbuffer_(0), |
| 105 current_program_(0), | 102 current_program_(0), |
| 106 bound_array_buffer_id_(0), | 103 bound_array_buffer_id_(0), |
| 107 bound_pixel_pack_transfer_buffer_id_(0), | 104 bound_pixel_pack_transfer_buffer_id_(0), |
| 108 bound_pixel_unpack_transfer_buffer_id_(0), | 105 bound_pixel_unpack_transfer_buffer_id_(0), |
| 109 async_upload_token_(0), | 106 async_upload_token_(0), |
| 110 async_upload_sync_(NULL), | 107 async_upload_sync_(NULL), |
| 111 async_upload_sync_shm_id_(0), | 108 async_upload_sync_shm_id_(0), |
| 112 async_upload_sync_shm_offset_(0), | 109 async_upload_sync_shm_offset_(0), |
| 113 error_bits_(0), | 110 error_bits_(0), |
| 114 debug_(false), | 111 debug_(false), |
| 115 lose_context_when_out_of_memory_(lose_context_when_out_of_memory), | 112 lose_context_when_out_of_memory_(lose_context_when_out_of_memory), |
| 113 support_client_side_arrays_(support_client_side_arrays), |
| 116 use_count_(0), | 114 use_count_(0), |
| 117 error_message_callback_(NULL), | 115 error_message_callback_(NULL), |
| 118 gpu_control_(gpu_control), | 116 gpu_control_(gpu_control), |
| 119 capabilities_(gpu_control->GetCapabilities()), | 117 capabilities_(gpu_control->GetCapabilities()), |
| 120 weak_ptr_factory_(this) { | 118 weak_ptr_factory_(this) { |
| 121 DCHECK(helper); | 119 DCHECK(helper); |
| 122 DCHECK(transfer_buffer); | 120 DCHECK(transfer_buffer); |
| 123 DCHECK(gpu_control); | 121 DCHECK(gpu_control); |
| 124 | 122 |
| 125 std::stringstream ss; | 123 std::stringstream ss; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 static_state_.int_state.num_shader_binary_formats); | 182 static_state_.int_state.num_shader_binary_formats); |
| 185 | 183 |
| 186 texture_units_.reset( | 184 texture_units_.reset( |
| 187 new TextureUnit[ | 185 new TextureUnit[ |
| 188 static_state_.int_state.max_combined_texture_image_units]); | 186 static_state_.int_state.max_combined_texture_image_units]); |
| 189 | 187 |
| 190 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 188 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
| 191 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); | 189 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); |
| 192 | 190 |
| 193 query_id_allocator_.reset(new IdAllocator()); | 191 query_id_allocator_.reset(new IdAllocator()); |
| 194 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 192 if (support_client_side_arrays_) { |
| 195 GetIdHandler(id_namespaces::kBuffers)->MakeIds( | 193 GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
| 196 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); | 194 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); |
| 197 #endif | 195 } |
| 198 | 196 |
| 199 vertex_array_object_manager_.reset(new VertexArrayObjectManager( | 197 vertex_array_object_manager_.reset(new VertexArrayObjectManager( |
| 200 static_state_.int_state.max_vertex_attribs, | 198 static_state_.int_state.max_vertex_attribs, |
| 201 reserved_ids_[0], | 199 reserved_ids_[0], |
| 202 reserved_ids_[1])); | 200 reserved_ids_[1], |
| 201 support_client_side_arrays_)); |
| 203 | 202 |
| 204 // GL_BIND_GENERATES_RESOURCE_CHROMIUM state must be the same | 203 // GL_BIND_GENERATES_RESOURCE_CHROMIUM state must be the same |
| 205 // on Client & Service. | 204 // on Client & Service. |
| 206 if (static_state_.int_state.bind_generates_resource_chromium != | 205 if (static_state_.int_state.bind_generates_resource_chromium != |
| 207 (share_group_->bind_generates_resource() ? 1 : 0)) { | 206 (share_group_->bind_generates_resource() ? 1 : 0)) { |
| 208 SetGLError(GL_INVALID_OPERATION, | 207 SetGLError(GL_INVALID_OPERATION, |
| 209 "Initialize", | 208 "Initialize", |
| 210 "Service bind_generates_resource mismatch."); | 209 "Service bind_generates_resource mismatch."); |
| 211 return false; | 210 return false; |
| 212 } | 211 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 } | 288 } |
| 290 | 289 |
| 291 GLES2Implementation::~GLES2Implementation() { | 290 GLES2Implementation::~GLES2Implementation() { |
| 292 // Make sure the queries are finished otherwise we'll delete the | 291 // Make sure the queries are finished otherwise we'll delete the |
| 293 // shared memory (mapped_memory_) which will free the memory used | 292 // shared memory (mapped_memory_) which will free the memory used |
| 294 // by the queries. The GPU process when validating that memory is still | 293 // by the queries. The GPU process when validating that memory is still |
| 295 // shared will fail and abort (ie, it will stop running). | 294 // shared will fail and abort (ie, it will stop running). |
| 296 WaitForCmd(); | 295 WaitForCmd(); |
| 297 query_tracker_.reset(); | 296 query_tracker_.reset(); |
| 298 | 297 |
| 299 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 298 if (support_client_side_arrays_) |
| 300 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); | 299 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); |
| 301 #endif | |
| 302 | 300 |
| 303 // Release any per-context data in share group. | 301 // Release any per-context data in share group. |
| 304 share_group_->FreeContext(this); | 302 share_group_->FreeContext(this); |
| 305 | 303 |
| 306 buffer_tracker_.reset(); | 304 buffer_tracker_.reset(); |
| 307 | 305 |
| 308 FreeAllAsyncUploadBuffers(); | 306 FreeAllAsyncUploadBuffers(); |
| 309 | 307 |
| 310 if (async_upload_sync_) { | 308 if (async_upload_sync_) { |
| 311 mapped_memory_->Free(async_upload_sync_); | 309 mapped_memory_->Free(async_upload_sync_); |
| (...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 << GLES2Util::GetStringBool(normalized) << ", " | 1204 << GLES2Util::GetStringBool(normalized) << ", " |
| 1207 << stride << ", " | 1205 << stride << ", " |
| 1208 << static_cast<const void*>(ptr) << ")"); | 1206 << static_cast<const void*>(ptr) << ")"); |
| 1209 // Record the info on the client side. | 1207 // Record the info on the client side. |
| 1210 if (!vertex_array_object_manager_->SetAttribPointer( | 1208 if (!vertex_array_object_manager_->SetAttribPointer( |
| 1211 bound_array_buffer_id_, index, size, type, normalized, stride, ptr)) { | 1209 bound_array_buffer_id_, index, size, type, normalized, stride, ptr)) { |
| 1212 SetGLError(GL_INVALID_OPERATION, "glVertexAttribPointer", | 1210 SetGLError(GL_INVALID_OPERATION, "glVertexAttribPointer", |
| 1213 "client side arrays are not allowed in vertex array objects."); | 1211 "client side arrays are not allowed in vertex array objects."); |
| 1214 return; | 1212 return; |
| 1215 } | 1213 } |
| 1216 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 1214 if (!support_client_side_arrays_ || bound_array_buffer_id_ != 0) { |
| 1217 if (bound_array_buffer_id_ != 0) { | |
| 1218 // Only report NON client side buffers to the service. | 1215 // Only report NON client side buffers to the service. |
| 1219 if (!ValidateOffset("glVertexAttribPointer", | 1216 if (!ValidateOffset("glVertexAttribPointer", |
| 1220 reinterpret_cast<GLintptr>(ptr))) { | 1217 reinterpret_cast<GLintptr>(ptr))) { |
| 1221 return; | 1218 return; |
| 1222 } | 1219 } |
| 1223 helper_->VertexAttribPointer(index, size, type, normalized, stride, | 1220 helper_->VertexAttribPointer(index, size, type, normalized, stride, |
| 1224 ToGLuint(ptr)); | 1221 ToGLuint(ptr)); |
| 1225 } | 1222 } |
| 1226 #else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 1227 if (!ValidateOffset("glVertexAttribPointer", | |
| 1228 reinterpret_cast<GLintptr>(ptr))) { | |
| 1229 return; | |
| 1230 } | |
| 1231 helper_->VertexAttribPointer(index, size, type, normalized, stride, | |
| 1232 ToGLuint(ptr)); | |
| 1233 #endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 1234 CheckGLError(); | 1223 CheckGLError(); |
| 1235 } | 1224 } |
| 1236 | 1225 |
| 1237 void GLES2Implementation::VertexAttribDivisorANGLE( | 1226 void GLES2Implementation::VertexAttribDivisorANGLE( |
| 1238 GLuint index, GLuint divisor) { | 1227 GLuint index, GLuint divisor) { |
| 1239 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1228 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1240 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" | 1229 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" |
| 1241 << index << ", " | 1230 << index << ", " |
| 1242 << divisor << ") "); | 1231 << divisor << ") "); |
| 1243 // Record the info on the client side. | 1232 // Record the info on the client side. |
| (...skipping 2702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3946 if (height <= 0) { | 3935 if (height <= 0) { |
| 3947 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "height <= 0"); | 3936 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "height <= 0"); |
| 3948 return 0; | 3937 return 0; |
| 3949 } | 3938 } |
| 3950 | 3939 |
| 3951 if (!ValidImageFormat(internalformat)) { | 3940 if (!ValidImageFormat(internalformat)) { |
| 3952 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "invalid format"); | 3941 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "invalid format"); |
| 3953 return 0; | 3942 return 0; |
| 3954 } | 3943 } |
| 3955 | 3944 |
| 3956 // Flush the command stream to ensure ordering in case the newly | |
| 3957 // returned image_id has recently been in use with a different buffer. | |
| 3958 helper_->CommandBufferHelper::Flush(); | |
| 3959 int32_t image_id = | 3945 int32_t image_id = |
| 3960 gpu_control_->CreateImage(buffer, width, height, internalformat); | 3946 gpu_control_->CreateImage(buffer, width, height, internalformat); |
| 3961 if (image_id < 0) { | 3947 if (image_id < 0) { |
| 3962 SetGLError(GL_OUT_OF_MEMORY, "glCreateImageCHROMIUM", "image_id < 0"); | 3948 SetGLError(GL_OUT_OF_MEMORY, "glCreateImageCHROMIUM", "image_id < 0"); |
| 3963 return 0; | 3949 return 0; |
| 3964 } | 3950 } |
| 3965 return image_id; | 3951 return image_id; |
| 3966 } | 3952 } |
| 3967 | 3953 |
| 3968 GLuint GLES2Implementation::CreateImageCHROMIUM(ClientBuffer buffer, | 3954 GLuint GLES2Implementation::CreateImageCHROMIUM(ClientBuffer buffer, |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4082 return true; | 4068 return true; |
| 4083 } | 4069 } |
| 4084 | 4070 |
| 4085 // Include the auto-generated part of this file. We split this because it means | 4071 // Include the auto-generated part of this file. We split this because it means |
| 4086 // we can easily edit the non-auto generated parts right here in this file | 4072 // we can easily edit the non-auto generated parts right here in this file |
| 4087 // instead of having to edit some template or the code generator. | 4073 // instead of having to edit some template or the code generator. |
| 4088 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 4074 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
| 4089 | 4075 |
| 4090 } // namespace gles2 | 4076 } // namespace gles2 |
| 4091 } // namespace gpu | 4077 } // namespace gpu |
| OLD | NEW |