Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/browser/renderer_host/software_frame_manager.h" | |
| 6 | |
| 7 #include <list> | |
| 8 #include <set> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/callback_helpers.h" | |
| 12 #include "base/memory/singleton.h" | |
| 13 #include "base/sys_info.h" | |
| 14 #include "content/browser/renderer_host/dip_util.h" | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 size_t MaxNumberOfSavedFrames() { | |
| 19 return std::min(5, 2 + (base::SysInfo::AmountOfPhysicalMemoryMB() / 256)); | |
| 20 } | |
| 21 | |
| 22 void ReleaseMailbox(scoped_refptr<content::SoftwareFrame> frame, | |
| 23 unsigned sync_point, | |
| 24 bool lost_resource) {} | |
| 25 | |
| 26 } // namespace | |
| 27 | |
| 28 namespace content { | |
| 29 | |
| 30 //////////////////////////////////////////////////////////////////////////////// | |
| 31 // SoftwareFrameMemoryManager | |
| 32 | |
| 33 class SoftwareFrameMemoryManager { | |
| 34 public: | |
| 35 static SoftwareFrameMemoryManager* GetInstance(); | |
| 36 | |
| 37 void AddFrame(SoftwareFrameManager*, bool visible); | |
| 38 void RemoveFrame(SoftwareFrameManager*); | |
| 39 void SetFrameVisibility(SoftwareFrameManager*, bool visible); | |
| 40 | |
| 41 private: | |
| 42 SoftwareFrameMemoryManager(); | |
| 43 ~SoftwareFrameMemoryManager(); | |
| 44 void CullHiddenFrames(); | |
| 45 friend struct DefaultSingletonTraits<SoftwareFrameMemoryManager>; | |
| 46 | |
| 47 std::set<SoftwareFrameManager*> visible_frames_; | |
| 48 std::list<SoftwareFrameManager*> hidden_frames_; | |
| 49 | |
| 50 DISALLOW_COPY_AND_ASSIGN(SoftwareFrameMemoryManager); | |
| 51 }; | |
| 52 | |
| 53 SoftwareFrameMemoryManager* SoftwareFrameMemoryManager::GetInstance() { | |
| 54 return Singleton<SoftwareFrameMemoryManager>::get(); | |
| 55 } | |
| 56 | |
| 57 void SoftwareFrameMemoryManager::AddFrame(SoftwareFrameManager* frame, | |
| 58 bool visible) { | |
| 59 RemoveFrame(frame); | |
| 60 if (visible) | |
| 61 visible_frames_.insert(frame); | |
| 62 else | |
| 63 hidden_frames_.push_front(frame); | |
| 64 CullHiddenFrames(); | |
| 65 } | |
| 66 | |
| 67 void SoftwareFrameMemoryManager::RemoveFrame(SoftwareFrameManager* frame) { | |
| 68 visible_frames_.erase(frame); | |
| 69 hidden_frames_.remove(frame); | |
| 70 } | |
| 71 | |
| 72 void SoftwareFrameMemoryManager::SetFrameVisibility(SoftwareFrameManager* frame, | |
| 73 bool visible) { | |
| 74 if (visible) { | |
| 75 hidden_frames_.remove(frame); | |
| 76 visible_frames_.insert(frame); | |
| 77 } else { | |
| 78 visible_frames_.erase(frame); | |
| 79 hidden_frames_.push_front(frame); | |
| 80 CullHiddenFrames(); | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 SoftwareFrameMemoryManager::SoftwareFrameMemoryManager() {} | |
| 85 | |
| 86 SoftwareFrameMemoryManager::~SoftwareFrameMemoryManager() {} | |
| 87 | |
| 88 void SoftwareFrameMemoryManager::CullHiddenFrames() { | |
| 89 while (!hidden_frames_.empty() && | |
| 90 hidden_frames_.size() + visible_frames_.size() > | |
| 91 MaxNumberOfSavedFrames()) { | |
|
piman
2013/10/22 22:32:48
nit: MaxNumberOfSavedFrames() is a constant, right
ccameron
2013/10/23 01:05:58
Done.
| |
| 92 size_t old_size = hidden_frames_.size(); | |
| 93 // Should remove self from list. | |
| 94 hidden_frames_.back()->EvictCurrentFrame(); | |
| 95 DCHECK_EQ(hidden_frames_.size() + 1, old_size); | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 //////////////////////////////////////////////////////////////////////////////// | |
| 100 // SoftwareFrame | |
| 101 | |
| 102 class SoftwareFrame : public base::RefCounted<SoftwareFrame> { | |
| 103 public: | |
| 104 SoftwareFrame( | |
| 105 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client, | |
| 106 uint32 output_surface_id, | |
| 107 unsigned frame_id, | |
| 108 gfx::Size frame_size_dip, | |
| 109 gfx::Size frame_size_pixels, | |
| 110 scoped_ptr<base::SharedMemory> shared_memory) | |
| 111 : frame_manager_client_(frame_manager_client), | |
| 112 output_surface_id_(output_surface_id), | |
| 113 frame_id_(frame_id), | |
| 114 frame_size_dip_(frame_size_dip), | |
| 115 frame_size_pixels_(frame_size_pixels), | |
| 116 shared_memory_(shared_memory.Pass()) {} | |
| 117 | |
| 118 void GetMailbox(cc::TextureMailbox* mailbox, | |
| 119 scoped_ptr<cc::SingleReleaseCallback>* callback) { | |
| 120 *mailbox = cc::TextureMailbox(shared_memory_.get(), frame_size_pixels_); | |
| 121 *callback = cc::SingleReleaseCallback::Create( | |
| 122 base::Bind(ReleaseMailbox, make_scoped_refptr(this))); | |
| 123 } | |
| 124 const void* GetPixels() const { return shared_memory_->memory(); } | |
| 125 gfx::Size GetSizeInDIP() const { return frame_size_dip_; } | |
| 126 gfx::Size GetSizeInPixels() const { return frame_size_pixels_; } | |
| 127 | |
| 128 private: | |
| 129 friend class base::RefCounted<SoftwareFrame>; | |
| 130 | |
| 131 ~SoftwareFrame() { | |
| 132 if (frame_manager_client_) { | |
| 133 frame_manager_client_->SoftwareFrameWasFreed( | |
| 134 output_surface_id_, frame_id_); | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client_; | |
| 139 const uint32 output_surface_id_; | |
| 140 const unsigned frame_id_; | |
| 141 const gfx::Size frame_size_dip_; | |
| 142 const gfx::Size frame_size_pixels_; | |
| 143 scoped_ptr<base::SharedMemory> shared_memory_; | |
| 144 }; | |
| 145 | |
| 146 //////////////////////////////////////////////////////////////////////////////// | |
| 147 // SoftwareFrameManager | |
| 148 | |
| 149 SoftwareFrameManager::SoftwareFrameManager( | |
| 150 base::WeakPtr<SoftwareFrameManagerClient> client) | |
| 151 : client_(client) {} | |
| 152 | |
| 153 SoftwareFrameManager::~SoftwareFrameManager() {} | |
| 154 | |
| 155 bool SoftwareFrameManager::SwapToNewFrame( | |
| 156 uint32 output_surface_id, | |
| 157 const cc::SoftwareFrameData* frame_data, | |
| 158 float frame_device_scale_factor, | |
| 159 base::ProcessHandle process_handle) { | |
| 160 const size_t size_in_bytes = 4 * frame_data->size.GetArea(); | |
| 161 #ifdef OS_WIN | |
| 162 scoped_ptr<base::SharedMemory> shared_memory( | |
| 163 new base::SharedMemory(frame_data->handle, true, process_handle)); | |
| 164 #else | |
| 165 scoped_ptr<base::SharedMemory> shared_memory( | |
| 166 new base::SharedMemory(frame_data->handle, true)); | |
| 167 #endif | |
| 168 if (!shared_memory->Map(size_in_bytes)) { | |
| 169 return false; | |
| 170 } | |
| 171 | |
| 172 scoped_refptr<SoftwareFrame> next_frame(new SoftwareFrame( | |
| 173 client_, | |
| 174 output_surface_id, | |
| 175 frame_data->id, | |
| 176 ConvertSizeToDIP(frame_device_scale_factor, frame_data->size), | |
| 177 frame_data->size, | |
| 178 shared_memory.Pass())); | |
| 179 current_frame_.swap(next_frame); | |
| 180 return true; | |
| 181 } | |
| 182 | |
| 183 bool SoftwareFrameManager::HasCurrentFrame() const { | |
| 184 return current_frame_; | |
| 185 } | |
| 186 | |
| 187 void SoftwareFrameManager::DiscardCurrentFrame() { | |
| 188 if (!HasCurrentFrame()) | |
| 189 return; | |
| 190 current_frame_ = NULL; | |
| 191 SoftwareFrameMemoryManager::GetInstance()->RemoveFrame(this); | |
| 192 } | |
| 193 | |
| 194 void SoftwareFrameManager::SwapToNewFrameComplete(bool visible) { | |
| 195 DCHECK(HasCurrentFrame()); | |
| 196 SoftwareFrameMemoryManager::GetInstance()->AddFrame(this, visible); | |
| 197 } | |
| 198 | |
| 199 void SoftwareFrameManager::SetVisibility(bool visible) { | |
| 200 if (HasCurrentFrame()) { | |
| 201 SoftwareFrameMemoryManager::GetInstance()->SetFrameVisibility(this, | |
| 202 visible); | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 void SoftwareFrameManager::GetCurrentFrameMailbox( | |
| 207 cc::TextureMailbox* mailbox, | |
| 208 scoped_ptr<cc::SingleReleaseCallback>* callback) { | |
| 209 DCHECK(HasCurrentFrame()); | |
| 210 current_frame_->GetMailbox(mailbox, callback); | |
| 211 } | |
| 212 | |
| 213 const void* SoftwareFrameManager::GetCurrentFramePixels() const { | |
| 214 DCHECK(HasCurrentFrame()); | |
| 215 return current_frame_->GetPixels(); | |
| 216 } | |
| 217 | |
| 218 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const { | |
| 219 DCHECK(HasCurrentFrame()); | |
| 220 return current_frame_->GetSizeInPixels(); | |
| 221 } | |
| 222 | |
| 223 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInDIP() const { | |
| 224 DCHECK(HasCurrentFrame()); | |
| 225 return current_frame_->GetSizeInDIP(); | |
| 226 } | |
| 227 | |
| 228 void SoftwareFrameManager::EvictCurrentFrame() { | |
| 229 DCHECK(HasCurrentFrame()); | |
| 230 DiscardCurrentFrame(); | |
| 231 if (client_) | |
| 232 client_->CurrentSoftwareFrameWasEvicted(); | |
| 233 } | |
| 234 | |
| 235 } // namespace content | |
| OLD | NEW |