Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/compositor/delegated_frame_host.h" | 5 #include "content/browser/compositor/delegated_frame_surface_host.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "cc/output/compositor_frame.h" | 9 #include "cc/output/compositor_frame.h" |
| 10 #include "cc/output/compositor_frame_ack.h" | 10 #include "cc/output/compositor_frame_ack.h" |
| 11 #include "cc/output/copy_output_request.h" | 11 #include "cc/output/copy_output_request.h" |
| 12 #include "cc/resources/single_release_callback.h" | 12 #include "cc/resources/single_release_callback.h" |
| 13 #include "cc/resources/texture_mailbox.h" | 13 #include "cc/resources/texture_mailbox.h" |
| 14 #include "cc/surfaces/surface_factory.h" | |
| 14 #include "content/browser/compositor/resize_lock.h" | 15 #include "content/browser/compositor/resize_lock.h" |
| 15 #include "content/common/gpu/client/gl_helper.h" | 16 #include "content/common/gpu/client/gl_helper.h" |
| 16 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 17 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
| 17 #include "content/public/common/content_switches.h" | 18 #include "content/public/common/content_switches.h" |
| 18 #include "media/base/video_frame.h" | 19 #include "media/base/video_frame.h" |
| 19 #include "media/base/video_util.h" | 20 #include "media/base/video_util.h" |
| 20 #include "skia/ext/image_operations.h" | 21 #include "skia/ext/image_operations.h" |
| 21 | 22 |
| 22 namespace content { | 23 namespace content { |
| 23 | 24 |
| 24 //////////////////////////////////////////////////////////////////////////////// | 25 //////////////////////////////////////////////////////////////////////////////// |
| 25 // DelegatedFrameHostClient | 26 // DelegatedFrameSurfaceHost |
| 26 | 27 |
| 27 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { | 28 DelegatedFrameSurfaceHost::DelegatedFrameSurfaceHost( |
| 28 // On Windows and Linux, holding pointer moves will not help throttling | 29 DelegatedFrameHostClient* client) |
| 29 // resizes. | |
| 30 // TODO(piman): on Windows we need to block (nested message loop?) the | |
| 31 // WM_SIZE event. On Linux we need to throttle at the WM level using | |
| 32 // _NET_WM_SYNC_REQUEST. | |
| 33 // TODO(ccameron): Mac browser window resizing is incompletely implemented. | |
| 34 #if !defined(OS_CHROMEOS) | |
| 35 return false; | |
| 36 #else | |
| 37 return GetDelegatedFrameHost()->ShouldCreateResizeLock(); | |
| 38 #endif | |
| 39 } | |
| 40 | |
| 41 void DelegatedFrameHostClient::RequestCopyOfOutput( | |
| 42 scoped_ptr<cc::CopyOutputRequest> request) { | |
| 43 GetDelegatedFrameHost()->RequestCopyOfOutput(request.Pass()); | |
| 44 } | |
| 45 | |
| 46 //////////////////////////////////////////////////////////////////////////////// | |
| 47 // DelegatedFrameHost | |
| 48 | |
| 49 DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client) | |
| 50 : client_(client), | 30 : client_(client), |
| 51 last_output_surface_id_(0), | 31 last_output_surface_id_(0), |
| 52 pending_delegated_ack_count_(0), | 32 pending_delegated_ack_count_(0), |
| 53 skipped_frames_(false), | 33 skipped_frames_(false), |
| 54 can_lock_compositor_(YES_CAN_LOCK), | 34 can_lock_compositor_(YES_CAN_LOCK), |
| 55 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { | 35 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { |
| 56 ImageTransportFactory::GetInstance()->AddObserver(this); | 36 ImageTransportFactory::GetInstance()->AddObserver(this); |
| 57 } | 37 } |
| 58 | 38 |
| 59 void DelegatedFrameHost::WasShown() { | 39 void DelegatedFrameSurfaceHost::WasShown() { |
| 60 delegated_frame_evictor_->SetVisible(true); | 40 delegated_frame_evictor_->SetVisible(true); |
| 61 | 41 |
| 62 if (!released_front_lock_.get()) { | 42 if (!released_front_lock_.get()) { |
| 63 ui::Compositor* compositor = client_->GetCompositor(); | 43 ui::Compositor* compositor = client_->GetCompositor(); |
| 64 if (compositor) | 44 if (compositor) |
| 65 released_front_lock_ = compositor->GetCompositorLock(); | 45 released_front_lock_ = compositor->GetCompositorLock(); |
| 66 } | 46 } |
| 67 } | 47 } |
| 68 | 48 |
| 69 void DelegatedFrameHost::WasHidden() { | 49 void DelegatedFrameSurfaceHost::WasHidden() { |
| 70 delegated_frame_evictor_->SetVisible(false); | 50 delegated_frame_evictor_->SetVisible(false); |
| 71 released_front_lock_ = NULL; | 51 released_front_lock_ = NULL; |
| 72 } | 52 } |
| 73 | 53 |
| 74 void DelegatedFrameHost::MaybeCreateResizeLock() { | 54 void DelegatedFrameSurfaceHost::MaybeCreateResizeLock() { |
| 75 if (!client_->ShouldCreateResizeLock()) | 55 if (!client_->ShouldCreateResizeLock()) |
| 76 return; | 56 return; |
| 77 DCHECK(client_->GetCompositor()); | 57 DCHECK(client_->GetCompositor()); |
| 78 | 58 |
| 79 // Listen to changes in the compositor lock state. | 59 // Listen to changes in the compositor lock state. |
| 80 ui::Compositor* compositor = client_->GetCompositor(); | 60 ui::Compositor* compositor = client_->GetCompositor(); |
| 81 if (!compositor->HasObserver(this)) | 61 if (!compositor->HasObserver(this)) |
| 82 compositor->AddObserver(this); | 62 compositor->AddObserver(this); |
| 83 | 63 |
| 84 bool defer_compositor_lock = | 64 bool defer_compositor_lock = |
| 85 can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | 65 can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || |
| 86 can_lock_compositor_ == NO_PENDING_COMMIT; | 66 can_lock_compositor_ == NO_PENDING_COMMIT; |
| 87 | 67 |
| 88 if (can_lock_compositor_ == YES_CAN_LOCK) | 68 if (can_lock_compositor_ == YES_CAN_LOCK) |
| 89 can_lock_compositor_ = YES_DID_LOCK; | 69 can_lock_compositor_ = YES_DID_LOCK; |
| 90 | 70 |
| 91 resize_lock_ = client_->CreateResizeLock(defer_compositor_lock); | 71 resize_lock_ = client_->CreateResizeLock(defer_compositor_lock); |
| 92 } | 72 } |
| 93 | 73 |
| 94 bool DelegatedFrameHost::ShouldCreateResizeLock() { | 74 bool DelegatedFrameSurfaceHost::ShouldCreateResizeLock() { |
| 95 RenderWidgetHostImpl* host = client_->GetHost(); | 75 RenderWidgetHostImpl* host = client_->GetHost(); |
| 96 | 76 |
| 97 if (resize_lock_) | 77 if (resize_lock_) |
| 98 return false; | 78 return false; |
| 99 | 79 |
| 100 if (host->should_auto_resize()) | 80 if (host->should_auto_resize()) |
| 101 return false; | 81 return false; |
| 102 | 82 |
| 103 gfx::Size desired_size = client_->DesiredFrameSize(); | 83 gfx::Size desired_size = client_->DesiredFrameSize(); |
| 104 if (desired_size == current_frame_size_in_dip_ || desired_size.IsEmpty()) | 84 if (desired_size == current_frame_size_in_dip_ || desired_size.IsEmpty()) |
| 105 return false; | 85 return false; |
| 106 | 86 |
| 107 ui::Compositor* compositor = client_->GetCompositor(); | 87 ui::Compositor* compositor = client_->GetCompositor(); |
| 108 if (!compositor) | 88 if (!compositor) |
| 109 return false; | 89 return false; |
| 110 | 90 |
| 111 return true; | 91 return true; |
| 112 } | 92 } |
| 113 | 93 |
| 114 void DelegatedFrameHost::RequestCopyOfOutput( | 94 void DelegatedFrameSurfaceHost::RequestCopyOfOutput( |
| 115 scoped_ptr<cc::CopyOutputRequest> request) { | 95 scoped_ptr<cc::CopyOutputRequest> request) { |
| 116 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); | 96 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); |
| 117 } | 97 } |
| 118 | 98 |
| 119 void DelegatedFrameHost::CopyFromCompositingSurface( | 99 void DelegatedFrameSurfaceHost::CopyFromCompositingSurface( |
| 120 const gfx::Rect& src_subrect, | 100 const gfx::Rect& src_subrect, |
| 121 const gfx::Size& dst_size, | 101 const gfx::Size& dst_size, |
| 122 const base::Callback<void(bool, const SkBitmap&)>& callback, | 102 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 123 const SkColorType color_type) { | 103 const SkColorType color_type) { |
| 124 // Only ARGB888 and RGB565 supported as of now. | 104 // Only ARGB888 and RGB565 supported as of now. |
| 125 bool format_support = ((color_type == kRGB_565_SkColorType) || | 105 bool format_support = ((color_type == kRGB_565_SkColorType) || |
| 126 (color_type == kN32_SkColorType)); | 106 (color_type == kN32_SkColorType)); |
| 127 DCHECK(format_support); | 107 DCHECK(format_support); |
| 128 if (!CanCopyToBitmap()) { | 108 if (!CanCopyToBitmap()) { |
| 129 callback.Run(false, SkBitmap()); | 109 callback.Run(false, SkBitmap()); |
| 130 return; | 110 return; |
| 131 } | 111 } |
| 132 | 112 |
| 133 const gfx::Size& dst_size_in_pixel = | 113 const gfx::Size& dst_size_in_pixel = |
| 134 client_->ConvertViewSizeToPixel(dst_size); | 114 client_->ConvertViewSizeToPixel(dst_size); |
| 135 scoped_ptr<cc::CopyOutputRequest> request = | 115 scoped_ptr<cc::CopyOutputRequest> request = |
| 136 cc::CopyOutputRequest::CreateRequest(base::Bind( | 116 cc::CopyOutputRequest::CreateRequest(base::Bind( |
| 137 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, | 117 &DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceHasResult, |
| 138 dst_size_in_pixel, | 118 dst_size_in_pixel, |
| 139 color_type, | 119 color_type, |
| 140 callback)); | 120 callback)); |
| 141 gfx::Rect src_subrect_in_pixel = | 121 gfx::Rect src_subrect_in_pixel = |
| 142 ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect); | 122 ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect); |
| 143 request->set_area(src_subrect_in_pixel); | 123 request->set_area(src_subrect_in_pixel); |
| 144 client_->RequestCopyOfOutput(request.Pass()); | 124 client_->RequestCopyOfOutput(request.Pass()); |
| 145 } | 125 } |
| 146 | 126 |
| 147 void DelegatedFrameHost::CopyFromCompositingSurfaceToVideoFrame( | 127 void DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceToVideoFrame( |
| 148 const gfx::Rect& src_subrect, | 128 const gfx::Rect& src_subrect, |
| 149 const scoped_refptr<media::VideoFrame>& target, | 129 const scoped_refptr<media::VideoFrame>& target, |
| 150 const base::Callback<void(bool)>& callback) { | 130 const base::Callback<void(bool)>& callback) { |
| 151 if (!CanCopyToVideoFrame()) { | 131 if (!CanCopyToVideoFrame()) { |
| 152 callback.Run(false); | 132 callback.Run(false); |
| 153 return; | 133 return; |
| 154 } | 134 } |
| 155 | 135 |
| 156 // Try get a texture to reuse. | 136 // Try get a texture to reuse. |
| 157 scoped_refptr<OwnedMailbox> subscriber_texture; | 137 scoped_refptr<OwnedMailbox> subscriber_texture; |
| 158 if (frame_subscriber_) { | 138 if (frame_subscriber_) { |
| 159 if (!idle_frame_subscriber_textures_.empty()) { | 139 if (!idle_frame_subscriber_textures_.empty()) { |
| 160 subscriber_texture = idle_frame_subscriber_textures_.back(); | 140 subscriber_texture = idle_frame_subscriber_textures_.back(); |
| 161 idle_frame_subscriber_textures_.pop_back(); | 141 idle_frame_subscriber_textures_.pop_back(); |
| 162 } else if (GLHelper* helper = | 142 } else if (GLHelper* helper = |
| 163 ImageTransportFactory::GetInstance()->GetGLHelper()) { | 143 ImageTransportFactory::GetInstance()->GetGLHelper()) { |
| 164 subscriber_texture = new OwnedMailbox(helper); | 144 subscriber_texture = new OwnedMailbox(helper); |
| 165 } | 145 } |
| 166 } | 146 } |
| 167 | 147 |
| 168 scoped_ptr<cc::CopyOutputRequest> request = | 148 scoped_ptr<cc::CopyOutputRequest> request = |
| 169 cc::CopyOutputRequest::CreateRequest(base::Bind( | 149 cc::CopyOutputRequest::CreateRequest(base::Bind( |
| 170 &DelegatedFrameHost:: | 150 &DelegatedFrameSurfaceHost:: |
| 171 CopyFromCompositingSurfaceHasResultForVideo, | 151 CopyFromCompositingSurfaceHasResultForVideo, |
| 172 AsWeakPtr(), // For caching the ReadbackYUVInterface on this class. | 152 AsWeakPtr(), // For caching the ReadbackYUVInterface on this class. |
| 173 subscriber_texture, | 153 subscriber_texture, |
| 174 target, | 154 target, |
| 175 callback)); | 155 callback)); |
| 176 gfx::Rect src_subrect_in_pixel = | 156 gfx::Rect src_subrect_in_pixel = |
| 177 ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect); | 157 ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect); |
| 178 request->set_area(src_subrect_in_pixel); | 158 request->set_area(src_subrect_in_pixel); |
| 179 if (subscriber_texture.get()) { | 159 if (subscriber_texture.get()) { |
| 180 request->SetTextureMailbox( | 160 request->SetTextureMailbox( |
| 181 cc::TextureMailbox(subscriber_texture->mailbox(), | 161 cc::TextureMailbox(subscriber_texture->mailbox(), |
| 182 subscriber_texture->target(), | 162 subscriber_texture->target(), |
| 183 subscriber_texture->sync_point())); | 163 subscriber_texture->sync_point())); |
| 184 } | 164 } |
| 185 client_->RequestCopyOfOutput(request.Pass()); | 165 client_->RequestCopyOfOutput(request.Pass()); |
| 186 } | 166 } |
| 187 | 167 |
| 188 bool DelegatedFrameHost::CanCopyToBitmap() const { | 168 bool DelegatedFrameSurfaceHost::CanCopyToBitmap() const { |
| 189 return client_->GetCompositor() && | 169 return client_->GetCompositor() && |
| 190 client_->GetLayer()->has_external_content(); | 170 client_->GetLayer()->has_external_content(); |
| 191 } | 171 } |
| 192 | 172 |
| 193 bool DelegatedFrameHost::CanCopyToVideoFrame() const { | 173 bool DelegatedFrameSurfaceHost::CanCopyToVideoFrame() const { |
| 194 return client_->GetCompositor() && | 174 return client_->GetCompositor() && |
| 195 client_->GetLayer()->has_external_content(); | 175 client_->GetLayer()->has_external_content(); |
| 196 } | 176 } |
| 197 | 177 |
| 198 bool DelegatedFrameHost::CanSubscribeFrame() const { | 178 bool DelegatedFrameSurfaceHost::CanSubscribeFrame() const { |
| 199 return true; | 179 return true; |
| 200 } | 180 } |
| 201 | 181 |
| 202 void DelegatedFrameHost::BeginFrameSubscription( | 182 void DelegatedFrameSurfaceHost::BeginFrameSubscription( |
| 203 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { | 183 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { |
| 204 frame_subscriber_ = subscriber.Pass(); | 184 frame_subscriber_ = subscriber.Pass(); |
| 205 } | 185 } |
| 206 | 186 |
| 207 void DelegatedFrameHost::EndFrameSubscription() { | 187 void DelegatedFrameSurfaceHost::EndFrameSubscription() { |
| 208 idle_frame_subscriber_textures_.clear(); | 188 idle_frame_subscriber_textures_.clear(); |
| 209 frame_subscriber_.reset(); | 189 frame_subscriber_.reset(); |
| 210 } | 190 } |
| 211 | 191 |
| 212 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { | 192 bool DelegatedFrameSurfaceHost::HasFrameSubscriber() const { |
| 193 return frame_subscriber_; | |
| 194 } | |
| 195 | |
| 196 bool DelegatedFrameSurfaceHost::ShouldSkipFrame(gfx::Size size_in_dip) const { | |
| 213 // Should skip a frame only when another frame from the renderer is guaranteed | 197 // Should skip a frame only when another frame from the renderer is guaranteed |
| 214 // to replace it. Otherwise may cause hangs when the renderer is waiting for | 198 // to replace it. Otherwise may cause hangs when the renderer is waiting for |
| 215 // the completion of latency infos (such as when taking a Snapshot.) | 199 // the completion of latency infos (such as when taking a Snapshot.) |
| 216 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | 200 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || |
| 217 can_lock_compositor_ == NO_PENDING_COMMIT || | 201 can_lock_compositor_ == NO_PENDING_COMMIT || !resize_lock_.get()) |
| 218 !resize_lock_.get()) | |
| 219 return false; | 202 return false; |
| 220 | 203 |
| 221 return size_in_dip != resize_lock_->expected_size(); | 204 return size_in_dip != resize_lock_->expected_size(); |
| 222 } | 205 } |
| 223 | 206 |
| 224 void DelegatedFrameHost::WasResized() { | 207 void DelegatedFrameSurfaceHost::WasResized() { |
| 225 MaybeCreateResizeLock(); | 208 MaybeCreateResizeLock(); |
| 226 } | 209 } |
| 227 | 210 |
| 228 gfx::Size DelegatedFrameHost::GetRequestedRendererSize() const { | 211 gfx::Size DelegatedFrameSurfaceHost::GetRequestedRendererSize() const { |
| 229 if (resize_lock_) | 212 if (resize_lock_) |
| 230 return resize_lock_->expected_size(); | 213 return resize_lock_->expected_size(); |
| 231 else | 214 else |
| 232 return client_->DesiredFrameSize(); | 215 return client_->DesiredFrameSize(); |
| 233 } | 216 } |
| 234 | 217 |
| 235 void DelegatedFrameHost::CheckResizeLock() { | 218 void DelegatedFrameSurfaceHost::CheckResizeLock() { |
| 236 if (!resize_lock_ || | 219 if (!resize_lock_ || |
| 237 resize_lock_->expected_size() != current_frame_size_in_dip_) | 220 resize_lock_->expected_size() != current_frame_size_in_dip_) |
| 238 return; | 221 return; |
| 239 | 222 |
| 240 // Since we got the size we were looking for, unlock the compositor. But delay | 223 // Since we got the size we were looking for, unlock the compositor. But delay |
| 241 // the release of the lock until we've kicked a frame with the new texture, to | 224 // the release of the lock until we've kicked a frame with the new texture, to |
| 242 // avoid resizing the UI before we have a chance to draw a "good" frame. | 225 // avoid resizing the UI before we have a chance to draw a "good" frame. |
| 243 resize_lock_->UnlockCompositor(); | 226 resize_lock_->UnlockCompositor(); |
| 244 ui::Compositor* compositor = client_->GetCompositor(); | 227 ui::Compositor* compositor = client_->GetCompositor(); |
| 245 if (compositor) { | 228 if (compositor) { |
| 246 if (!compositor->HasObserver(this)) | 229 if (!compositor->HasObserver(this)) |
| 247 compositor->AddObserver(this); | 230 compositor->AddObserver(this); |
| 248 } | 231 } |
| 249 } | 232 } |
| 250 | 233 |
| 251 void DelegatedFrameHost::DidReceiveFrameFromRenderer() { | 234 void DelegatedFrameSurfaceHost::DidReceiveFrameFromRenderer() { |
| 252 if (frame_subscriber() && CanCopyToVideoFrame()) { | 235 if (frame_subscriber() && CanCopyToVideoFrame()) { |
| 253 const base::TimeTicks present_time = base::TimeTicks::Now(); | 236 const base::TimeTicks present_time = base::TimeTicks::Now(); |
| 254 scoped_refptr<media::VideoFrame> frame; | 237 scoped_refptr<media::VideoFrame> frame; |
| 255 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; | 238 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; |
| 256 if (frame_subscriber()->ShouldCaptureFrame(present_time, | 239 if (frame_subscriber()->ShouldCaptureFrame( |
| 257 &frame, &callback)) { | 240 present_time, &frame, &callback)) { |
| 258 CopyFromCompositingSurfaceToVideoFrame( | 241 CopyFromCompositingSurfaceToVideoFrame( |
| 259 gfx::Rect(current_frame_size_in_dip_), | 242 gfx::Rect(current_frame_size_in_dip_), |
| 260 frame, | 243 frame, |
| 261 base::Bind(callback, present_time)); | 244 base::Bind(callback, present_time)); |
| 262 } | 245 } |
| 263 } | 246 } |
| 264 } | 247 } |
| 265 | 248 |
| 266 void DelegatedFrameHost::SwapDelegatedFrame( | 249 void DelegatedFrameSurfaceHost::SwapDelegatedFrame( |
| 267 uint32 output_surface_id, | 250 uint32 output_surface_id, |
| 268 scoped_ptr<cc::DelegatedFrameData> frame_data, | 251 scoped_ptr<cc::DelegatedFrameData> frame_data, |
| 269 float frame_device_scale_factor, | 252 float frame_device_scale_factor, |
| 270 const std::vector<ui::LatencyInfo>& latency_info) { | 253 const std::vector<ui::LatencyInfo>& latency_info) { |
| 271 RenderWidgetHostImpl* host = client_->GetHost(); | 254 RenderWidgetHostImpl* host = client_->GetHost(); |
| 272 DCHECK(!frame_data->render_pass_list.empty()); | 255 DCHECK(!frame_data->render_pass_list.empty()); |
| 273 | 256 |
| 274 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); | 257 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); |
| 275 | 258 |
| 276 gfx::Size frame_size = root_pass->output_rect.size(); | 259 gfx::Size frame_size = root_pass->output_rect.size(); |
| 277 gfx::Size frame_size_in_dip = | 260 gfx::Size frame_size_in_dip = |
| 278 ConvertSizeToDIP(frame_device_scale_factor, frame_size); | 261 ConvertSizeToDIP(frame_device_scale_factor, frame_size); |
| 279 | 262 |
| 280 gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect); | 263 gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect); |
| 281 damage_rect.Intersect(gfx::Rect(frame_size)); | 264 damage_rect.Intersect(gfx::Rect(frame_size)); |
| 282 gfx::Rect damage_rect_in_dip = | 265 gfx::Rect damage_rect_in_dip = |
| 283 ConvertRectToDIP(frame_device_scale_factor, damage_rect); | 266 ConvertRectToDIP(frame_device_scale_factor, damage_rect); |
| 284 | 267 |
| 285 if (ShouldSkipFrame(frame_size_in_dip)) { | 268 if (ShouldSkipFrame(frame_size_in_dip)) { |
| 286 cc::CompositorFrameAck ack; | 269 cc::CompositorFrameAck ack; |
| 287 cc::TransferableResource::ReturnResources(frame_data->resource_list, | 270 cc::TransferableResource::ReturnResources(frame_data->resource_list, |
| 288 &ack.resources); | 271 &ack.resources); |
| 289 | 272 |
| 290 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), | 273 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), |
| 291 latency_info.begin(), latency_info.end()); | 274 latency_info.begin(), |
| 275 latency_info.end()); | |
| 292 | 276 |
| 293 RenderWidgetHostImpl::SendSwapCompositorFrameAck( | 277 RenderWidgetHostImpl::SendSwapCompositorFrameAck( |
| 294 host->GetRoutingID(), output_surface_id, | 278 host->GetRoutingID(), |
| 295 host->GetProcess()->GetID(), ack); | 279 output_surface_id, |
| 280 host->GetProcess()->GetID(), | |
| 281 ack); | |
| 296 skipped_frames_ = true; | 282 skipped_frames_ = true; |
| 297 return; | 283 return; |
| 298 } | 284 } |
| 299 | 285 |
| 300 if (skipped_frames_) { | 286 if (skipped_frames_) { |
| 301 skipped_frames_ = false; | 287 skipped_frames_ = false; |
| 302 damage_rect = gfx::Rect(frame_size); | 288 damage_rect = gfx::Rect(frame_size); |
| 303 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); | 289 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); |
| 304 | 290 |
| 305 // Give the same damage rect to the compositor. | 291 // Give the same damage rect to the compositor. |
| 306 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); | 292 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); |
| 307 root_pass->damage_rect = damage_rect; | 293 root_pass->damage_rect = damage_rect; |
| 308 } | 294 } |
| 309 | 295 |
| 310 if (output_surface_id != last_output_surface_id_) { | 296 if (output_surface_id != last_output_surface_id_) { |
| 311 // Resource ids are scoped by the output surface. | 297 // Resource ids are scoped by the output surface. |
| 312 // If the originating output surface doesn't match the last one, it | 298 // If the originating output surface doesn't match the last one, it |
| 313 // indicates the renderer's output surface may have been recreated, in which | 299 // indicates the renderer's output surface may have been recreated, in which |
| 314 // case we should recreate the DelegatedRendererLayer, to avoid matching | 300 // case we should recreate the DelegatedRendererLayer, to avoid matching |
| 315 // resources from the old one with resources from the new one which would | 301 // resources from the old one with resources from the new one which would |
| 316 // have the same id. Changing the layer to showing painted content destroys | 302 // have the same id. Changing the layer to showing painted content destroys |
| 317 // the DelegatedRendererLayer. | 303 // the DelegatedRendererLayer. |
| 318 EvictDelegatedFrame(); | 304 EvictDelegatedFrame(); |
| 319 | 305 |
| 320 // Drop the cc::DelegatedFrameResourceCollection so that we will not return | 306 // Drop the cc::DelegatedFrameResourceCollection so that we will not return |
| 321 // any resources from the old output surface with the new output surface id. | 307 // any resources from the old output surface with the new output surface id. |
| 322 if (resource_collection_.get()) { | |
| 323 resource_collection_->SetClient(NULL); | |
| 324 | |
| 325 if (resource_collection_->LoseAllResources()) | |
| 326 SendReturnedDelegatedResources(last_output_surface_id_); | |
| 327 | |
| 328 resource_collection_ = NULL; | |
| 329 } | |
| 330 last_output_surface_id_ = output_surface_id; | 308 last_output_surface_id_ = output_surface_id; |
| 331 } | 309 } |
| 332 if (frame_size.IsEmpty()) { | 310 if (frame_size.IsEmpty()) { |
| 333 DCHECK(frame_data->resource_list.empty()); | 311 DCHECK(frame_data->resource_list.empty()); |
| 334 EvictDelegatedFrame(); | 312 EvictDelegatedFrame(); |
| 335 } else { | 313 } else { |
| 336 if (!resource_collection_) { | 314 if (!surface_factory_) { |
| 337 resource_collection_ = new cc::DelegatedFrameResourceCollection; | 315 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
| 338 resource_collection_->SetClient(this); | 316 cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
| 317 id_allocator_ = factory->CreateSurfaceIdAllocator(); | |
| 318 surface_factory_ = make_scoped_ptr(new cc::SurfaceFactory(manager, this)); | |
| 339 } | 319 } |
| 340 // If the physical frame size changes, we need a new |frame_provider_|. If | 320 if (surface_id_.is_null() || frame_size != current_surface_size_ || |
| 341 // the physical frame size is the same, but the size in DIP changed, we | |
| 342 // need to adjust the scale at which the frames will be drawn, and we do | |
| 343 // this by making a new |frame_provider_| also to ensure the scale change | |
| 344 // is presented in sync with the new frame content. | |
| 345 if (!frame_provider_.get() || frame_size != frame_provider_->frame_size() || | |
| 346 frame_size_in_dip != current_frame_size_in_dip_) { | 321 frame_size_in_dip != current_frame_size_in_dip_) { |
| 347 frame_provider_ = new cc::DelegatedFrameProvider( | 322 if (!surface_id_.is_null()) |
| 348 resource_collection_.get(), frame_data.Pass()); | 323 surface_factory_->Destroy(surface_id_); |
| 349 client_->GetLayer()->SetShowDelegatedContent(frame_provider_.get(), | 324 surface_id_ = id_allocator_->GenerateId(); |
| 350 frame_size_in_dip); | 325 surface_factory_->Create(surface_id_, frame_size); |
| 351 } else { | 326 client_->GetLayer()->SetShowSurface(surface_id_, frame_size_in_dip); |
| 352 frame_provider_->SetFrameData(frame_data.Pass()); | 327 current_surface_size_ = frame_size; |
| 353 } | 328 } |
| 329 scoped_ptr<cc::CompositorFrame> compositor_frame = | |
| 330 make_scoped_ptr(new cc::CompositorFrame()); | |
| 331 compositor_frame->delegated_frame_data = frame_data.Pass(); | |
| 332 surface_factory_->SubmitFrame(surface_id_, compositor_frame.Pass()); | |
| 354 } | 333 } |
| 355 released_front_lock_ = NULL; | 334 released_front_lock_ = NULL; |
| 356 current_frame_size_in_dip_ = frame_size_in_dip; | 335 current_frame_size_in_dip_ = frame_size_in_dip; |
| 357 CheckResizeLock(); | 336 CheckResizeLock(); |
| 358 | 337 |
| 359 client_->SchedulePaintInRect(damage_rect_in_dip); | 338 client_->SchedulePaintInRect(damage_rect_in_dip); |
| 360 | 339 |
| 361 pending_delegated_ack_count_++; | 340 pending_delegated_ack_count_++; |
| 362 | 341 |
| 363 ui::Compositor* compositor = client_->GetCompositor(); | 342 ui::Compositor* compositor = client_->GetCompositor(); |
| 364 if (!compositor) { | 343 if (!compositor) { |
| 365 SendDelegatedFrameAck(output_surface_id); | 344 SendDelegatedFrameAck(output_surface_id); |
| 366 } else { | 345 } else { |
| 367 std::vector<ui::LatencyInfo>::const_iterator it; | 346 std::vector<ui::LatencyInfo>::const_iterator it; |
| 368 for (it = latency_info.begin(); it != latency_info.end(); ++it) | 347 for (it = latency_info.begin(); it != latency_info.end(); ++it) |
| 369 compositor->SetLatencyInfo(*it); | 348 compositor->SetLatencyInfo(*it); |
| 370 // If we've previously skipped any latency infos add them. | 349 // If we've previously skipped any latency infos add them. |
| 371 for (it = skipped_latency_info_list_.begin(); | 350 for (it = skipped_latency_info_list_.begin(); |
| 372 it != skipped_latency_info_list_.end(); | 351 it != skipped_latency_info_list_.end(); |
| 373 ++it) | 352 ++it) |
| 374 compositor->SetLatencyInfo(*it); | 353 compositor->SetLatencyInfo(*it); |
| 375 skipped_latency_info_list_.clear(); | 354 skipped_latency_info_list_.clear(); |
| 376 AddOnCommitCallbackAndDisableLocks( | 355 AddOnCommitCallbackAndDisableLocks( |
| 377 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, | 356 base::Bind(&DelegatedFrameSurfaceHost::SendDelegatedFrameAck, |
| 378 AsWeakPtr(), | 357 AsWeakPtr(), |
| 379 output_surface_id)); | 358 output_surface_id)); |
| 380 } | 359 } |
| 381 DidReceiveFrameFromRenderer(); | 360 DidReceiveFrameFromRenderer(); |
| 382 if (frame_provider_.get()) | 361 if (!surface_id_.is_null()) |
| 383 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); | 362 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); |
| 384 // Note: the frame may have been evicted immediately. | 363 // Note: the frame may have been evicted immediately. |
| 385 } | 364 } |
| 386 | 365 |
| 387 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { | 366 void DelegatedFrameSurfaceHost::SetLayerOwner(ui::LayerOwner* layer_owner) { |
| 367 layer_owner->set_layer_owner_delegate(this); | |
| 368 } | |
| 369 | |
| 370 cc::DelegatedFrameProvider* DelegatedFrameSurfaceHost::FrameProviderForTesting() | |
| 371 const { | |
| 372 return NULL; | |
| 373 } | |
| 374 | |
| 375 void DelegatedFrameSurfaceHost::OnCompositingDidCommitForTesting( | |
| 376 ui::Compositor* compositor) { | |
| 377 OnCompositingDidCommit(compositor); | |
| 378 } | |
| 379 | |
| 380 void DelegatedFrameSurfaceHost::SendDelegatedFrameAck( | |
| 381 uint32 output_surface_id) { | |
| 388 RenderWidgetHostImpl* host = client_->GetHost(); | 382 RenderWidgetHostImpl* host = client_->GetHost(); |
| 389 cc::CompositorFrameAck ack; | 383 cc::CompositorFrameAck ack; |
| 390 if (resource_collection_) | 384 if (!surface_returned_resources_.empty()) |
| 391 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); | 385 ack.resources.swap(surface_returned_resources_); |
| 392 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(), | 386 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(), |
| 393 output_surface_id, | 387 output_surface_id, |
| 394 host->GetProcess()->GetID(), | 388 host->GetProcess()->GetID(), |
| 395 ack); | 389 ack); |
| 396 DCHECK_GT(pending_delegated_ack_count_, 0); | 390 DCHECK_GT(pending_delegated_ack_count_, 0); |
| 397 pending_delegated_ack_count_--; | 391 pending_delegated_ack_count_--; |
| 398 } | 392 } |
| 399 | 393 |
| 400 void DelegatedFrameHost::UnusedResourcesAreAvailable() { | 394 void DelegatedFrameSurfaceHost::SendReturnedDelegatedResources( |
| 401 if (pending_delegated_ack_count_) | |
| 402 return; | |
| 403 | |
| 404 SendReturnedDelegatedResources(last_output_surface_id_); | |
| 405 } | |
| 406 | |
| 407 void DelegatedFrameHost::SendReturnedDelegatedResources( | |
| 408 uint32 output_surface_id) { | 395 uint32 output_surface_id) { |
| 409 RenderWidgetHostImpl* host = client_->GetHost(); | 396 RenderWidgetHostImpl* host = client_->GetHost(); |
| 410 DCHECK(resource_collection_); | |
| 411 | 397 |
| 412 cc::CompositorFrameAck ack; | 398 cc::CompositorFrameAck ack; |
| 413 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); | 399 if (!surface_returned_resources_.empty()) { |
|
piman
2014/07/25 01:27:42
This if can go away, the only caller is ReturnReso
| |
| 400 ack.resources.swap(surface_returned_resources_); | |
| 401 } | |
| 414 DCHECK(!ack.resources.empty()); | 402 DCHECK(!ack.resources.empty()); |
| 415 | 403 |
| 416 RenderWidgetHostImpl::SendReclaimCompositorResources( | 404 RenderWidgetHostImpl::SendReclaimCompositorResources( |
| 417 host->GetRoutingID(), | 405 host->GetRoutingID(), |
| 418 output_surface_id, | 406 output_surface_id, |
| 419 host->GetProcess()->GetID(), | 407 host->GetProcess()->GetID(), |
| 420 ack); | 408 ack); |
| 421 } | 409 } |
| 422 | 410 |
| 423 void DelegatedFrameHost::EvictDelegatedFrame() { | 411 void DelegatedFrameSurfaceHost::ReturnResources( |
| 412 const cc::ReturnedResourceArray& resources) { | |
| 413 if (resources.empty()) | |
| 414 return; | |
| 415 std::copy(resources.begin(), | |
| 416 resources.end(), | |
| 417 std::back_inserter(surface_returned_resources_)); | |
| 418 if (!pending_delegated_ack_count_) | |
| 419 SendReturnedDelegatedResources(last_output_surface_id_); | |
| 420 } | |
| 421 | |
| 422 void DelegatedFrameSurfaceHost::EvictDelegatedFrame() { | |
| 424 client_->GetLayer()->SetShowPaintedContent(); | 423 client_->GetLayer()->SetShowPaintedContent(); |
| 425 frame_provider_ = NULL; | 424 if (!surface_id_.is_null()) { |
| 425 surface_factory_->Destroy(surface_id_); | |
| 426 surface_id_ = cc::SurfaceId(); | |
| 427 } | |
| 426 delegated_frame_evictor_->DiscardedFrame(); | 428 delegated_frame_evictor_->DiscardedFrame(); |
| 427 } | 429 } |
| 428 | 430 |
| 429 // static | 431 // static |
| 430 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( | 432 void DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceHasResult( |
| 431 const gfx::Size& dst_size_in_pixel, | 433 const gfx::Size& dst_size_in_pixel, |
| 432 const SkColorType color_type, | 434 const SkColorType color_type, |
| 433 const base::Callback<void(bool, const SkBitmap&)>& callback, | 435 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 434 scoped_ptr<cc::CopyOutputResult> result) { | 436 scoped_ptr<cc::CopyOutputResult> result) { |
| 435 if (result->IsEmpty() || result->size().IsEmpty()) { | 437 if (result->IsEmpty() || result->size().IsEmpty()) { |
| 436 callback.Run(false, SkBitmap()); | 438 callback.Run(false, SkBitmap()); |
| 437 return; | 439 return; |
| 438 } | 440 } |
| 439 | 441 |
| 440 if (result->HasTexture()) { | 442 if (result->HasTexture()) { |
| 441 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, | 443 PrepareTextureCopyOutputResult( |
| 442 callback, | 444 dst_size_in_pixel, color_type, callback, result.Pass()); |
| 443 result.Pass()); | |
| 444 return; | 445 return; |
| 445 } | 446 } |
| 446 | 447 |
| 447 DCHECK(result->HasBitmap()); | 448 DCHECK(result->HasBitmap()); |
| 448 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, | 449 PrepareBitmapCopyOutputResult( |
| 449 result.Pass()); | 450 dst_size_in_pixel, color_type, callback, result.Pass()); |
| 450 } | 451 } |
| 451 | 452 |
| 452 static void CopyFromCompositingSurfaceFinished( | 453 static void CopyFromCompositingSurfaceFinished( |
| 453 const base::Callback<void(bool, const SkBitmap&)>& callback, | 454 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 454 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 455 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
| 455 scoped_ptr<SkBitmap> bitmap, | 456 scoped_ptr<SkBitmap> bitmap, |
| 456 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 457 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
| 457 bool result) { | 458 bool result) { |
| 458 bitmap_pixels_lock.reset(); | 459 bitmap_pixels_lock.reset(); |
| 459 | 460 |
| 460 uint32 sync_point = 0; | 461 uint32 sync_point = 0; |
| 461 if (result) { | 462 if (result) { |
| 462 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); | 463 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
| 463 sync_point = gl_helper->InsertSyncPoint(); | 464 sync_point = gl_helper->InsertSyncPoint(); |
| 464 } | 465 } |
| 465 bool lost_resource = sync_point == 0; | 466 bool lost_resource = sync_point == 0; |
| 466 release_callback->Run(sync_point, lost_resource); | 467 release_callback->Run(sync_point, lost_resource); |
| 467 | 468 |
| 468 callback.Run(result, *bitmap); | 469 callback.Run(result, *bitmap); |
| 469 } | 470 } |
| 470 | 471 |
| 471 // static | 472 // static |
| 472 void DelegatedFrameHost::PrepareTextureCopyOutputResult( | 473 void DelegatedFrameSurfaceHost::PrepareTextureCopyOutputResult( |
| 473 const gfx::Size& dst_size_in_pixel, | 474 const gfx::Size& dst_size_in_pixel, |
| 474 const SkColorType color_type, | 475 const SkColorType color_type, |
| 475 const base::Callback<void(bool, const SkBitmap&)>& callback, | 476 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 476 scoped_ptr<cc::CopyOutputResult> result) { | 477 scoped_ptr<cc::CopyOutputResult> result) { |
| 477 DCHECK(result->HasTexture()); | 478 DCHECK(result->HasTexture()); |
| 478 base::ScopedClosureRunner scoped_callback_runner( | 479 base::ScopedClosureRunner scoped_callback_runner( |
| 479 base::Bind(callback, false, SkBitmap())); | 480 base::Bind(callback, false, SkBitmap())); |
| 480 | 481 |
| 481 scoped_ptr<SkBitmap> bitmap(new SkBitmap); | 482 scoped_ptr<SkBitmap> bitmap(new SkBitmap); |
| 482 if (!bitmap->allocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), | 483 if (!bitmap->allocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 511 color_type, | 512 color_type, |
| 512 base::Bind(&CopyFromCompositingSurfaceFinished, | 513 base::Bind(&CopyFromCompositingSurfaceFinished, |
| 513 callback, | 514 callback, |
| 514 base::Passed(&release_callback), | 515 base::Passed(&release_callback), |
| 515 base::Passed(&bitmap), | 516 base::Passed(&bitmap), |
| 516 base::Passed(&bitmap_pixels_lock)), | 517 base::Passed(&bitmap_pixels_lock)), |
| 517 GLHelper::SCALER_QUALITY_FAST); | 518 GLHelper::SCALER_QUALITY_FAST); |
| 518 } | 519 } |
| 519 | 520 |
| 520 // static | 521 // static |
| 521 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( | 522 void DelegatedFrameSurfaceHost::PrepareBitmapCopyOutputResult( |
| 522 const gfx::Size& dst_size_in_pixel, | 523 const gfx::Size& dst_size_in_pixel, |
| 523 const SkColorType color_type, | 524 const SkColorType color_type, |
| 524 const base::Callback<void(bool, const SkBitmap&)>& callback, | 525 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 525 scoped_ptr<cc::CopyOutputResult> result) { | 526 scoped_ptr<cc::CopyOutputResult> result) { |
| 526 if (color_type != kN32_SkColorType) { | 527 if (color_type != kN32_SkColorType) { |
| 527 NOTIMPLEMENTED(); | 528 NOTIMPLEMENTED(); |
| 528 callback.Run(false, SkBitmap()); | 529 callback.Run(false, SkBitmap()); |
| 529 return; | 530 return; |
| 530 } | 531 } |
| 531 DCHECK(result->HasBitmap()); | 532 DCHECK(result->HasBitmap()); |
| 532 scoped_ptr<SkBitmap> source = result->TakeBitmap(); | 533 scoped_ptr<SkBitmap> source = result->TakeBitmap(); |
| 533 DCHECK(source); | 534 DCHECK(source); |
| 534 SkBitmap bitmap = skia::ImageOperations::Resize( | 535 SkBitmap bitmap = |
| 535 *source, | 536 skia::ImageOperations::Resize(*source, |
| 536 skia::ImageOperations::RESIZE_BEST, | 537 skia::ImageOperations::RESIZE_BEST, |
| 537 dst_size_in_pixel.width(), | 538 dst_size_in_pixel.width(), |
| 538 dst_size_in_pixel.height()); | 539 dst_size_in_pixel.height()); |
| 539 callback.Run(true, bitmap); | 540 callback.Run(true, bitmap); |
| 540 } | 541 } |
| 541 | 542 |
| 542 // static | 543 // static |
| 543 void DelegatedFrameHost::ReturnSubscriberTexture( | 544 void DelegatedFrameSurfaceHost::ReturnSubscriberTexture( |
| 544 base::WeakPtr<DelegatedFrameHost> dfh, | 545 base::WeakPtr<DelegatedFrameSurfaceHost> dfh, |
| 545 scoped_refptr<OwnedMailbox> subscriber_texture, | 546 scoped_refptr<OwnedMailbox> subscriber_texture, |
| 546 uint32 sync_point) { | 547 uint32 sync_point) { |
| 547 if (!subscriber_texture.get()) | 548 if (!subscriber_texture.get()) |
| 548 return; | 549 return; |
| 549 if (!dfh) | 550 if (!dfh) |
| 550 return; | 551 return; |
| 551 | 552 |
| 552 subscriber_texture->UpdateSyncPoint(sync_point); | 553 subscriber_texture->UpdateSyncPoint(sync_point); |
| 553 | 554 |
| 554 if (dfh->frame_subscriber_ && subscriber_texture->texture_id()) | 555 if (dfh->frame_subscriber_ && subscriber_texture->texture_id()) |
| 555 dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture); | 556 dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture); |
| 556 } | 557 } |
| 557 | 558 |
| 558 void DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo( | 559 void DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceFinishedForVideo( |
| 559 base::WeakPtr<DelegatedFrameHost> dfh, | 560 base::WeakPtr<DelegatedFrameSurfaceHost> dfh, |
| 560 const base::Callback<void(bool)>& callback, | 561 const base::Callback<void(bool)>& callback, |
| 561 scoped_refptr<OwnedMailbox> subscriber_texture, | 562 scoped_refptr<OwnedMailbox> subscriber_texture, |
| 562 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 563 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
| 563 bool result) { | 564 bool result) { |
| 564 callback.Run(result); | 565 callback.Run(result); |
| 565 | 566 |
| 566 uint32 sync_point = 0; | 567 uint32 sync_point = 0; |
| 567 if (result) { | 568 if (result) { |
| 568 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); | 569 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
| 569 sync_point = gl_helper->InsertSyncPoint(); | 570 sync_point = gl_helper->InsertSyncPoint(); |
| 570 } | 571 } |
| 571 if (release_callback) { | 572 if (release_callback) { |
| 572 // A release callback means the texture came from the compositor, so there | 573 // A release callback means the texture came from the compositor, so there |
| 573 // should be no |subscriber_texture|. | 574 // should be no |subscriber_texture|. |
| 574 DCHECK(!subscriber_texture); | 575 DCHECK(!subscriber_texture); |
| 575 bool lost_resource = sync_point == 0; | 576 bool lost_resource = sync_point == 0; |
| 576 release_callback->Run(sync_point, lost_resource); | 577 release_callback->Run(sync_point, lost_resource); |
| 577 } | 578 } |
| 578 ReturnSubscriberTexture(dfh, subscriber_texture, sync_point); | 579 ReturnSubscriberTexture(dfh, subscriber_texture, sync_point); |
| 579 } | 580 } |
| 580 | 581 |
| 581 // static | 582 // static |
| 582 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo( | 583 void DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceHasResultForVideo( |
| 583 base::WeakPtr<DelegatedFrameHost> dfh, | 584 base::WeakPtr<DelegatedFrameSurfaceHost> dfh, |
| 584 scoped_refptr<OwnedMailbox> subscriber_texture, | 585 scoped_refptr<OwnedMailbox> subscriber_texture, |
| 585 scoped_refptr<media::VideoFrame> video_frame, | 586 scoped_refptr<media::VideoFrame> video_frame, |
| 586 const base::Callback<void(bool)>& callback, | 587 const base::Callback<void(bool)>& callback, |
| 587 scoped_ptr<cc::CopyOutputResult> result) { | 588 scoped_ptr<cc::CopyOutputResult> result) { |
| 588 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); | 589 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); |
| 589 base::ScopedClosureRunner scoped_return_subscriber_texture( | 590 base::ScopedClosureRunner scoped_return_subscriber_texture( |
| 590 base::Bind(&ReturnSubscriberTexture, dfh, subscriber_texture, 0)); | 591 base::Bind(&ReturnSubscriberTexture, dfh, subscriber_texture, 0)); |
| 591 | 592 |
| 592 if (!dfh) | 593 if (!dfh) |
| 593 return; | 594 return; |
| 594 if (result->IsEmpty()) | 595 if (result->IsEmpty()) |
| 595 return; | 596 return; |
| 596 if (result->size().IsEmpty()) | 597 if (result->size().IsEmpty()) |
| 597 return; | 598 return; |
| 598 | 599 |
| 599 // Compute the dest size we want after the letterboxing resize. Make the | 600 // Compute the dest size we want after the letterboxing resize. Make the |
| 600 // coordinates and sizes even because we letterbox in YUV space | 601 // coordinates and sizes even because we letterbox in YUV space |
| 601 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to | 602 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to |
| 602 // line up correctly. | 603 // line up correctly. |
| 603 // The video frame's coded_size() and the result's size() are both physical | 604 // The video frame's coded_size() and the result's size() are both physical |
| 604 // pixels. | 605 // pixels. |
| 605 gfx::Rect region_in_frame = | 606 gfx::Rect region_in_frame = media::ComputeLetterboxRegion( |
| 606 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), | 607 gfx::Rect(video_frame->coded_size()), result->size()); |
| 607 result->size()); | |
| 608 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, | 608 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, |
| 609 region_in_frame.y() & ~1, | 609 region_in_frame.y() & ~1, |
| 610 region_in_frame.width() & ~1, | 610 region_in_frame.width() & ~1, |
| 611 region_in_frame.height() & ~1); | 611 region_in_frame.height() & ~1); |
| 612 if (region_in_frame.IsEmpty()) | 612 if (region_in_frame.IsEmpty()) |
| 613 return; | 613 return; |
| 614 | 614 |
| 615 if (!result->HasTexture()) { | 615 if (!result->HasTexture()) { |
| 616 DCHECK(result->HasBitmap()); | 616 DCHECK(result->HasBitmap()); |
| 617 scoped_ptr<SkBitmap> bitmap = result->TakeBitmap(); | 617 scoped_ptr<SkBitmap> bitmap = result->TakeBitmap(); |
| 618 // Scale the bitmap to the required size, if necessary. | 618 // Scale the bitmap to the required size, if necessary. |
| 619 SkBitmap scaled_bitmap; | 619 SkBitmap scaled_bitmap; |
| 620 if (result->size().width() != region_in_frame.width() || | 620 if (result->size().width() != region_in_frame.width() || |
| 621 result->size().height() != region_in_frame.height()) { | 621 result->size().height() != region_in_frame.height()) { |
| 622 skia::ImageOperations::ResizeMethod method = | 622 skia::ImageOperations::ResizeMethod method = |
| 623 skia::ImageOperations::RESIZE_GOOD; | 623 skia::ImageOperations::RESIZE_GOOD; |
| 624 scaled_bitmap = skia::ImageOperations::Resize(*bitmap.get(), method, | 624 scaled_bitmap = skia::ImageOperations::Resize(*bitmap.get(), |
| 625 method, | |
| 625 region_in_frame.width(), | 626 region_in_frame.width(), |
| 626 region_in_frame.height()); | 627 region_in_frame.height()); |
| 627 } else { | 628 } else { |
| 628 scaled_bitmap = *bitmap.get(); | 629 scaled_bitmap = *bitmap.get(); |
| 629 } | 630 } |
| 630 | 631 |
| 631 { | 632 { |
| 632 SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); | 633 SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); |
| 633 | 634 |
| 634 media::CopyRGBToVideoFrame( | 635 media::CopyRGBToVideoFrame( |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 685 video_frame->coded_size(), | 686 video_frame->coded_size(), |
| 686 region_in_frame, | 687 region_in_frame, |
| 687 true, | 688 true, |
| 688 true)); | 689 true)); |
| 689 yuv_readback_pipeline = dfh->yuv_readback_pipeline_.get(); | 690 yuv_readback_pipeline = dfh->yuv_readback_pipeline_.get(); |
| 690 } | 691 } |
| 691 | 692 |
| 692 ignore_result(scoped_callback_runner.Release()); | 693 ignore_result(scoped_callback_runner.Release()); |
| 693 ignore_result(scoped_return_subscriber_texture.Release()); | 694 ignore_result(scoped_return_subscriber_texture.Release()); |
| 694 base::Callback<void(bool result)> finished_callback = base::Bind( | 695 base::Callback<void(bool result)> finished_callback = base::Bind( |
| 695 &DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo, | 696 &DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceFinishedForVideo, |
| 696 dfh->AsWeakPtr(), | 697 dfh->AsWeakPtr(), |
| 697 callback, | 698 callback, |
| 698 subscriber_texture, | 699 subscriber_texture, |
| 699 base::Passed(&release_callback)); | 700 base::Passed(&release_callback)); |
| 700 yuv_readback_pipeline->ReadbackYUV(texture_mailbox.mailbox(), | 701 yuv_readback_pipeline->ReadbackYUV(texture_mailbox.mailbox(), |
| 701 texture_mailbox.sync_point(), | 702 texture_mailbox.sync_point(), |
| 702 video_frame.get(), | 703 video_frame.get(), |
| 703 finished_callback); | 704 finished_callback); |
| 704 } | 705 } |
| 705 | 706 |
| 706 //////////////////////////////////////////////////////////////////////////////// | 707 //////////////////////////////////////////////////////////////////////////////// |
| 707 // DelegatedFrameHost, ui::CompositorObserver implementation: | 708 // DelegatedFrameSurfaceHost, ui::CompositorObserver implementation: |
| 708 | 709 |
| 709 void DelegatedFrameHost::OnCompositingDidCommit( | 710 void DelegatedFrameSurfaceHost::OnCompositingDidCommit( |
| 710 ui::Compositor* compositor) { | 711 ui::Compositor* compositor) { |
| 711 RenderWidgetHostImpl* host = client_->GetHost(); | 712 RenderWidgetHostImpl* host = client_->GetHost(); |
| 712 if (can_lock_compositor_ == NO_PENDING_COMMIT) { | 713 if (can_lock_compositor_ == NO_PENDING_COMMIT) { |
| 713 can_lock_compositor_ = YES_CAN_LOCK; | 714 can_lock_compositor_ = YES_CAN_LOCK; |
| 714 if (resize_lock_.get() && resize_lock_->GrabDeferredLock()) | 715 if (resize_lock_.get() && resize_lock_->GrabDeferredLock()) |
| 715 can_lock_compositor_ = YES_DID_LOCK; | 716 can_lock_compositor_ = YES_DID_LOCK; |
| 716 } | 717 } |
| 717 RunOnCommitCallbacks(); | 718 RunOnCommitCallbacks(); |
| 718 if (resize_lock_ && | 719 if (resize_lock_ && |
| 719 resize_lock_->expected_size() == current_frame_size_in_dip_) { | 720 resize_lock_->expected_size() == current_frame_size_in_dip_) { |
| 720 resize_lock_.reset(); | 721 resize_lock_.reset(); |
| 721 host->WasResized(); | 722 host->WasResized(); |
| 722 // We may have had a resize while we had the lock (e.g. if the lock expired, | 723 // We may have had a resize while we had the lock (e.g. if the lock expired, |
| 723 // or if the UI still gave us some resizes), so make sure we grab a new lock | 724 // or if the UI still gave us some resizes), so make sure we grab a new lock |
| 724 // if necessary. | 725 // if necessary. |
| 725 MaybeCreateResizeLock(); | 726 MaybeCreateResizeLock(); |
| 726 } | 727 } |
| 727 } | 728 } |
| 728 | 729 |
| 729 void DelegatedFrameHost::OnCompositingStarted( | 730 void DelegatedFrameSurfaceHost::OnCompositingStarted( |
| 730 ui::Compositor* compositor, base::TimeTicks start_time) { | 731 ui::Compositor* compositor, |
| 732 base::TimeTicks start_time) { | |
| 731 last_draw_ended_ = start_time; | 733 last_draw_ended_ = start_time; |
| 732 } | 734 } |
| 733 | 735 |
| 734 void DelegatedFrameHost::OnCompositingEnded( | 736 void DelegatedFrameSurfaceHost::OnCompositingEnded(ui::Compositor* compositor) { |
| 737 } | |
| 738 | |
| 739 void DelegatedFrameSurfaceHost::OnCompositingAborted( | |
| 735 ui::Compositor* compositor) { | 740 ui::Compositor* compositor) { |
| 736 } | 741 } |
| 737 | 742 |
| 738 void DelegatedFrameHost::OnCompositingAborted(ui::Compositor* compositor) { | 743 void DelegatedFrameSurfaceHost::OnCompositingLockStateChanged( |
| 739 } | |
| 740 | |
| 741 void DelegatedFrameHost::OnCompositingLockStateChanged( | |
| 742 ui::Compositor* compositor) { | 744 ui::Compositor* compositor) { |
| 743 // A compositor lock that is part of a resize lock timed out. We | 745 // A compositor lock that is part of a resize lock timed out. We |
| 744 // should display a renderer frame. | 746 // should display a renderer frame. |
| 745 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { | 747 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { |
| 746 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; | 748 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; |
| 747 } | 749 } |
| 748 } | 750 } |
| 749 | 751 |
| 750 void DelegatedFrameHost::OnUpdateVSyncParameters( | 752 void DelegatedFrameSurfaceHost::OnUpdateVSyncParameters( |
| 751 base::TimeTicks timebase, | 753 base::TimeTicks timebase, |
| 752 base::TimeDelta interval) { | 754 base::TimeDelta interval) { |
| 753 RenderWidgetHostImpl* host = client_->GetHost(); | 755 RenderWidgetHostImpl* host = client_->GetHost(); |
| 754 if (client_->IsVisible()) | 756 if (client_->IsVisible()) |
| 755 host->UpdateVSyncParameters(timebase, interval); | 757 host->UpdateVSyncParameters(timebase, interval); |
| 756 } | 758 } |
| 757 | 759 |
| 758 //////////////////////////////////////////////////////////////////////////////// | 760 //////////////////////////////////////////////////////////////////////////////// |
| 759 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: | 761 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: |
| 760 | 762 |
| 761 void DelegatedFrameHost::OnLostResources() { | 763 void DelegatedFrameSurfaceHost::OnLostResources() { |
| 762 RenderWidgetHostImpl* host = client_->GetHost(); | 764 RenderWidgetHostImpl* host = client_->GetHost(); |
| 763 if (frame_provider_.get()) | 765 if (!surface_id_.is_null()) |
| 764 EvictDelegatedFrame(); | 766 EvictDelegatedFrame(); |
| 765 idle_frame_subscriber_textures_.clear(); | 767 idle_frame_subscriber_textures_.clear(); |
| 766 yuv_readback_pipeline_.reset(); | 768 yuv_readback_pipeline_.reset(); |
| 767 | 769 |
| 768 host->ScheduleComposite(); | 770 host->ScheduleComposite(); |
| 769 } | 771 } |
| 770 | 772 |
| 771 //////////////////////////////////////////////////////////////////////////////// | 773 //////////////////////////////////////////////////////////////////////////////// |
| 772 // DelegatedFrameHost, private: | 774 // DelegatedFrameSurfaceHost, private: |
| 773 | 775 |
| 774 DelegatedFrameHost::~DelegatedFrameHost() { | 776 DelegatedFrameSurfaceHost::~DelegatedFrameSurfaceHost() { |
| 775 ImageTransportFactory::GetInstance()->RemoveObserver(this); | 777 ImageTransportFactory::GetInstance()->RemoveObserver(this); |
| 776 | 778 |
| 777 if (resource_collection_.get()) | 779 if (!surface_id_.is_null()) |
| 778 resource_collection_->SetClient(NULL); | 780 surface_factory_->Destroy(surface_id_); |
| 779 | |
| 780 DCHECK(!vsync_manager_); | 781 DCHECK(!vsync_manager_); |
| 781 } | 782 } |
| 782 | 783 |
| 783 void DelegatedFrameHost::RunOnCommitCallbacks() { | 784 void DelegatedFrameSurfaceHost::RunOnCommitCallbacks() { |
| 784 for (std::vector<base::Closure>::const_iterator | 785 for (std::vector<base::Closure>::const_iterator it = |
| 785 it = on_compositing_did_commit_callbacks_.begin(); | 786 on_compositing_did_commit_callbacks_.begin(); |
| 786 it != on_compositing_did_commit_callbacks_.end(); ++it) { | 787 it != on_compositing_did_commit_callbacks_.end(); |
| 788 ++it) { | |
| 787 it->Run(); | 789 it->Run(); |
| 788 } | 790 } |
| 789 on_compositing_did_commit_callbacks_.clear(); | 791 on_compositing_did_commit_callbacks_.clear(); |
| 790 } | 792 } |
| 791 | 793 |
| 792 void DelegatedFrameHost::AddOnCommitCallbackAndDisableLocks( | 794 void DelegatedFrameSurfaceHost::AddOnCommitCallbackAndDisableLocks( |
| 793 const base::Closure& callback) { | 795 const base::Closure& callback) { |
| 794 ui::Compositor* compositor = client_->GetCompositor(); | 796 ui::Compositor* compositor = client_->GetCompositor(); |
| 795 DCHECK(compositor); | 797 DCHECK(compositor); |
| 796 | 798 |
| 797 if (!compositor->HasObserver(this)) | 799 if (!compositor->HasObserver(this)) |
| 798 compositor->AddObserver(this); | 800 compositor->AddObserver(this); |
| 799 | 801 |
| 800 can_lock_compositor_ = NO_PENDING_COMMIT; | 802 can_lock_compositor_ = NO_PENDING_COMMIT; |
| 801 on_compositing_did_commit_callbacks_.push_back(callback); | 803 on_compositing_did_commit_callbacks_.push_back(callback); |
| 802 } | 804 } |
| 803 | 805 |
| 804 void DelegatedFrameHost::AddedToWindow() { | 806 void DelegatedFrameSurfaceHost::AddedToWindow() { |
| 805 ui::Compositor* compositor = client_->GetCompositor(); | 807 ui::Compositor* compositor = client_->GetCompositor(); |
| 806 if (compositor) { | 808 if (compositor) { |
| 807 DCHECK(!vsync_manager_); | 809 DCHECK(!vsync_manager_); |
| 808 vsync_manager_ = compositor->vsync_manager(); | 810 vsync_manager_ = compositor->vsync_manager(); |
| 809 vsync_manager_->AddObserver(this); | 811 vsync_manager_->AddObserver(this); |
| 810 } | 812 } |
| 811 } | 813 } |
| 812 | 814 |
| 813 void DelegatedFrameHost::RemovingFromWindow() { | 815 void DelegatedFrameSurfaceHost::RemovingFromWindow() { |
| 814 RunOnCommitCallbacks(); | 816 RunOnCommitCallbacks(); |
| 815 resize_lock_.reset(); | 817 resize_lock_.reset(); |
| 816 client_->GetHost()->WasResized(); | 818 client_->GetHost()->WasResized(); |
| 817 ui::Compositor* compositor = client_->GetCompositor(); | 819 ui::Compositor* compositor = client_->GetCompositor(); |
| 818 if (compositor && compositor->HasObserver(this)) | 820 if (compositor && compositor->HasObserver(this)) |
| 819 compositor->RemoveObserver(this); | 821 compositor->RemoveObserver(this); |
| 820 | 822 |
| 821 if (vsync_manager_) { | 823 if (vsync_manager_) { |
| 822 vsync_manager_->RemoveObserver(this); | 824 vsync_manager_->RemoveObserver(this); |
| 823 vsync_manager_ = NULL; | 825 vsync_manager_ = NULL; |
| 824 } | 826 } |
| 825 } | 827 } |
| 826 | 828 |
| 827 void DelegatedFrameHost::LockResources() { | 829 void DelegatedFrameSurfaceHost::LockResources() { |
| 828 DCHECK(frame_provider_); | 830 DCHECK(!surface_id_.is_null()); |
| 829 delegated_frame_evictor_->LockFrame(); | 831 delegated_frame_evictor_->LockFrame(); |
| 830 } | 832 } |
| 831 | 833 |
| 832 void DelegatedFrameHost::UnlockResources() { | 834 void DelegatedFrameSurfaceHost::UnlockResources() { |
| 833 DCHECK(frame_provider_); | 835 DCHECK(!surface_id_.is_null()); |
| 834 delegated_frame_evictor_->UnlockFrame(); | 836 delegated_frame_evictor_->UnlockFrame(); |
| 835 } | 837 } |
| 836 | 838 |
| 837 //////////////////////////////////////////////////////////////////////////////// | 839 //////////////////////////////////////////////////////////////////////////////// |
| 838 // DelegatedFrameHost, ui::LayerOwnerDelegate implementation: | 840 // DelegatedFrameSurfaceHost, ui::LayerOwnerDelegate implementation: |
| 839 | 841 |
| 840 void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer, | 842 void DelegatedFrameSurfaceHost::OnLayerRecreated(ui::Layer* old_layer, |
| 841 ui::Layer* new_layer) { | 843 ui::Layer* new_layer) { |
| 842 // The new_layer is the one that will be used by our Window, so that's the one | 844 // The new_layer is the one that will be used by our Window, so that's the one |
| 843 // that should keep our frame. old_layer will be returned to the | 845 // that should keep our frame. old_layer will be returned to the |
| 844 // RecreateLayer caller, and should have a copy. | 846 // RecreateLayer caller, and should have a copy. |
| 845 if (frame_provider_.get()) { | 847 if (!surface_id_.is_null()) { |
| 846 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 848 client_->GetLayer()->SetShowSurface(surface_id_, |
| 847 current_frame_size_in_dip_); | 849 current_frame_size_in_dip_); |
| 848 } | 850 } |
| 849 } | 851 } |
| 850 | 852 |
| 851 } // namespace content | 853 } // namespace content |
| 852 | |
| OLD | NEW |