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

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: Fix windows resolve Created 7 years, 2 months 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 "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/sys_info.h"
10 #include "content/browser/renderer_host/dip_util.h"
11 #include "content/public/browser/user_metrics.h"
12
13 namespace {
14
15 void ReleaseMailbox(scoped_refptr<content::SoftwareFrame> frame,
16 unsigned sync_point,
17 bool lost_resource) {}
18
19 } // namespace
20
21 namespace content {
22
23 ////////////////////////////////////////////////////////////////////////////////
24 // SoftwareFrame
25
26 class CONTENT_EXPORT SoftwareFrame : public base::RefCounted<SoftwareFrame> {
27 private:
28 friend class base::RefCounted<SoftwareFrame>;
29 friend class SoftwareFrameManager;
30
31 SoftwareFrame(
32 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
33 uint32 output_surface_id,
34 unsigned frame_id,
35 gfx::Size frame_size_dip,
36 gfx::Size frame_size_pixels,
37 scoped_ptr<base::SharedMemory> shared_memory);
38 ~SoftwareFrame();
39
40 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client_;
41 const uint32 output_surface_id_;
42 const unsigned frame_id_;
43 const gfx::Size frame_size_dip_;
44 const gfx::Size frame_size_pixels_;
45 scoped_ptr<base::SharedMemory> shared_memory_;
46
47 DISALLOW_COPY_AND_ASSIGN(SoftwareFrame);
48 };
49
50 SoftwareFrame::SoftwareFrame(
51 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
52 uint32 output_surface_id,
53 unsigned frame_id,
54 gfx::Size frame_size_dip,
55 gfx::Size frame_size_pixels,
56 scoped_ptr<base::SharedMemory> shared_memory)
57 : frame_manager_client_(frame_manager_client),
58 output_surface_id_(output_surface_id),
59 frame_id_(frame_id),
60 frame_size_dip_(frame_size_dip),
61 frame_size_pixels_(frame_size_pixels),
62 shared_memory_(shared_memory.Pass()) {}
63
64 SoftwareFrame::~SoftwareFrame() {
65 if (frame_manager_client_) {
66 frame_manager_client_->SoftwareFrameWasFreed(
67 output_surface_id_, frame_id_);
68 }
69 }
70
71 ////////////////////////////////////////////////////////////////////////////////
72 // SoftwareFrameManager
73
74 SoftwareFrameManager::SoftwareFrameManager(
75 base::WeakPtr<SoftwareFrameManagerClient> client)
76 : client_(client) {}
77
78 SoftwareFrameManager::~SoftwareFrameManager() {
79 DiscardCurrentFrame();
80 }
81
82 bool SoftwareFrameManager::SwapToNewFrame(
83 uint32 output_surface_id,
84 const cc::SoftwareFrameData* frame_data,
85 float frame_device_scale_factor,
86 base::ProcessHandle process_handle) {
87
88 #ifdef OS_WIN
89 scoped_ptr<base::SharedMemory> shared_memory(
90 new base::SharedMemory(frame_data->handle, true,
91 process_handle));
92 #else
93 scoped_ptr<base::SharedMemory> shared_memory(
94 new base::SharedMemory(frame_data->handle, true));
95 #endif
96
97 // The NULL handle is used in testing.
98 if (base::SharedMemory::IsHandleValid(shared_memory->handle())) {
99 const size_t size_in_bytes = 4 * frame_data->size.GetArea();
100 #ifdef OS_WIN
101 if (!shared_memory->Map(0)) {
102 DLOG(ERROR) << "Unable to map renderer memory.";
103 RecordAction(UserMetricsAction(
104 "BadMessageTerminate_SharedMemoryManager1"));
105 return false;
106 }
107
108 if (shared_memory->mapped_size() < size_in_bytes) {
109 DLOG(ERROR) << "Shared memory too small for given rectangle";
110 RecordAction(UserMetricsAction(
111 "BadMessageTerminate_SharedMemoryManager2"));
112 return false;
113 }
114 #else
115 if (!shared_memory->Map(size_in_bytes)) {
116 DLOG(ERROR) << "Unable to map renderer memory.";
117 RecordAction(UserMetricsAction(
118 "BadMessageTerminate_SharedMemoryManager1"));
119 return false;
120 }
121 #endif
122 }
123
124 scoped_refptr<SoftwareFrame> next_frame(new SoftwareFrame(
125 client_,
126 output_surface_id,
127 frame_data->id,
128 ConvertSizeToDIP(frame_device_scale_factor, frame_data->size),
129 frame_data->size,
130 shared_memory.Pass()));
131 current_frame_.swap(next_frame);
132 return true;
133 }
134
135 bool SoftwareFrameManager::HasCurrentFrame() const {
136 return current_frame_.get() ? true : false;
137 }
138
139 void SoftwareFrameManager::DiscardCurrentFrame() {
140 if (!HasCurrentFrame())
141 return;
142 current_frame_ = NULL;
143 SoftwareFrameMemoryManager::GetInstance()->RemoveFrame(this);
144 }
145
146 void SoftwareFrameManager::SwapToNewFrameComplete(bool visible) {
147 DCHECK(HasCurrentFrame());
148 SoftwareFrameMemoryManager::GetInstance()->AddFrame(this, visible);
149 }
150
151 void SoftwareFrameManager::SetVisibility(bool visible) {
152 if (HasCurrentFrame()) {
153 SoftwareFrameMemoryManager::GetInstance()->SetFrameVisibility(this,
154 visible);
155 }
156 }
157
158 void SoftwareFrameManager::GetCurrentFrameMailbox(
159 cc::TextureMailbox* mailbox,
160 scoped_ptr<cc::SingleReleaseCallback>* callback) {
161 DCHECK(HasCurrentFrame());
162 *mailbox = cc::TextureMailbox(
163 current_frame_->shared_memory_.get(), current_frame_->frame_size_pixels_);
164 *callback = cc::SingleReleaseCallback::Create(
165 base::Bind(ReleaseMailbox, current_frame_));
166 }
167
168 const void* SoftwareFrameManager::GetCurrentFramePixels() const {
169 DCHECK(HasCurrentFrame());
170 DCHECK(base::SharedMemory::IsHandleValid(
171 current_frame_->shared_memory_->handle()));
172 return current_frame_->shared_memory_->memory();
173 }
174
175 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const {
176 DCHECK(HasCurrentFrame());
177 return current_frame_->frame_size_pixels_;
178 }
179
180 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInDIP() const {
181 DCHECK(HasCurrentFrame());
182 return current_frame_->frame_size_dip_;
183 }
184
185 void SoftwareFrameManager::EvictCurrentFrame() {
186 DCHECK(HasCurrentFrame());
187 DiscardCurrentFrame();
188 if (client_)
189 client_->ReleaseReferencesToSoftwareFrame();
190 }
191
192 ////////////////////////////////////////////////////////////////////////////////
193 // SoftwareFrameMemoryManager
194
195 SoftwareFrameMemoryManager* SoftwareFrameMemoryManager::GetInstance() {
196 return Singleton<SoftwareFrameMemoryManager>::get();
197 }
198
199 void SoftwareFrameMemoryManager::AddFrame(SoftwareFrameManager* frame,
200 bool visible) {
201 RemoveFrame(frame);
202 if (visible)
203 visible_frames_.insert(frame);
204 else
205 hidden_frames_.push_front(frame);
206 CullHiddenFrames();
207 }
208
209 void SoftwareFrameMemoryManager::RemoveFrame(SoftwareFrameManager* frame) {
210 visible_frames_.erase(frame);
211 hidden_frames_.remove(frame);
212 }
213
214 void SoftwareFrameMemoryManager::SetFrameVisibility(SoftwareFrameManager* frame,
215 bool visible) {
216 if (visible) {
217 hidden_frames_.remove(frame);
218 visible_frames_.insert(frame);
219 } else {
220 visible_frames_.erase(frame);
221 hidden_frames_.push_front(frame);
222 CullHiddenFrames();
223 }
224 }
225
226 SoftwareFrameMemoryManager::SoftwareFrameMemoryManager()
227 : max_number_of_saved_frames_(
228 std::min(5, 2 + (base::SysInfo::AmountOfPhysicalMemoryMB() / 256))) {}
229
230 SoftwareFrameMemoryManager::~SoftwareFrameMemoryManager() {}
231
232 void SoftwareFrameMemoryManager::CullHiddenFrames() {
233 while (!hidden_frames_.empty() &&
234 hidden_frames_.size() + visible_frames_.size() >
235 max_number_of_saved_frames()) {
236 size_t old_size = hidden_frames_.size();
237 // Should remove self from list.
238 hidden_frames_.back()->EvictCurrentFrame();
239 DCHECK_EQ(hidden_frames_.size() + 1, old_size);
240 }
241 }
242
243 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698