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

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

Issue 25942002: Make software compositing work on Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Touch-ups 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 (c) 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 "software_framebuffer.h"
6
7 #include "cc/output/compositor_frame_ack.h"
8 #include "content/browser/renderer_host/dip_util.h"
9 #include "content/browser/renderer_host/frame_memory_manager.h"
10 #include "content/public/browser/render_process_host.h"
11
12 namespace content {
13
14 class MemoryHolder : public base::RefCounted<MemoryHolder> {
15 public:
16 MemoryHolder(scoped_ptr<base::SharedMemory> shared_memory,
17 gfx::Size frame_size,
18 float frame_scale_factor,
19 base::Callback<void()> callback)
20 : shared_memory_(shared_memory.Pass()),
21 frame_size_(frame_size),
22 frame_scale_factor_(frame_scale_factor),
23 callback_(callback) {}
24
25 void GetMailbox(cc::TextureMailbox* mailbox,
26 scoped_ptr<cc::SingleReleaseCallback>* release_callback) {
27 *mailbox = cc::TextureMailbox(shared_memory_.get(), frame_size_);
28 *release_callback = cc::SingleReleaseCallback::Create(
29 base::Bind(ReleaseMailbox, make_scoped_refptr(this)));
30 }
31 const gfx::Size& GetSizeInPixels() const { return frame_size_; }
32 float GetScaleFactor() const { return frame_scale_factor_; }
33 const void* GetPixels() const { return shared_memory_->memory(); }
34
35 private:
36 friend class base::RefCounted<MemoryHolder>;
37 ~MemoryHolder() { callback_.Run(); }
38
39 static void ReleaseMailbox(scoped_refptr<MemoryHolder> holder,
40 unsigned sync_point,
41 bool lost_resource) {}
42
43 scoped_ptr<base::SharedMemory> shared_memory_;
44 gfx::Size frame_size_;
45 float frame_scale_factor_;
46 base::Callback<void()> callback_;
47 };
48
49 SoftwareFramebuffer::SoftwareFramebuffer(
50 SoftwareFramebufferClient* client,
51 RenderWidgetHostImpl* render_widget_host_impl)
52 : client_(client), render_widget_host_impl_(render_widget_host_impl) {}
53
54 SoftwareFramebuffer::~SoftwareFramebuffer() {
55 client_ = NULL;
56 render_widget_host_impl_ = NULL;
57 DiscardCurrentFrame();
58 }
59
60 void SoftwareFramebuffer::WasShown() {
61 if (framebuffer_holder_)
62 FrameMemoryManager::GetInstance()->SetFrameVisibility(this, true);
63 }
64
65 void SoftwareFramebuffer::WasHidden() {
66 if (framebuffer_holder_)
67 FrameMemoryManager::GetInstance()->SetFrameVisibility(this, false);
68 }
69
70 void SoftwareFramebuffer::DiscardCurrentFrame() {
71 FrameMemoryManager::GetInstance()->RemoveFrame(this);
72 framebuffer_holder_ = NULL;
73 }
74
75 void SoftwareFramebuffer::GetCurrentFrameMailbox(
76 cc::TextureMailbox* mailbox,
77 scoped_ptr<cc::SingleReleaseCallback>* release_callback) const {
78 DCHECK(framebuffer_holder_);
79 return framebuffer_holder_->GetMailbox(mailbox,
80 release_callback);
81 }
82
83 gfx::Size SoftwareFramebuffer::GetCurrentFrameSizeInPixels() const {
84 DCHECK(framebuffer_holder_);
85 return framebuffer_holder_->GetSizeInPixels();
86 }
87
88 gfx::Size SoftwareFramebuffer::GetCurrentFrameSizeInDIP() const {
89 DCHECK(framebuffer_holder_);
90 return ConvertSizeToDIP(framebuffer_holder_->GetScaleFactor(),
91 framebuffer_holder_->GetSizeInPixels());
92 }
93
94 const void* SoftwareFramebuffer::GetCurrentFramePixels() const {
95 DCHECK(framebuffer_holder_);
96 return framebuffer_holder_->GetPixels();
97 }
98
99 void SoftwareFramebuffer::SwapToNewFrame(
100 uint32 output_surface_id,
101 const cc::SoftwareFrameData* frame_data,
102 float frame_scale_factor) {
103 const gfx::Size& frame_size = frame_data->size;
104 const size_t size_in_bytes = 4 * frame_size.GetArea();
105
106 #ifdef OS_WIN
107 scoped_ptr<base::SharedMemory> shared_memory(
108 new base::SharedMemory(frame_data->handle, true,
109 render_widget_host_impl_->GetProcess()->GetHandle()));
110 #else
111 scoped_ptr<base::SharedMemory> shared_memory(
112 new base::SharedMemory(frame_data->handle, true));
113 #endif
114
115 if (!shared_memory->Map(size_in_bytes)) {
116 render_widget_host_impl_->GetProcess()->ReceivedBadMessage();
117 framebuffer_holder_ = NULL;
118 return;
119 }
120
121 scoped_refptr<MemoryHolder> holder(new MemoryHolder(
122 shared_memory.Pass(),
123 frame_size,
124 frame_scale_factor,
125 base::Bind(&SoftwareFramebuffer::ReleaseSoftwareFrame,
126 AsWeakPtr(),
127 output_surface_id,
128 frame_data->id)));
129 framebuffer_holder_.swap(holder);
130
131 FrameMemoryManager::GetInstance()->AddFrame(
132 this, !render_widget_host_impl_->is_hidden());
133 }
134
135 void SoftwareFramebuffer::SendSoftwareFrameAck(uint32 output_surface_id) {
136 unsigned software_frame_id = 0;
137 if (!released_software_frames_.empty()) {
138 unsigned released_output_surface_id =
139 released_software_frames_.back().output_surface_id;
140 if (released_output_surface_id == output_surface_id) {
141 software_frame_id = released_software_frames_.back().frame_id;
142 released_software_frames_.pop_back();
143 }
144 }
145
146 cc::CompositorFrameAck ack;
147 ack.last_software_frame_id = software_frame_id;
148 if (render_widget_host_impl_) {
149 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
piman 2013/10/08 02:58:38 I would really prefer if the message sending logic
ccameron 2013/10/22 07:15:55 I did essentially this in the new version. The cal
150 render_widget_host_impl_->GetRoutingID(), output_surface_id,
151 render_widget_host_impl_->GetProcess()->GetID(), ack);
152 }
153 SendReclaimSoftwareFrames();
154 }
155
156 void SoftwareFramebuffer::SendReclaimSoftwareFrames() {
157 while (!released_software_frames_.empty()) {
158 cc::CompositorFrameAck ack;
159 ack.last_software_frame_id = released_software_frames_.back().frame_id;
160 if (render_widget_host_impl_) {
161 RenderWidgetHostImpl::SendReclaimCompositorResources(
162 render_widget_host_impl_->GetRoutingID(),
163 released_software_frames_.back().output_surface_id,
164 render_widget_host_impl_->GetProcess()->GetID(),
165 ack);
166 }
167 released_software_frames_.pop_back();
168 }
169 }
170
171 void SoftwareFramebuffer::ReleaseSoftwareFrame(
172 uint32 output_surface_id,
173 unsigned software_frame_id) {
174 SendReclaimSoftwareFrames();
175 released_software_frames_.push_back(
176 ReleasedFrameInfo(output_surface_id, software_frame_id));
177 }
178
179 void SoftwareFramebuffer::ReleaseCurrentFrame() {
180 DCHECK(framebuffer_holder_);
181
182 DiscardCurrentFrame();
183
184 if (client_)
185 client_->CurrentSoftwareFrameWasDiscarded();
186 }
187
188 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698