Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / software_frame_manager.cc
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 "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                     uint32 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     float frame_device_scale_factor,
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   float frame_device_scale_factor_;
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     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),
59       frame_id_(frame_id),
60       frame_device_scale_factor_(frame_device_scale_factor),
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(
104           base::UserMetricsAction("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(
111           base::UserMetricsAction("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(
118           base::UserMetricsAction("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       frame_device_scale_factor,
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   RendererFrameManager::GetInstance()->RemoveFrame(this);
144 }
145
146 void SoftwareFrameManager::SwapToNewFrameComplete(bool visible) {
147   DCHECK(HasCurrentFrame());
148   RendererFrameManager::GetInstance()->AddFrame(this, visible);
149 }
150
151 void SoftwareFrameManager::SetVisibility(bool visible) {
152   if (HasCurrentFrame()) {
153     if (visible) {
154       RendererFrameManager::GetInstance()->LockFrame(this);
155     } else {
156       RendererFrameManager::GetInstance()->UnlockFrame(this);
157     }
158   }
159 }
160
161 uint32 SoftwareFrameManager::GetCurrentFrameOutputSurfaceId() const {
162   DCHECK(HasCurrentFrame());
163   return current_frame_->output_surface_id_;
164 }
165
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_));
174 }
175
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();
181 }
182
183 float SoftwareFrameManager::GetCurrentFrameDeviceScaleFactor() const {
184   DCHECK(HasCurrentFrame());
185   return current_frame_->frame_device_scale_factor_;
186 }
187
188 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const {
189   DCHECK(HasCurrentFrame());
190   return current_frame_->frame_size_pixels_;
191 }
192
193 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInDIP() const {
194   DCHECK(HasCurrentFrame());
195   return ConvertSizeToDIP(current_frame_->frame_device_scale_factor_,
196                           current_frame_->frame_size_pixels_);
197 }
198
199 void SoftwareFrameManager::EvictCurrentFrame() {
200   DCHECK(HasCurrentFrame());
201   DiscardCurrentFrame();
202   if (client_)
203     client_->ReleaseReferencesToSoftwareFrame();
204 }
205
206 }  // namespace content