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/debug/alias.h"
10 #include "base/numerics/safe_math.h"
11 #include "cc/resources/shared_bitmap.h"
12 #include "content/browser/renderer_host/dip_util.h"
13 #include "content/common/host_shared_bitmap_manager.h"
14 #include "content/public/browser/user_metrics.h"
15
16 namespace {
17
ReleaseMailbox(scoped_refptr<content::SoftwareFrame> frame,uint32 sync_point,bool lost_resource)18 void ReleaseMailbox(scoped_refptr<content::SoftwareFrame> frame,
19 uint32 sync_point,
20 bool lost_resource) {}
21
22 } // namespace
23
24 namespace content {
25
26 ////////////////////////////////////////////////////////////////////////////////
27 // SoftwareFrame
28
29 class CONTENT_EXPORT SoftwareFrame : public base::RefCounted<SoftwareFrame> {
30 private:
31 friend class base::RefCounted<SoftwareFrame>;
32 friend class SoftwareFrameManager;
33
34 SoftwareFrame(base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
35 uint32 output_surface_id,
36 unsigned frame_id,
37 float frame_device_scale_factor,
38 gfx::Size frame_size_pixels,
39 scoped_ptr<cc::SharedBitmap> shared_bitmap);
40 ~SoftwareFrame();
41
42 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client_;
43 const uint32 output_surface_id_;
44 const unsigned frame_id_;
45 float frame_device_scale_factor_;
46 const gfx::Size frame_size_pixels_;
47 scoped_ptr<cc::SharedBitmap> shared_bitmap_;
48
49 DISALLOW_COPY_AND_ASSIGN(SoftwareFrame);
50 };
51
SoftwareFrame(base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,uint32 output_surface_id,unsigned frame_id,float frame_device_scale_factor,gfx::Size frame_size_pixels,scoped_ptr<cc::SharedBitmap> shared_bitmap)52 SoftwareFrame::SoftwareFrame(
53 base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
54 uint32 output_surface_id,
55 unsigned frame_id,
56 float frame_device_scale_factor,
57 gfx::Size frame_size_pixels,
58 scoped_ptr<cc::SharedBitmap> shared_bitmap)
59 : frame_manager_client_(frame_manager_client),
60 output_surface_id_(output_surface_id),
61 frame_id_(frame_id),
62 frame_device_scale_factor_(frame_device_scale_factor),
63 frame_size_pixels_(frame_size_pixels),
64 shared_bitmap_(shared_bitmap.Pass()) {}
65
~SoftwareFrame()66 SoftwareFrame::~SoftwareFrame() {
67 if (frame_manager_client_) {
68 frame_manager_client_->SoftwareFrameWasFreed(
69 output_surface_id_, frame_id_);
70 }
71 }
72
73 ////////////////////////////////////////////////////////////////////////////////
74 // SoftwareFrameManager
75
SoftwareFrameManager(base::WeakPtr<SoftwareFrameManagerClient> client)76 SoftwareFrameManager::SoftwareFrameManager(
77 base::WeakPtr<SoftwareFrameManagerClient> client)
78 : client_(client) {}
79
~SoftwareFrameManager()80 SoftwareFrameManager::~SoftwareFrameManager() {
81 DiscardCurrentFrame();
82 }
83
SwapToNewFrame(uint32 output_surface_id,const cc::SoftwareFrameData * frame_data,float frame_device_scale_factor,base::ProcessHandle process_handle)84 bool SoftwareFrameManager::SwapToNewFrame(
85 uint32 output_surface_id,
86 const cc::SoftwareFrameData* frame_data,
87 float frame_device_scale_factor,
88 base::ProcessHandle process_handle) {
89 scoped_ptr<cc::SharedBitmap> shared_bitmap =
90 HostSharedBitmapManager::current()->GetSharedBitmapFromId(
91 frame_data->size, frame_data->bitmap_id);
92
93 if (!shared_bitmap) {
94 RecordAction(
95 base::UserMetricsAction("BadMessageTerminate_SharedMemoryManager1"));
96 return false;
97 }
98
99 scoped_refptr<SoftwareFrame> next_frame(
100 new SoftwareFrame(client_,
101 output_surface_id,
102 frame_data->id,
103 frame_device_scale_factor,
104 frame_data->size,
105 shared_bitmap.Pass()));
106 current_frame_.swap(next_frame);
107 return true;
108 }
109
HasCurrentFrame() const110 bool SoftwareFrameManager::HasCurrentFrame() const {
111 return current_frame_.get() ? true : false;
112 }
113
DiscardCurrentFrame()114 void SoftwareFrameManager::DiscardCurrentFrame() {
115 if (!HasCurrentFrame())
116 return;
117 current_frame_ = NULL;
118 RendererFrameManager::GetInstance()->RemoveFrame(this);
119 }
120
SwapToNewFrameComplete(bool visible)121 void SoftwareFrameManager::SwapToNewFrameComplete(bool visible) {
122 DCHECK(HasCurrentFrame());
123 RendererFrameManager::GetInstance()->AddFrame(this, visible);
124 }
125
SetVisibility(bool visible)126 void SoftwareFrameManager::SetVisibility(bool visible) {
127 if (HasCurrentFrame()) {
128 if (visible) {
129 RendererFrameManager::GetInstance()->LockFrame(this);
130 } else {
131 RendererFrameManager::GetInstance()->UnlockFrame(this);
132 }
133 }
134 }
135
GetCurrentFrameOutputSurfaceId() const136 uint32 SoftwareFrameManager::GetCurrentFrameOutputSurfaceId() const {
137 DCHECK(HasCurrentFrame());
138 return current_frame_->output_surface_id_;
139 }
140
GetCurrentFrameMailbox(cc::TextureMailbox * mailbox,scoped_ptr<cc::SingleReleaseCallback> * callback)141 void SoftwareFrameManager::GetCurrentFrameMailbox(
142 cc::TextureMailbox* mailbox,
143 scoped_ptr<cc::SingleReleaseCallback>* callback) {
144 DCHECK(HasCurrentFrame());
145 *mailbox = cc::TextureMailbox(current_frame_->shared_bitmap_->memory(),
146 current_frame_->frame_size_pixels_);
147 *callback = cc::SingleReleaseCallback::Create(
148 base::Bind(ReleaseMailbox, current_frame_));
149 }
150
GetCurrentFramePixels() const151 void* SoftwareFrameManager::GetCurrentFramePixels() const {
152 DCHECK(HasCurrentFrame());
153 DCHECK(current_frame_->shared_bitmap_);
154 return current_frame_->shared_bitmap_->pixels();
155 }
156
GetCurrentFrameDeviceScaleFactor() const157 float SoftwareFrameManager::GetCurrentFrameDeviceScaleFactor() const {
158 DCHECK(HasCurrentFrame());
159 return current_frame_->frame_device_scale_factor_;
160 }
161
GetCurrentFrameSizeInPixels() const162 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const {
163 DCHECK(HasCurrentFrame());
164 return current_frame_->frame_size_pixels_;
165 }
166
GetCurrentFrameSizeInDIP() const167 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInDIP() const {
168 DCHECK(HasCurrentFrame());
169 return ConvertSizeToDIP(current_frame_->frame_device_scale_factor_,
170 current_frame_->frame_size_pixels_);
171 }
172
EvictCurrentFrame()173 void SoftwareFrameManager::EvictCurrentFrame() {
174 DCHECK(HasCurrentFrame());
175 DiscardCurrentFrame();
176 if (client_)
177 client_->ReleaseReferencesToSoftwareFrame();
178 }
179
180 } // namespace content
181