// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/browser/renderer_host/software_frame_manager.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "base/debug/alias.h" #include "base/numerics/safe_math.h" #include "cc/resources/shared_bitmap.h" #include "content/browser/renderer_host/dip_util.h" #include "content/common/host_shared_bitmap_manager.h" #include "content/public/browser/user_metrics.h" namespace { void ReleaseMailbox(scoped_refptr frame, uint32 sync_point, bool lost_resource) {} } // namespace namespace content { //////////////////////////////////////////////////////////////////////////////// // SoftwareFrame class CONTENT_EXPORT SoftwareFrame : public base::RefCounted { private: friend class base::RefCounted; friend class SoftwareFrameManager; SoftwareFrame(base::WeakPtr frame_manager_client, uint32 output_surface_id, unsigned frame_id, float frame_device_scale_factor, gfx::Size frame_size_pixels, scoped_ptr shared_bitmap); ~SoftwareFrame(); base::WeakPtr frame_manager_client_; const uint32 output_surface_id_; const unsigned frame_id_; float frame_device_scale_factor_; const gfx::Size frame_size_pixels_; scoped_ptr shared_bitmap_; DISALLOW_COPY_AND_ASSIGN(SoftwareFrame); }; SoftwareFrame::SoftwareFrame( base::WeakPtr frame_manager_client, uint32 output_surface_id, unsigned frame_id, float frame_device_scale_factor, gfx::Size frame_size_pixels, scoped_ptr shared_bitmap) : frame_manager_client_(frame_manager_client), output_surface_id_(output_surface_id), frame_id_(frame_id), frame_device_scale_factor_(frame_device_scale_factor), frame_size_pixels_(frame_size_pixels), shared_bitmap_(shared_bitmap.Pass()) {} SoftwareFrame::~SoftwareFrame() { if (frame_manager_client_) { frame_manager_client_->SoftwareFrameWasFreed( output_surface_id_, frame_id_); } } //////////////////////////////////////////////////////////////////////////////// // SoftwareFrameManager SoftwareFrameManager::SoftwareFrameManager( base::WeakPtr client) : client_(client) {} SoftwareFrameManager::~SoftwareFrameManager() { DiscardCurrentFrame(); } bool SoftwareFrameManager::SwapToNewFrame( uint32 output_surface_id, const cc::SoftwareFrameData* frame_data, float frame_device_scale_factor, base::ProcessHandle process_handle) { scoped_ptr shared_bitmap = HostSharedBitmapManager::current()->GetSharedBitmapFromId( frame_data->size, frame_data->bitmap_id); if (!shared_bitmap) { RecordAction( base::UserMetricsAction("BadMessageTerminate_SharedMemoryManager1")); return false; } scoped_refptr next_frame( new SoftwareFrame(client_, output_surface_id, frame_data->id, frame_device_scale_factor, frame_data->size, shared_bitmap.Pass())); current_frame_.swap(next_frame); return true; } bool SoftwareFrameManager::HasCurrentFrame() const { return current_frame_.get() ? true : false; } void SoftwareFrameManager::DiscardCurrentFrame() { if (!HasCurrentFrame()) return; current_frame_ = NULL; RendererFrameManager::GetInstance()->RemoveFrame(this); } void SoftwareFrameManager::SwapToNewFrameComplete(bool visible) { DCHECK(HasCurrentFrame()); RendererFrameManager::GetInstance()->AddFrame(this, visible); } void SoftwareFrameManager::SetVisibility(bool visible) { if (HasCurrentFrame()) { if (visible) { RendererFrameManager::GetInstance()->LockFrame(this); } else { RendererFrameManager::GetInstance()->UnlockFrame(this); } } } uint32 SoftwareFrameManager::GetCurrentFrameOutputSurfaceId() const { DCHECK(HasCurrentFrame()); return current_frame_->output_surface_id_; } void SoftwareFrameManager::GetCurrentFrameMailbox( cc::TextureMailbox* mailbox, scoped_ptr* callback) { DCHECK(HasCurrentFrame()); *mailbox = cc::TextureMailbox(current_frame_->shared_bitmap_->memory(), current_frame_->frame_size_pixels_); *callback = cc::SingleReleaseCallback::Create( base::Bind(ReleaseMailbox, current_frame_)); } void* SoftwareFrameManager::GetCurrentFramePixels() const { DCHECK(HasCurrentFrame()); DCHECK(current_frame_->shared_bitmap_); return current_frame_->shared_bitmap_->pixels(); } float SoftwareFrameManager::GetCurrentFrameDeviceScaleFactor() const { DCHECK(HasCurrentFrame()); return current_frame_->frame_device_scale_factor_; } gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const { DCHECK(HasCurrentFrame()); return current_frame_->frame_size_pixels_; } gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInDIP() const { DCHECK(HasCurrentFrame()); return ConvertSizeToDIP(current_frame_->frame_device_scale_factor_, current_frame_->frame_size_pixels_); } void SoftwareFrameManager::EvictCurrentFrame() { DCHECK(HasCurrentFrame()); DiscardCurrentFrame(); if (client_) client_->ReleaseReferencesToSoftwareFrame(); } } // namespace content