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.
5 #include "content/browser/renderer_host/software_frame_manager.h"
8 #include "base/callback_helpers.h"
9 #include "base/debug/alias.h"
10 #include "content/browser/renderer_host/dip_util.h"
11 #include "content/public/browser/user_metrics.h"
15 void ReleaseMailbox(scoped_refptr
<content::SoftwareFrame
> frame
,
17 bool lost_resource
) {}
23 ////////////////////////////////////////////////////////////////////////////////
26 class CONTENT_EXPORT SoftwareFrame
: public base::RefCounted
<SoftwareFrame
> {
28 friend class base::RefCounted
<SoftwareFrame
>;
29 friend class SoftwareFrameManager
;
32 base::WeakPtr
<SoftwareFrameManagerClient
> frame_manager_client
,
33 uint32 output_surface_id
,
35 float frame_device_scale_factor
,
36 gfx::Size frame_size_pixels
,
37 scoped_ptr
<base::SharedMemory
> shared_memory
);
40 base::WeakPtr
<SoftwareFrameManagerClient
> frame_manager_client_
;
41 const uint32 output_surface_id_
;
42 const unsigned frame_id_
;
43 float frame_device_scale_factor_
;
44 const gfx::Size frame_size_pixels_
;
45 scoped_ptr
<base::SharedMemory
> shared_memory_
;
47 DISALLOW_COPY_AND_ASSIGN(SoftwareFrame
);
50 SoftwareFrame::SoftwareFrame(
51 base::WeakPtr
<SoftwareFrameManagerClient
> frame_manager_client
,
52 uint32 output_surface_id
,
54 float frame_device_scale_factor
,
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
),
60 frame_device_scale_factor_(frame_device_scale_factor
),
61 frame_size_pixels_(frame_size_pixels
),
62 shared_memory_(shared_memory
.Pass()) {}
64 SoftwareFrame::~SoftwareFrame() {
65 if (frame_manager_client_
) {
66 frame_manager_client_
->SoftwareFrameWasFreed(
67 output_surface_id_
, frame_id_
);
71 ////////////////////////////////////////////////////////////////////////////////
72 // SoftwareFrameManager
74 SoftwareFrameManager::SoftwareFrameManager(
75 base::WeakPtr
<SoftwareFrameManagerClient
> client
)
78 SoftwareFrameManager::~SoftwareFrameManager() {
79 DiscardCurrentFrame();
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
) {
89 scoped_ptr
<base::SharedMemory
> shared_memory(
90 new base::SharedMemory(frame_data
->handle
, true,
93 scoped_ptr
<base::SharedMemory
> shared_memory(
94 new base::SharedMemory(frame_data
->handle
, true));
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();
101 if (!shared_memory
->Map(0)) {
102 DLOG(ERROR
) << "Unable to map renderer memory.";
104 UserMetricsAction("BadMessageTerminate_SharedMemoryManager1"));
108 if (shared_memory
->mapped_size() < size_in_bytes
) {
109 DLOG(ERROR
) << "Shared memory too small for given rectangle";
111 UserMetricsAction("BadMessageTerminate_SharedMemoryManager2"));
115 if (!shared_memory
->Map(size_in_bytes
)) {
116 DLOG(ERROR
) << "Unable to map renderer memory.";
118 UserMetricsAction("BadMessageTerminate_SharedMemoryManager1"));
124 scoped_refptr
<SoftwareFrame
> next_frame(new SoftwareFrame(
128 frame_device_scale_factor
,
130 shared_memory
.Pass()));
131 current_frame_
.swap(next_frame
);
135 bool SoftwareFrameManager::HasCurrentFrame() const {
136 return current_frame_
.get() ? true : false;
139 void SoftwareFrameManager::DiscardCurrentFrame() {
140 if (!HasCurrentFrame())
142 current_frame_
= NULL
;
143 RendererFrameManager::GetInstance()->RemoveFrame(this);
146 void SoftwareFrameManager::SwapToNewFrameComplete(bool visible
) {
147 DCHECK(HasCurrentFrame());
148 RendererFrameManager::GetInstance()->AddFrame(this, visible
);
151 void SoftwareFrameManager::SetVisibility(bool visible
) {
152 if (HasCurrentFrame()) {
154 RendererFrameManager::GetInstance()->LockFrame(this);
156 RendererFrameManager::GetInstance()->UnlockFrame(this);
161 uint32
SoftwareFrameManager::GetCurrentFrameOutputSurfaceId() const {
162 DCHECK(HasCurrentFrame());
163 return current_frame_
->output_surface_id_
;
166 void SoftwareFrameManager::GetCurrentFrameMailbox(
167 cc::TextureMailbox
* mailbox
,
168 scoped_ptr
<cc::SingleReleaseCallback
>* callback
) {
169 DCHECK(HasCurrentFrame());
170 *mailbox
= cc::TextureMailbox(
171 current_frame_
->shared_memory_
.get(), current_frame_
->frame_size_pixels_
);
172 *callback
= cc::SingleReleaseCallback::Create(
173 base::Bind(ReleaseMailbox
, current_frame_
));
176 void* SoftwareFrameManager::GetCurrentFramePixels() const {
177 DCHECK(HasCurrentFrame());
178 DCHECK(base::SharedMemory::IsHandleValid(
179 current_frame_
->shared_memory_
->handle()));
180 return current_frame_
->shared_memory_
->memory();
183 float SoftwareFrameManager::GetCurrentFrameDeviceScaleFactor() const {
184 DCHECK(HasCurrentFrame());
185 return current_frame_
->frame_device_scale_factor_
;
188 gfx::Size
SoftwareFrameManager::GetCurrentFrameSizeInPixels() const {
189 DCHECK(HasCurrentFrame());
190 return current_frame_
->frame_size_pixels_
;
193 gfx::Size
SoftwareFrameManager::GetCurrentFrameSizeInDIP() const {
194 DCHECK(HasCurrentFrame());
195 return ConvertSizeToDIP(current_frame_
->frame_device_scale_factor_
,
196 current_frame_
->frame_size_pixels_
);
199 void SoftwareFrameManager::EvictCurrentFrame() {
200 DCHECK(HasCurrentFrame());
201 DiscardCurrentFrame();
203 client_
->ReleaseReferencesToSoftwareFrame();
206 } // namespace content