software_frame_manager.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file.
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/renderer_host/software_frame_manager.h"
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/bind.h"
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/callback_helpers.h"
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/debug/alias.h"
101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/renderer_host/dip_util.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace {
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReleaseMailbox(scoped_refptr<content::SoftwareFrame> frame,
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                    unsigned sync_point,
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                    bool lost_resource) {}
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace content {
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// SoftwareFrame
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class CONTENT_EXPORT SoftwareFrame : public base::RefCounted<SoftwareFrame> {
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private:
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  friend class base::RefCounted<SoftwareFrame>;
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  friend class SoftwareFrameManager;
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SoftwareFrame(
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    uint32 output_surface_id,
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    unsigned frame_id,
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Size frame_size_dip,
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Size frame_size_pixels,
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<base::SharedMemory> shared_memory);
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ~SoftwareFrame();
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client_;
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const uint32 output_surface_id_;
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const unsigned frame_id_;
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const gfx::Size frame_size_dip_;
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const gfx::Size frame_size_pixels_;
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_memory_;
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SoftwareFrame);
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)SoftwareFrame::SoftwareFrame(
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    uint32 output_surface_id,
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    unsigned frame_id,
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Size frame_size_dip,
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Size frame_size_pixels,
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<base::SharedMemory> shared_memory)
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : frame_manager_client_(frame_manager_client),
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      output_surface_id_(output_surface_id),
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      frame_id_(frame_id),
601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      frame_size_dip_(frame_size_dip),
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      frame_size_pixels_(frame_size_pixels),
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      shared_memory_(shared_memory.Pass()) {}
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)SoftwareFrame::~SoftwareFrame() {
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (frame_manager_client_) {
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    frame_manager_client_->SoftwareFrameWasFreed(
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        output_surface_id_, frame_id_);
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// SoftwareFrameManager
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)SoftwareFrameManager::SoftwareFrameManager(
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::WeakPtr<SoftwareFrameManagerClient> client)
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      : client_(client) {}
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)SoftwareFrameManager::~SoftwareFrameManager() {
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DiscardCurrentFrame();
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool SoftwareFrameManager::SwapToNewFrame(
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    uint32 output_surface_id,
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const cc::SoftwareFrameData* frame_data,
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    float frame_device_scale_factor,
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::ProcessHandle process_handle) {
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifdef OS_WIN
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_memory(
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new base::SharedMemory(frame_data->handle, true,
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             process_handle));
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#else
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_memory(
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new base::SharedMemory(frame_data->handle, true));
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The NULL handle is used in testing.
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (base::SharedMemory::IsHandleValid(shared_memory->handle())) {
991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const size_t size_in_bytes = 4 * frame_data->size.GetArea();
1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifdef OS_WIN
1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!shared_memory->Map(0)) {
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      DLOG(ERROR) << "Unable to map renderer memory.";
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      RecordAction(
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          UserMetricsAction("BadMessageTerminate_SharedMemoryManager1"));
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return false;
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (shared_memory->mapped_size() < size_in_bytes) {
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      DLOG(ERROR) << "Shared memory too small for given rectangle";
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      RecordAction(
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          UserMetricsAction("BadMessageTerminate_SharedMemoryManager2"));
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return false;
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#else
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!shared_memory->Map(size_in_bytes)) {
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      DLOG(ERROR) << "Unable to map renderer memory.";
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      RecordAction(
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          UserMetricsAction("BadMessageTerminate_SharedMemoryManager1"));
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return false;
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<SoftwareFrame> next_frame(new SoftwareFrame(
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      client_,
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      output_surface_id,
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      frame_data->id,
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ConvertSizeToDIP(frame_device_scale_factor, frame_data->size),
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      frame_data->size,
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      shared_memory.Pass()));
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  current_frame_.swap(next_frame);
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return true;
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool SoftwareFrameManager::HasCurrentFrame() const {
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return current_frame_.get() ? true : false;
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SoftwareFrameManager::DiscardCurrentFrame() {
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!HasCurrentFrame())
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  current_frame_ = NULL;
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RendererFrameManager::GetInstance()->RemoveFrame(this);
1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SoftwareFrameManager::SwapToNewFrameComplete(bool visible) {
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(HasCurrentFrame());
1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RendererFrameManager::GetInstance()->AddFrame(this, visible);
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SoftwareFrameManager::SetVisibility(bool visible) {
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (HasCurrentFrame()) {
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    RendererFrameManager::GetInstance()->SetFrameVisibility(this, visible);
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SoftwareFrameManager::GetCurrentFrameMailbox(
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    cc::TextureMailbox* mailbox,
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<cc::SingleReleaseCallback>* callback) {
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(HasCurrentFrame());
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *mailbox = cc::TextureMailbox(
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      current_frame_->shared_memory_.get(), current_frame_->frame_size_pixels_);
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *callback = cc::SingleReleaseCallback::Create(
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::Bind(ReleaseMailbox, current_frame_));
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const void* SoftwareFrameManager::GetCurrentFramePixels() const {
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(HasCurrentFrame());
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(base::SharedMemory::IsHandleValid(
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      current_frame_->shared_memory_->handle()));
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return current_frame_->shared_memory_->memory();
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const {
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(HasCurrentFrame());
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return current_frame_->frame_size_pixels_;
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInDIP() const {
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(HasCurrentFrame());
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return current_frame_->frame_size_dip_;
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SoftwareFrameManager::EvictCurrentFrame() {
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(HasCurrentFrame());
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DiscardCurrentFrame();
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (client_)
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    client_->ReleaseReferencesToSoftwareFrame();
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace content
192