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 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 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 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 76 SoftwareFrameManager::SoftwareFrameManager( 77 base::WeakPtr<SoftwareFrameManagerClient> client) 78 : client_(client) {} 79 80 SoftwareFrameManager::~SoftwareFrameManager() { 81 DiscardCurrentFrame(); 82 } 83 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 110 bool SoftwareFrameManager::HasCurrentFrame() const { 111 return current_frame_.get() ? true : false; 112 } 113 114 void SoftwareFrameManager::DiscardCurrentFrame() { 115 if (!HasCurrentFrame()) 116 return; 117 current_frame_ = NULL; 118 RendererFrameManager::GetInstance()->RemoveFrame(this); 119 } 120 121 void SoftwareFrameManager::SwapToNewFrameComplete(bool visible) { 122 DCHECK(HasCurrentFrame()); 123 RendererFrameManager::GetInstance()->AddFrame(this, visible); 124 } 125 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 136 uint32 SoftwareFrameManager::GetCurrentFrameOutputSurfaceId() const { 137 DCHECK(HasCurrentFrame()); 138 return current_frame_->output_surface_id_; 139 } 140 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 151 void* SoftwareFrameManager::GetCurrentFramePixels() const { 152 DCHECK(HasCurrentFrame()); 153 DCHECK(current_frame_->shared_bitmap_); 154 return current_frame_->shared_bitmap_->pixels(); 155 } 156 157 float SoftwareFrameManager::GetCurrentFrameDeviceScaleFactor() const { 158 DCHECK(HasCurrentFrame()); 159 return current_frame_->frame_device_scale_factor_; 160 } 161 162 gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const { 163 DCHECK(HasCurrentFrame()); 164 return current_frame_->frame_size_pixels_; 165 } 166 167 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 173 void SoftwareFrameManager::EvictCurrentFrame() { 174 DCHECK(HasCurrentFrame()); 175 DiscardCurrentFrame(); 176 if (client_) 177 client_->ReleaseReferencesToSoftwareFrame(); 178 } 179 180 } // namespace content 181