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> |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 #include "base/command_line.h" | 46 #include "base/command_line.h" |
| 47 #include "gpu/command_buffer/client/gpu_switches.h" | 47 #include "gpu/command_buffer/client/gpu_switches.h" |
| 48 #endif | 48 #endif |
| 49 | 49 |
| 50 namespace gpu { | 50 namespace gpu { |
| 51 namespace gles2 { | 51 namespace gles2 { |
| 52 | 52 |
| 53 namespace { | 53 namespace { |
| 54 | 54 |
| 55 // Class that DCHECKs if it is destructed without first having Release called. | 55 // Class that DCHECKs if it is destructed without first having Release called. |
| 56 class ScopedVisibilityImpl : public ContextSupport::ScopedVisibility { | 56 template <typename T> |
| 57 class ScopedContextSupportToken : public T { | |
| 57 public: | 58 public: |
| 58 explicit ScopedVisibilityImpl(ContextSupport* context_support) | 59 explicit ScopedContextSupportToken(ContextSupport* context_support) |
| 59 : initial_context_support_(context_support) {} | 60 : initial_context_support_(context_support) {} |
| 60 ~ScopedVisibilityImpl() { DCHECK(!initial_context_support_); } | 61 |
| 62 ~ScopedContextSupportToken() { DCHECK(!initial_context_support_); } | |
| 61 | 63 |
| 62 void Release(ContextSupport* context_support) { | 64 void Release(ContextSupport* context_support) { |
| 63 DCHECK_EQ(initial_context_support_, context_support); | 65 DCHECK_EQ(initial_context_support_, context_support); |
| 64 initial_context_support_ = nullptr; | 66 initial_context_support_ = nullptr; |
| 65 } | 67 } |
| 66 | 68 |
| 67 private: | 69 private: |
| 68 const ContextSupport* initial_context_support_; | 70 const ContextSupport* initial_context_support_; |
| 69 }; | 71 }; |
| 70 | 72 |
| 73 using ScopedVisibilityImpl = | |
| 74 ScopedContextSupportToken<ContextSupport::ScopedVisibility>; | |
| 75 using ScopedBusyImpl = ScopedContextSupportToken<ContextSupport::ScopedBusy>; | |
| 76 | |
| 71 void CopyRectToBuffer(const void* pixels, | 77 void CopyRectToBuffer(const void* pixels, |
| 72 uint32_t height, | 78 uint32_t height, |
| 73 uint32_t unpadded_row_size, | 79 uint32_t unpadded_row_size, |
| 74 uint32_t pixels_padded_row_size, | 80 uint32_t pixels_padded_row_size, |
| 75 void* buffer, | 81 void* buffer, |
| 76 uint32_t buffer_padded_row_size) { | 82 uint32_t buffer_padded_row_size) { |
| 77 if (height == 0) | 83 if (height == 0) |
| 78 return; | 84 return; |
| 79 const int8_t* source = static_cast<const int8_t*>(pixels); | 85 const int8_t* source = static_cast<const int8_t*>(pixels); |
| 80 int8_t* dest = static_cast<int8_t*>(buffer); | 86 int8_t* dest = static_cast<int8_t*>(buffer); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 94 GLuint ToGLuint(const void* ptr) { | 100 GLuint ToGLuint(const void* ptr) { |
| 95 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); | 101 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); |
| 96 } | 102 } |
| 97 | 103 |
| 98 static base::StaticAtomicSequenceNumber g_flush_id; | 104 static base::StaticAtomicSequenceNumber g_flush_id; |
| 99 | 105 |
| 100 uint32_t GenerateNextFlushId() { | 106 uint32_t GenerateNextFlushId() { |
| 101 return static_cast<uint32_t>(g_flush_id.GetNext()); | 107 return static_cast<uint32_t>(g_flush_id.GetNext()); |
| 102 } | 108 } |
| 103 | 109 |
| 110 const base::TimeDelta kIdleCallbackDelay = base::TimeDelta::FromSeconds(1); | |
| 111 | |
| 104 } // anonymous namespace | 112 } // anonymous namespace |
| 105 | 113 |
| 106 #if !defined(_MSC_VER) | 114 #if !defined(_MSC_VER) |
| 107 const size_t GLES2Implementation::kMaxSizeOfSimpleResult; | 115 const size_t GLES2Implementation::kMaxSizeOfSimpleResult; |
| 108 const unsigned int GLES2Implementation::kStartingOffset; | 116 const unsigned int GLES2Implementation::kStartingOffset; |
| 109 #endif | 117 #endif |
| 110 | 118 |
| 111 GLES2Implementation::GLStaticState::GLStaticState() { | 119 GLES2Implementation::GLStaticState::GLStaticState() { |
| 112 } | 120 } |
| 113 | 121 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 this, "GLES2Implementation", base::ThreadTaskRunnerHandle::Get()); | 293 this, "GLES2Implementation", base::ThreadTaskRunnerHandle::Get()); |
| 286 } | 294 } |
| 287 | 295 |
| 288 return true; | 296 return true; |
| 289 } | 297 } |
| 290 | 298 |
| 291 GLES2Implementation::~GLES2Implementation() { | 299 GLES2Implementation::~GLES2Implementation() { |
| 292 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( | 300 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
| 293 this); | 301 this); |
| 294 | 302 |
| 303 CancelIdleCallback(); | |
| 304 | |
| 295 // Make sure the queries are finished otherwise we'll delete the | 305 // Make sure the queries are finished otherwise we'll delete the |
| 296 // shared memory (mapped_memory_) which will free the memory used | 306 // shared memory (mapped_memory_) which will free the memory used |
| 297 // by the queries. The GPU process when validating that memory is still | 307 // by the queries. The GPU process when validating that memory is still |
| 298 // shared will fail and abort (ie, it will stop running). | 308 // shared will fail and abort (ie, it will stop running). |
| 299 WaitForCmd(); | 309 WaitForCmd(); |
| 300 query_tracker_.reset(); | 310 query_tracker_.reset(); |
| 301 | 311 |
| 302 // GLES2Implementation::Initialize() could fail before allocating | 312 // GLES2Implementation::Initialize() could fail before allocating |
| 303 // reserved_ids_, so we need delete them carefully. | 313 // reserved_ids_, so we need delete them carefully. |
| 304 if (support_client_side_arrays_ && reserved_ids_[0]) { | 314 if (support_client_side_arrays_ && reserved_ids_[0]) { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 439 FlushDriverCachesCHROMIUM(); | 449 FlushDriverCachesCHROMIUM(); |
| 440 | 450 |
| 441 // Flush will delete transfer buffer resources if | 451 // Flush will delete transfer buffer resources if |
| 442 // |aggressively_free_resources_| is true. | 452 // |aggressively_free_resources_| is true. |
| 443 Flush(); | 453 Flush(); |
| 444 } else { | 454 } else { |
| 445 ShallowFlushCHROMIUM(); | 455 ShallowFlushCHROMIUM(); |
| 446 } | 456 } |
| 447 } | 457 } |
| 448 | 458 |
| 459 void GLES2Implementation::TrimResources() { | |
| 460 TRACE_EVENT0("gpu", "GLES2Implementation::TrimResources"); | |
| 461 | |
| 462 bool initial_state = aggressively_free_resources_; | |
| 463 | |
| 464 SetAggressivelyFreeResources(true); | |
| 465 | |
| 466 if (!initial_state) { | |
| 467 SetAggressivelyFreeResources(false); | |
| 468 } | |
| 469 } | |
| 470 | |
| 449 bool GLES2Implementation::OnMemoryDump( | 471 bool GLES2Implementation::OnMemoryDump( |
| 450 const base::trace_event::MemoryDumpArgs& args, | 472 const base::trace_event::MemoryDumpArgs& args, |
| 451 base::trace_event::ProcessMemoryDump* pmd) { | 473 base::trace_event::ProcessMemoryDump* pmd) { |
| 452 if (!transfer_buffer_->HaveBuffer()) | 474 if (!transfer_buffer_->HaveBuffer()) |
| 453 return true; | 475 return true; |
| 454 | 476 |
| 455 const uint64_t tracing_process_id = | 477 const uint64_t tracing_process_id = |
| 456 base::trace_event::MemoryDumpManager::GetInstance() | 478 base::trace_event::MemoryDumpManager::GetInstance() |
| 457 ->GetTracingProcessId(); | 479 ->GetTracingProcessId(); |
| 458 | 480 |
| (...skipping 5429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5888 DCHECK(visibility); | 5910 DCHECK(visibility); |
| 5889 DCHECK_GT(num_visible_clients_, 0u); | 5911 DCHECK_GT(num_visible_clients_, 0u); |
| 5890 --num_visible_clients_; | 5912 --num_visible_clients_; |
| 5891 static_cast<ScopedVisibilityImpl*>(visibility.get())->Release(this); | 5913 static_cast<ScopedVisibilityImpl*>(visibility.get())->Release(this); |
| 5892 } | 5914 } |
| 5893 | 5915 |
| 5894 bool GLES2Implementation::AnyClientsVisible() const { | 5916 bool GLES2Implementation::AnyClientsVisible() const { |
| 5895 return num_visible_clients_ > 0; | 5917 return num_visible_clients_ > 0; |
| 5896 } | 5918 } |
| 5897 | 5919 |
| 5920 std::unique_ptr<ContextSupport::ScopedBusy> | |
| 5921 GLES2Implementation::ClientBecameBusy() { | |
| 5922 DCHECK(is_idle_); | |
| 5923 is_idle_ = false; | |
| 5924 | |
| 5925 if (idle_callback_) { | |
| 5926 // We can only modify |pending_idle_callback_| from the provided callback | |
|
danakj
2016/08/23 01:26:25
Its kinda awk if you end up running the cancel rig
ericrk
2016/08/24 18:32:21
It's actually a little bit tricky to avoid races l
| |
| 5927 // thread due to CancellableCallback constraints. Move to that thread. | |
| 5928 idle_callback_task_runner_->PostTask( | |
| 5929 FROM_HERE, base::Bind(&GLES2Implementation::CancelIdleCallback, | |
| 5930 weak_ptr_factory_.GetWeakPtr())); | |
| 5931 } | |
| 5932 | |
| 5933 return base::MakeUnique<ScopedBusyImpl>(this); | |
| 5934 } | |
| 5935 | |
| 5936 void GLES2Implementation::ClientBecameNotBusy( | |
| 5937 std::unique_ptr<ScopedBusy> busy) { | |
| 5938 DCHECK(busy); | |
| 5939 DCHECK(!is_idle_); | |
| 5940 is_idle_ = true; | |
| 5941 | |
| 5942 if (idle_callback_) { | |
| 5943 // We can only modify |pending_idle_callback_| from the provided callback | |
| 5944 // thread due to CancellableCallback constraints. Move to that thread. | |
| 5945 idle_callback_task_runner_->PostTask( | |
| 5946 FROM_HERE, base::Bind(&GLES2Implementation::ScheduleIdleCallback, | |
| 5947 weak_ptr_factory_.GetWeakPtr())); | |
| 5948 } | |
| 5949 | |
| 5950 static_cast<ScopedBusyImpl*>(busy.get())->Release(this); | |
| 5951 } | |
| 5952 | |
| 5953 void GLES2Implementation::SetIdleCallback( | |
| 5954 const base::Closure& callback, | |
| 5955 scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner) { | |
| 5956 idle_callback_ = callback; | |
| 5957 idle_callback_task_runner_ = std::move(callback_task_runner); | |
| 5958 } | |
| 5959 | |
| 5898 void GLES2Implementation::SetLostContextCallback( | 5960 void GLES2Implementation::SetLostContextCallback( |
| 5899 const base::Closure& callback) { | 5961 const base::Closure& callback) { |
| 5900 lost_context_callback_ = callback; | 5962 lost_context_callback_ = callback; |
| 5901 } | 5963 } |
| 5902 | 5964 |
| 5903 GLuint64 GLES2Implementation::InsertFenceSyncCHROMIUM() { | 5965 GLuint64 GLES2Implementation::InsertFenceSyncCHROMIUM() { |
| 5904 const uint64_t release = gpu_control_->GenerateFenceSyncRelease(); | 5966 const uint64_t release = gpu_control_->GenerateFenceSyncRelease(); |
| 5905 helper_->InsertFenceSyncCHROMIUM(release); | 5967 helper_->InsertFenceSyncCHROMIUM(release); |
| 5906 return release; | 5968 return release; |
| 5907 } | 5969 } |
| (...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6922 return; | 6984 return; |
| 6923 } | 6985 } |
| 6924 GetStringHelper(GL_EXTENSIONS); | 6986 GetStringHelper(GL_EXTENSIONS); |
| 6925 } | 6987 } |
| 6926 | 6988 |
| 6927 void GLES2Implementation::InvalidateCachedExtensions() { | 6989 void GLES2Implementation::InvalidateCachedExtensions() { |
| 6928 cached_extension_string_ = nullptr; | 6990 cached_extension_string_ = nullptr; |
| 6929 cached_extensions_.clear(); | 6991 cached_extensions_.clear(); |
| 6930 } | 6992 } |
| 6931 | 6993 |
| 6994 void GLES2Implementation::ScheduleIdleCallback() { | |
| 6995 if (!idle_callback_) | |
| 6996 return; | |
| 6997 if (!pending_idle_callback_) | |
| 6998 pending_idle_callback_.reset(new base::CancelableClosure()); | |
| 6999 | |
| 7000 pending_idle_callback_->Reset(idle_callback_); | |
| 7001 idle_callback_task_runner_->PostDelayedTask( | |
| 7002 FROM_HERE, pending_idle_callback_->callback(), kIdleCallbackDelay); | |
| 7003 } | |
| 7004 | |
| 7005 void GLES2Implementation::CancelIdleCallback() { | |
| 7006 if (pending_idle_callback_) | |
| 7007 pending_idle_callback_->Cancel(); | |
| 7008 } | |
| 7009 | |
| 6932 // Include the auto-generated part of this file. We split this because it means | 7010 // Include the auto-generated part of this file. We split this because it means |
| 6933 // we can easily edit the non-auto generated parts right here in this file | 7011 // we can easily edit the non-auto generated parts right here in this file |
| 6934 // instead of having to edit some template or the code generator. | 7012 // instead of having to edit some template or the code generator. |
| 6935 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 7013 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
| 6936 | 7014 |
| 6937 } // namespace gles2 | 7015 } // namespace gles2 |
| 6938 } // namespace gpu | 7016 } // namespace gpu |
| OLD | NEW |