Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(457)

Side by Side Diff: content/browser/renderer_host/software_frame_manager.cc

Issue 25942002: Make software compositing work on Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add missed statics Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 static size_t max_number_of_saved_frames = std::min(
20 5, 2 + (base::SysInfo::AmountOfPhysicalMemoryMB() / 256));
21 return max_number_of_saved_frames;
22 }
23
24 void ReleaseMailbox(scoped_refptr<content::SoftwareFrame> frame,
25 unsigned sync_point,
26 bool lost_resource) {}
27
28 } // namespace
29
30 namespace content {
31
32 ////////////////////////////////////////////////////////////////////////////////
33 // SoftwareFrameMemoryManager
34
35 class SoftwareFrameMemoryManager {
36 public:
37 static SoftwareFrameMemoryManager* GetInstance();
38
39 void AddFrame(SoftwareFrameManager*, bool visible);
40 void RemoveFrame(SoftwareFrameManager*);
41 void SetFrameVisibility(SoftwareFrameManager*, bool visible);
42
43 private:
44 SoftwareFrameMemoryManager();
45 ~SoftwareFrameMemoryManager();
46 void CullHiddenFrames();
47 friend struct DefaultSingletonTraits<SoftwareFrameMemoryManager>;
48
49 std::set<SoftwareFrameManager*> visible_frames_;
50 std::list<SoftwareFrameManager*> hidden_frames_;
51
52 DISALLOW_COPY_AND_ASSIGN(SoftwareFrameMemoryManager);
53 };
54
55 SoftwareFrameMemoryManager* SoftwareFrameMemoryManager::GetInstance() {
56 return Singleton<SoftwareFrameMemoryManager>::get();
57 }
58
59 void SoftwareFrameMemoryManager::AddFrame(SoftwareFrameManager* frame,
60 bool visible) {
61 RemoveFrame(frame);
62 if (visible)
63 visible_frames_.insert(frame);
64 else
65 hidden_frames_.push_front(frame);
66 CullHiddenFrames();
67 }
68
69 void SoftwareFrameMemoryManager::RemoveFrame(SoftwareFrameManager* frame) {
70 visible_frames_.erase(frame);
71 hidden_frames_.remove(frame);
72 }
73
74 void SoftwareFrameMemoryManager::SetFrameVisibility(SoftwareFrameManager* frame,
75 bool visible) {
76 if (visible) {
77 hidden_frames_.remove(frame);
78 visible_frames_.insert(frame);
79 } else {
80 visible_frames_.erase(frame);
81 hidden_frames_.push_front(frame);
82 CullHiddenFrames();
83 }
84 }
85
86 SoftwareFrameMemoryManager::SoftwareFrameMemoryManager() {}
87
88 SoftwareFrameMemoryManager::~SoftwareFrameMemoryManager() {}
89
90 void SoftwareFrameMemoryManager::CullHiddenFrames() {
91 while (!hidden_frames_.empty() &&
92 hidden_frames_.size() + visible_frames_.size() >
93 MaxNumberOfSavedFrames()) {
94 size_t old_size = hidden_frames_.size();
95 // Should remove self from list.
96 hidden_frames_.back()->EvictCurrentFrame();
97 DCHECK_EQ(hidden_frames_.size() + 1, old_size);
98 }
99 }
100
101 ////////////////////////////////////////////////////////////////////////////////
102 // SoftwareFrame
103
104 class CONTENT_EXPORT SoftwareFrame : public base::RefCounted<SoftwareFrame> {
105 private:
106 friend class base::RefCounted<SoftwareFrame>;
107 friend class SoftwareFrameManager;
108
109 SoftwareFrame(
110 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
111 uint32 output_surface_id,
112 unsigned frame_id,
113 gfx::Size frame_size_dip,
114 gfx::Size frame_size_pixels,
115 scoped_ptr<base::SharedMemory> shared_memory);
116 ~SoftwareFrame();
117
118 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client_;
119 const uint32 output_surface_id_;
120 const unsigned frame_id_;
121 const gfx::Size frame_size_dip_;
122 const gfx::Size frame_size_pixels_;
123 scoped_ptr<base::SharedMemory> shared_memory_;
124
125 DISALLOW_COPY_AND_ASSIGN(SoftwareFrame);
126 };
127
128 SoftwareFrame::SoftwareFrame(
129 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
130 uint32 output_surface_id,
131 unsigned frame_id,
132 gfx::Size frame_size_dip,
133 gfx::Size frame_size_pixels,
134 scoped_ptr<base::SharedMemory> shared_memory)
135 : frame_manager_client_(frame_manager_client),
136 output_surface_id_(output_surface_id),
137 frame_id_(frame_id),
138 frame_size_dip_(frame_size_dip),
139 frame_size_pixels_(frame_size_pixels),
140 shared_memory_(shared_memory.Pass()) {}
141
142 SoftwareFrame::~SoftwareFrame() {
143 if (frame_manager_client_) {
144 frame_manager_client_->SoftwareFrameWasFreed(
145 output_surface_id_, frame_id_);
146 }
147 }
148
149 ////////////////////////////////////////////////////////////////////////////////
150 // SoftwareFrameManager
151
152 SoftwareFrameManager::SoftwareFrameManager(
153 base::WeakPtr<SoftwareFrameManagerClient> client)
154 : client_(client) {}
155
156 SoftwareFrameManager::~SoftwareFrameManager() {
157 DiscardCurrentFrame();
158 }
159
160 bool SoftwareFrameManager::SwapToNewFrame(
161 uint32 output_surface_id,
162 const cc::SoftwareFrameData* frame_data,
163 float frame_device_scale_factor,
164 base::ProcessHandle process_handle) {
165 const size_t size_in_bytes = 4 * frame_data->size.GetArea();
166 #ifdef OS_WIN
167 scoped_ptr<base::SharedMemory> shared_memory(
168 new base::SharedMemory(frame_data->handle, true, process_handle));
169 #else
170 scoped_ptr<base::SharedMemory> shared_memory(
171 new base::SharedMemory(frame_data->handle, true));
172 #endif
173 // The NULL handle is used in testing.
174 if (base::SharedMemory::IsHandleValid(shared_memory->handle())) {
175 if (!shared_memory->Map(size_in_bytes)) {
176 return false;
177 }
178 }
179
180 scoped_refptr<SoftwareFrame> next_frame(new SoftwareFrame(
181 client_,
182 output_surface_id,
183 frame_data->id,
184 ConvertSizeToDIP(frame_device_scale_factor, frame_data->size),
185 frame_data->size,
186 shared_memory.Pass()));
187 current_frame_.swap(next_frame);
188 return true;
189 }
190
191 bool SoftwareFrameManager::HasCurrentFrame() const {
192 return current_frame_;
193 }
194
195 void SoftwareFrameManager::DiscardCurrentFrame() {
196 if (!HasCurrentFrame())
197 return;
198 current_frame_ = NULL;
199 SoftwareFrameMemoryManager::GetInstance()->RemoveFrame(this);
200 }
201
202 void SoftwareFrameManager::SwapToNewFrameComplete(bool visible) {
203 DCHECK(HasCurrentFrame());
204 SoftwareFrameMemoryManager::GetInstance()->AddFrame(this, visible);
205 }
206
207 void SoftwareFrameManager::SetVisibility(bool visible) {
208 if (HasCurrentFrame()) {
209 SoftwareFrameMemoryManager::GetInstance()->SetFrameVisibility(this,
210 visible);
211 }
212 }
213
214 void SoftwareFrameManager::GetCurrentFrameMailbox(
215 cc::TextureMailbox* mailbox,
216 scoped_ptr<cc::SingleReleaseCallback>* callback) {
217 DCHECK(HasCurrentFrame());
218 *mailbox = cc::TextureMailbox(
219 current_frame_->shared_memory_.get(), current_frame_->frame_size_pixels_);
220 *callback = cc::SingleReleaseCallback::Create(
221 base::Bind(ReleaseMailbox, current_frame_));
222 }
223
224 const void* SoftwareFrameManager::GetCurrentFramePixels() const {
225 DCHECK(HasCurrentFrame());
226 DCHECK(base::SharedMemory::IsHandleValid(
227 current_frame_->shared_memory_->handle()));
228 return current_frame_->shared_memory_->memory();
229 }
230
231 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const {
232 DCHECK(HasCurrentFrame());
233 return current_frame_->frame_size_pixels_;
234 }
235
236 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInDIP() const {
237 DCHECK(HasCurrentFrame());
238 return current_frame_->frame_size_dip_;
239 }
240
241 void SoftwareFrameManager::EvictCurrentFrame() {
242 DCHECK(HasCurrentFrame());
243 DiscardCurrentFrame();
244 if (client_)
245 client_->ReleaseReferencesToSoftwareFrame();
246 }
247
248 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698