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