Chromium Code Reviews| 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/gl2.h> | 9 #include <GLES2/gl2.h> |
| 10 #include <GLES2/gl2ext.h> | 10 #include <GLES2/gl2ext.h> |
| 11 #include <GLES2/gl2extchromium.h> | 11 #include <GLES2/gl2extchromium.h> |
| 12 #include <GLES3/gl3.h> | 12 #include <GLES3/gl3.h> |
| 13 #include <stddef.h> | 13 #include <stddef.h> |
| 14 #include <stdint.h> | 14 #include <stdint.h> |
| 15 #include <algorithm> | 15 #include <algorithm> |
| 16 #include <map> | 16 #include <map> |
| 17 #include <set> | 17 #include <set> |
| 18 #include <sstream> | 18 #include <sstream> |
| 19 #include <string> | 19 #include <string> |
| 20 #include "base/compiler_specific.h" | 20 #include "base/compiler_specific.h" |
| 21 #include "base/strings/string_split.h" | |
| 21 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
| 22 #include "base/sys_info.h" | 23 #include "base/sys_info.h" |
| 23 #include "base/thread_task_runner_handle.h" | 24 #include "base/thread_task_runner_handle.h" |
| 24 #include "base/trace_event/memory_allocator_dump.h" | 25 #include "base/trace_event/memory_allocator_dump.h" |
| 25 #include "base/trace_event/memory_dump_manager.h" | 26 #include "base/trace_event/memory_dump_manager.h" |
| 26 #include "base/trace_event/process_memory_dump.h" | 27 #include "base/trace_event/process_memory_dump.h" |
| 27 #include "base/trace_event/trace_event.h" | 28 #include "base/trace_event/trace_event.h" |
| 28 #include "gpu/command_buffer/client/buffer_tracker.h" | 29 #include "gpu/command_buffer/client/buffer_tracker.h" |
| 29 #include "gpu/command_buffer/client/gles2_cmd_helper.h" | 30 #include "gpu/command_buffer/client/gles2_cmd_helper.h" |
| 30 #include "gpu/command_buffer/client/gpu_control.h" | 31 #include "gpu/command_buffer/client/gpu_control.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 base::SysInfo::AmountOfPhysicalMemory() > 1024 * 1024 * 1024 | 125 base::SysInfo::AmountOfPhysicalMemory() > 1024 * 1024 * 1024 |
| 125 ? base::saturated_cast<uint32_t>( | 126 ? base::saturated_cast<uint32_t>( |
| 126 base::SysInfo::AmountOfPhysicalMemory() / 20) | 127 base::SysInfo::AmountOfPhysicalMemory() / 20) |
| 127 : 0), | 128 : 0), |
| 128 #endif | 129 #endif |
| 129 error_message_callback_(NULL), | 130 error_message_callback_(NULL), |
| 130 current_trace_stack_(0), | 131 current_trace_stack_(0), |
| 131 gpu_control_(gpu_control), | 132 gpu_control_(gpu_control), |
| 132 capabilities_(gpu_control->GetCapabilities()), | 133 capabilities_(gpu_control->GetCapabilities()), |
| 133 aggressively_free_resources_(false), | 134 aggressively_free_resources_(false), |
| 135 cached_extension_string_(nullptr), | |
| 134 weak_ptr_factory_(this) { | 136 weak_ptr_factory_(this) { |
| 135 DCHECK(helper); | 137 DCHECK(helper); |
| 136 DCHECK(transfer_buffer); | 138 DCHECK(transfer_buffer); |
| 137 DCHECK(gpu_control); | 139 DCHECK(gpu_control); |
| 138 | 140 |
| 139 std::stringstream ss; | 141 std::stringstream ss; |
| 140 ss << std::hex << this; | 142 ss << std::hex << this; |
| 141 this_in_hex_ = ss.str(); | 143 this_in_hex_ = ss.str(); |
| 142 | 144 |
| 143 GPU_CLIENT_LOG_CODE_BLOCK({ | 145 GPU_CLIENT_LOG_CODE_BLOCK({ |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: | 944 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: |
| 943 *params = capabilities_.max_vertex_uniform_components; | 945 *params = capabilities_.max_vertex_uniform_components; |
| 944 return true; | 946 return true; |
| 945 case GL_MIN_PROGRAM_TEXEL_OFFSET: | 947 case GL_MIN_PROGRAM_TEXEL_OFFSET: |
| 946 *params = capabilities_.min_program_texel_offset; | 948 *params = capabilities_.min_program_texel_offset; |
| 947 return true; | 949 return true; |
| 948 case GL_MINOR_VERSION: | 950 case GL_MINOR_VERSION: |
| 949 *params = capabilities_.minor_version; | 951 *params = capabilities_.minor_version; |
| 950 return true; | 952 return true; |
| 951 case GL_NUM_EXTENSIONS: | 953 case GL_NUM_EXTENSIONS: |
| 952 *params = capabilities_.num_extensions; | 954 UpdateCachedExtensionsIfNeeded(); |
| 955 *params = cached_extensions_.size(); | |
| 953 return true; | 956 return true; |
| 954 case GL_NUM_PROGRAM_BINARY_FORMATS: | 957 case GL_NUM_PROGRAM_BINARY_FORMATS: |
| 955 *params = capabilities_.num_program_binary_formats; | 958 *params = capabilities_.num_program_binary_formats; |
| 956 return true; | 959 return true; |
| 957 case GL_PIXEL_PACK_BUFFER_BINDING: | 960 case GL_PIXEL_PACK_BUFFER_BINDING: |
| 958 *params = bound_pixel_pack_buffer_; | 961 *params = bound_pixel_pack_buffer_; |
| 959 return true; | 962 return true; |
| 960 case GL_PIXEL_UNPACK_BUFFER_BINDING: | 963 case GL_PIXEL_UNPACK_BUFFER_BINDING: |
| 961 *params = bound_pixel_unpack_buffer_; | 964 *params = bound_pixel_unpack_buffer_; |
| 962 return true; | 965 return true; |
| (...skipping 2327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3290 } | 3293 } |
| 3291 if (precision) { | 3294 if (precision) { |
| 3292 precision[0] = result->precision; | 3295 precision[0] = result->precision; |
| 3293 GPU_CLIENT_LOG(" min_range: " << precision[0]); | 3296 GPU_CLIENT_LOG(" min_range: " << precision[0]); |
| 3294 } | 3297 } |
| 3295 } | 3298 } |
| 3296 CheckGLError(); | 3299 CheckGLError(); |
| 3297 } | 3300 } |
| 3298 | 3301 |
| 3299 const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) { | 3302 const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) { |
| 3303 if (name == GL_EXTENSIONS && cached_extension_string_) { | |
| 3304 return reinterpret_cast<const GLubyte*>(cached_extension_string_); | |
| 3305 } | |
| 3300 const char* result = NULL; | 3306 const char* result = NULL; |
| 3301 // Clears the bucket so if the command fails nothing will be in it. | 3307 // Clears the bucket so if the command fails nothing will be in it. |
| 3302 helper_->SetBucketSize(kResultBucketId, 0); | 3308 helper_->SetBucketSize(kResultBucketId, 0); |
| 3303 helper_->GetString(name, kResultBucketId); | 3309 helper_->GetString(name, kResultBucketId); |
| 3304 std::string str; | 3310 std::string str; |
| 3305 if (GetBucketAsString(kResultBucketId, &str)) { | 3311 if (GetBucketAsString(kResultBucketId, &str)) { |
| 3306 // Adds extensions implemented on client side only. | 3312 // Adds extensions implemented on client side only. |
| 3307 switch (name) { | 3313 if (name == GL_EXTENSIONS) { |
| 3308 case GL_EXTENSIONS: | 3314 str += std::string(str.empty() ? "" : " ") + |
| 3309 str += std::string(str.empty() ? "" : " ") + | 3315 "GL_EXT_unpack_subimage " |
| 3310 "GL_EXT_unpack_subimage " | 3316 "GL_CHROMIUM_map_sub"; |
| 3311 "GL_CHROMIUM_map_sub"; | 3317 if (capabilities_.image) |
| 3312 if (capabilities_.image) | 3318 str += " GL_CHROMIUM_image GL_CHROMIUM_gpu_memory_buffer_image"; |
| 3313 str += " GL_CHROMIUM_image GL_CHROMIUM_gpu_memory_buffer_image"; | 3319 if (capabilities_.future_sync_points) |
| 3314 if (capabilities_.future_sync_points) | 3320 str += " GL_CHROMIUM_future_sync_point"; |
| 3315 str += " GL_CHROMIUM_future_sync_point"; | |
| 3316 break; | |
| 3317 default: | |
| 3318 break; | |
| 3319 } | 3321 } |
| 3320 | 3322 |
| 3321 // Because of WebGL the extensions can change. We have to cache each unique | 3323 // Because of WebGL the extensions can change. We have to cache each unique |
| 3322 // result since we don't know when the client will stop referring to a | 3324 // result since we don't know when the client will stop referring to a |
| 3323 // previous one it queries. | 3325 // previous one it queries. |
| 3324 GLStringMap::iterator it = gl_strings_.find(name); | 3326 const std::string& cache = *gl_strings_.insert(str).first; |
|
piman
2016/02/11 18:50:38
Is it really advantageous to change gl_strings_ fr
Kimmo Kinnunen
2016/02/11 18:55:42
It is changed from many sets to sets.
map of sets
piman
2016/02/11 19:15:27
Mmh, ok, I misread the former code. I was under th
| |
| 3325 if (it == gl_strings_.end()) { | 3327 result = cache.c_str(); |
| 3326 std::set<std::string> strings; | 3328 |
| 3327 std::pair<GLStringMap::iterator, bool> insert_result = | 3329 if (name == GL_EXTENSIONS) { |
| 3328 gl_strings_.insert(std::make_pair(name, strings)); | 3330 cached_extension_string_ = result; |
| 3329 DCHECK(insert_result.second); | 3331 std::vector<std::string> extensions = |
| 3330 it = insert_result.first; | 3332 base::SplitString(cache, base::kWhitespaceASCII, |
| 3331 } | 3333 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| 3332 std::set<std::string>& string_set = it->second; | 3334 for (auto extension : extensions) { |
| 3333 std::set<std::string>::const_iterator sit = string_set.find(str); | 3335 cached_extensions_.push_back( |
| 3334 if (sit != string_set.end()) { | 3336 gl_strings_.insert(extension).first->c_str()); |
| 3335 result = sit->c_str(); | 3337 } |
| 3336 } else { | |
| 3337 std::pair<std::set<std::string>::const_iterator, bool> insert_result = | |
| 3338 string_set.insert(str); | |
| 3339 DCHECK(insert_result.second); | |
| 3340 result = insert_result.first->c_str(); | |
| 3341 } | 3338 } |
| 3342 } | 3339 } |
| 3343 return reinterpret_cast<const GLubyte*>(result); | 3340 return reinterpret_cast<const GLubyte*>(result); |
| 3344 } | 3341 } |
| 3345 | 3342 |
| 3346 const GLubyte* GLES2Implementation::GetString(GLenum name) { | 3343 const GLubyte* GLES2Implementation::GetString(GLenum name) { |
| 3347 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3344 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3348 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetString(" | 3345 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetString(" |
| 3349 << GLES2Util::GetStringStringType(name) << ")"); | 3346 << GLES2Util::GetStringStringType(name) << ")"); |
| 3350 TRACE_EVENT0("gpu", "GLES2::GetString"); | 3347 TRACE_EVENT0("gpu", "GLES2::GetString"); |
| 3351 const GLubyte* result = GetStringHelper(name); | 3348 const GLubyte* result = GetStringHelper(name); |
| 3352 GPU_CLIENT_LOG(" returned " << reinterpret_cast<const char*>(result)); | 3349 GPU_CLIENT_LOG(" returned " << reinterpret_cast<const char*>(result)); |
| 3353 CheckGLError(); | 3350 CheckGLError(); |
| 3354 return result; | 3351 return result; |
| 3355 } | 3352 } |
| 3356 | 3353 |
| 3354 const GLubyte* GLES2Implementation::GetStringi(GLenum name, GLuint index) { | |
| 3355 GPU_CLIENT_SINGLE_THREAD_CHECK(); | |
| 3356 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetStringi(" | |
| 3357 << GLES2Util::GetStringStringType(name) << "," << index | |
| 3358 << ")"); | |
| 3359 TRACE_EVENT0("gpu", "GLES2::GetStringi"); | |
| 3360 UpdateCachedExtensionsIfNeeded(); | |
| 3361 if (name != GL_EXTENSIONS) { | |
| 3362 SetGLError(GL_INVALID_ENUM, "glGetStringi", "name"); | |
| 3363 return nullptr; | |
| 3364 } | |
| 3365 if (index >= cached_extensions_.size()) { | |
| 3366 SetGLError(GL_INVALID_VALUE, "glGetStringi", "index too large"); | |
| 3367 return nullptr; | |
| 3368 } | |
| 3369 | |
| 3370 const char* result = cached_extensions_[index]; | |
| 3371 GPU_CLIENT_LOG(" returned " << result); | |
| 3372 CheckGLError(); | |
| 3373 return reinterpret_cast<const GLubyte*>(result); | |
| 3374 } | |
| 3375 | |
| 3357 bool GLES2Implementation::GetTransformFeedbackVaryingHelper( | 3376 bool GLES2Implementation::GetTransformFeedbackVaryingHelper( |
| 3358 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, | 3377 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, |
| 3359 GLenum* type, char* name) { | 3378 GLenum* type, char* name) { |
| 3360 // Clear the bucket so if the command fails nothing will be in it. | 3379 // Clear the bucket so if the command fails nothing will be in it. |
| 3361 helper_->SetBucketSize(kResultBucketId, 0); | 3380 helper_->SetBucketSize(kResultBucketId, 0); |
| 3362 typedef cmds::GetTransformFeedbackVarying::Result Result; | 3381 typedef cmds::GetTransformFeedbackVarying::Result Result; |
| 3363 Result* result = GetResultAs<Result*>(); | 3382 Result* result = GetResultAs<Result*>(); |
| 3364 if (!result) { | 3383 if (!result) { |
| 3365 return false; | 3384 return false; |
| 3366 } | 3385 } |
| (...skipping 1446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4813 const char* result = NULL; | 4832 const char* result = NULL; |
| 4814 // Clear the bucket so if the command fails nothing will be in it. | 4833 // Clear the bucket so if the command fails nothing will be in it. |
| 4815 helper_->SetBucketSize(kResultBucketId, 0); | 4834 helper_->SetBucketSize(kResultBucketId, 0); |
| 4816 helper_->GetRequestableExtensionsCHROMIUM(kResultBucketId); | 4835 helper_->GetRequestableExtensionsCHROMIUM(kResultBucketId); |
| 4817 std::string str; | 4836 std::string str; |
| 4818 if (GetBucketAsString(kResultBucketId, &str)) { | 4837 if (GetBucketAsString(kResultBucketId, &str)) { |
| 4819 // The set of requestable extensions shrinks as we enable | 4838 // The set of requestable extensions shrinks as we enable |
| 4820 // them. Because we don't know when the client will stop referring | 4839 // them. Because we don't know when the client will stop referring |
| 4821 // to a previous one it queries (see GetString) we need to cache | 4840 // to a previous one it queries (see GetString) we need to cache |
| 4822 // the unique results. | 4841 // the unique results. |
| 4823 std::set<std::string>::const_iterator sit = | 4842 result = gl_strings_.insert(str).first->c_str(); |
| 4824 requestable_extensions_set_.find(str); | |
| 4825 if (sit != requestable_extensions_set_.end()) { | |
| 4826 result = sit->c_str(); | |
| 4827 } else { | |
| 4828 std::pair<std::set<std::string>::const_iterator, bool> insert_result = | |
| 4829 requestable_extensions_set_.insert(str); | |
| 4830 DCHECK(insert_result.second); | |
| 4831 result = insert_result.first->c_str(); | |
| 4832 } | |
| 4833 } | 4843 } |
| 4834 GPU_CLIENT_LOG(" returned " << result); | 4844 GPU_CLIENT_LOG(" returned " << result); |
| 4835 return reinterpret_cast<const GLchar*>(result); | 4845 return reinterpret_cast<const GLchar*>(result); |
| 4836 } | 4846 } |
| 4837 | 4847 |
| 4838 // TODO(gman): Remove this command. It's here for WebGL but is incompatible | 4848 // TODO(gman): Remove this command. It's here for WebGL but is incompatible |
| 4839 // with VirtualGL contexts. | 4849 // with VirtualGL contexts. |
| 4840 void GLES2Implementation::RequestExtensionCHROMIUM(const char* extension) { | 4850 void GLES2Implementation::RequestExtensionCHROMIUM(const char* extension) { |
| 4841 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 4851 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 4842 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glRequestExtensionCHROMIUM(" | 4852 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glRequestExtensionCHROMIUM(" |
| 4843 << extension << ")"); | 4853 << extension << ")"); |
| 4854 InvalidateCachedExtensions(); | |
| 4844 SetBucketAsCString(kResultBucketId, extension); | 4855 SetBucketAsCString(kResultBucketId, extension); |
| 4845 helper_->RequestExtensionCHROMIUM(kResultBucketId); | 4856 helper_->RequestExtensionCHROMIUM(kResultBucketId); |
| 4846 helper_->SetBucketSize(kResultBucketId, 0); | 4857 helper_->SetBucketSize(kResultBucketId, 0); |
| 4847 | 4858 |
| 4848 struct ExtensionCheck { | 4859 struct ExtensionCheck { |
| 4849 const char* extension; | 4860 const char* extension; |
| 4850 ExtensionStatus* status; | 4861 ExtensionStatus* status; |
| 4851 }; | 4862 }; |
| 4852 const ExtensionCheck checks[] = { | 4863 const ExtensionCheck checks[] = { |
| 4853 { | 4864 { |
| (...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6544 unsigned char* addr = static_cast<unsigned char*>(buffer.address()); | 6555 unsigned char* addr = static_cast<unsigned char*>(buffer.address()); |
| 6545 memcpy(addr, coeffs, coeffs_size); | 6556 memcpy(addr, coeffs, coeffs_size); |
| 6546 | 6557 |
| 6547 helper_->ProgramPathFragmentInputGenCHROMIUM(program, location, gen_mode, | 6558 helper_->ProgramPathFragmentInputGenCHROMIUM(program, location, gen_mode, |
| 6548 components, buffer.shm_id(), | 6559 components, buffer.shm_id(), |
| 6549 buffer.offset()); | 6560 buffer.offset()); |
| 6550 } | 6561 } |
| 6551 CheckGLError(); | 6562 CheckGLError(); |
| 6552 } | 6563 } |
| 6553 | 6564 |
| 6565 void GLES2Implementation::UpdateCachedExtensionsIfNeeded() { | |
| 6566 if (cached_extension_string_) { | |
| 6567 return; | |
| 6568 } | |
| 6569 GetStringHelper(GL_EXTENSIONS); | |
| 6570 } | |
| 6571 | |
| 6572 void GLES2Implementation::InvalidateCachedExtensions() { | |
| 6573 cached_extension_string_ = nullptr; | |
| 6574 cached_extensions_.clear(); | |
| 6575 } | |
| 6576 | |
| 6554 // Include the auto-generated part of this file. We split this because it means | 6577 // Include the auto-generated part of this file. We split this because it means |
| 6555 // we can easily edit the non-auto generated parts right here in this file | 6578 // we can easily edit the non-auto generated parts right here in this file |
| 6556 // instead of having to edit some template or the code generator. | 6579 // instead of having to edit some template or the code generator. |
| 6557 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 6580 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
| 6558 | 6581 |
| 6559 } // namespace gles2 | 6582 } // namespace gles2 |
| 6560 } // namespace gpu | 6583 } // namespace gpu |
| OLD | NEW |