1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file. 4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/compositor/delegated_frame_host.h" 6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/callback_helpers.h" 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/command_line.h" 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "cc/output/compositor_frame.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "cc/output/compositor_frame_ack.h" 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "cc/output/copy_output_request.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "cc/resources/single_release_callback.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "cc/resources/texture_mailbox.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "cc/surfaces/surface_factory.h" 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/compositor/resize_lock.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/browser/gpu/compositor_util.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/common/gpu/client/gl_helper.h" 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/browser/render_widget_host_view_frame_subscriber.h" 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/common/content_switches.h" 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "media/base/video_frame.h" 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "media/base/video_util.h" 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "skia/ext/image_operations.h" 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/skia/include/core/SkCanvas.h" 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/skia/include/core/SkPaint.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/skia/include/effects/SkLumaColorFilter.h" 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/frame_time.h" 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace content { 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// DelegatedFrameHostClient 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DelegatedFrameHostClient::ShouldCreateResizeLock() { 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // On Windows and Linux, holding pointer moves will not help throttling 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // resizes. 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(piman): on Windows we need to block (nested message loop?) the 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // WM_SIZE event. On Linux we need to throttle at the WM level using 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // _NET_WM_SYNC_REQUEST. 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(ccameron): Mac browser window resizing is incompletely implemented. 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(OS_CHROMEOS) 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return GetDelegatedFrameHost()->ShouldCreateResizeLock(); 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHostClient::RequestCopyOfOutput( 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::CopyOutputRequest> request) { 490de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) GetDelegatedFrameHost()->RequestCopyOfOutput(request.Pass()); 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// DelegatedFrameHost 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client) 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : client_(client), 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci use_surfaces_(UseSurfacesEnabled()), 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) last_output_surface_id_(0), 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pending_delegated_ack_count_(0), 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) skipped_frames_(false), 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) can_lock_compositor_(YES_CAN_LOCK), 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ImageTransportFactory::GetInstance()->AddObserver(this); 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void DelegatedFrameHost::WasShown(const ui::LatencyInfo& latency_info) { 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegated_frame_evictor_->SetVisible(true); 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (surface_id_.is_null() && !frame_provider_.get() && 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !released_front_lock_.get()) { 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor = client_->GetCompositor(); 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (compositor) 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) released_front_lock_ = compositor->GetCompositorLock(); 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ui::Compositor* compositor = client_->GetCompositor(); 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (compositor) { 786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) compositor->SetLatencyInfo(latency_info); 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool DelegatedFrameHost::HasSavedFrame() { 836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return delegated_frame_evictor_->HasFrame(); 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::WasHidden() { 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegated_frame_evictor_->SetVisible(false); 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) released_front_lock_ = NULL; 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::MaybeCreateResizeLock() { 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!client_->ShouldCreateResizeLock()) 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(client_->GetCompositor()); 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Listen to changes in the compositor lock state. 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor = client_->GetCompositor(); 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!compositor->HasObserver(this)) 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) compositor->AddObserver(this); 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool defer_compositor_lock = 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) can_lock_compositor_ == NO_PENDING_COMMIT; 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (can_lock_compositor_ == YES_CAN_LOCK) 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) can_lock_compositor_ = YES_DID_LOCK; 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resize_lock_ = client_->CreateResizeLock(defer_compositor_lock); 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DelegatedFrameHost::ShouldCreateResizeLock() { 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl* host = client_->GetHost(); 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (resize_lock_) 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 117e578b2d213c837aab9cea5407d30f5c84065cd0eMarcin Kosiba if (host->auto_resize_enabled()) 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Size desired_size = client_->DesiredFrameSize(); 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (desired_size == current_frame_size_in_dip_ || desired_size.IsEmpty()) 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor = client_->GetCompositor(); 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!compositor) 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::RequestCopyOfOutput( 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::CopyOutputRequest> request) { 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (use_surfaces_) { 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (surface_factory_ && !surface_id_.is_null()) 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci surface_factory_->RequestCopyOfSurface(surface_id_, request.Pass()); 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->SendEmptyResult(); 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->GetLayer()->RequestCopyOfOutput(request.Pass()); 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::CopyFromCompositingSurface( 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const gfx::Rect& src_subrect, 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const gfx::Size& output_size, 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyFromCompositingSurfaceCallback& callback, 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const SkColorType color_type) { 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Only ARGB888 and RGB565 supported as of now. 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool format_support = ((color_type == kAlpha_8_SkColorType) || 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (color_type == kRGB_565_SkColorType) || 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (color_type == kN32_SkColorType)); 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(format_support); 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!CanCopyToBitmap()) { 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(false, SkBitmap()); 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::CopyOutputRequest> request = 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::CopyOutputRequest::CreateRequest(base::Bind( 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) output_size, 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch color_type, 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback)); 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) request->set_area(src_subrect); 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) client_->RequestCopyOfOutput(request.Pass()); 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::CopyFromCompositingSurfaceToVideoFrame( 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const gfx::Rect& src_subrect, 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const scoped_refptr<media::VideoFrame>& target, 171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::Callback<void(bool)>& callback) { 172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!CanCopyToVideoFrame()) { 173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(false); 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Try get a texture to reuse. 178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<OwnedMailbox> subscriber_texture; 179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (frame_subscriber_) { 180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!idle_frame_subscriber_textures_.empty()) { 181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) subscriber_texture = idle_frame_subscriber_textures_.back(); 182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) idle_frame_subscriber_textures_.pop_back(); 183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (GLHelper* helper = 184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ImageTransportFactory::GetInstance()->GetGLHelper()) { 185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) subscriber_texture = new OwnedMailbox(helper); 186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::CopyOutputRequest> request = 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::CopyOutputRequest::CreateRequest(base::Bind( 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &DelegatedFrameHost:: 192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CopyFromCompositingSurfaceHasResultForVideo, 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AsWeakPtr(), // For caching the ReadbackYUVInterface on this class. 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) subscriber_texture, 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) target, 196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback)); 1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) request->set_area(src_subrect); 198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (subscriber_texture.get()) { 199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request->SetTextureMailbox( 200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::TextureMailbox(subscriber_texture->mailbox(), 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) subscriber_texture->target(), 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) subscriber_texture->sync_point())); 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) client_->RequestCopyOfOutput(request.Pass()); 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DelegatedFrameHost::CanCopyToBitmap() const { 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return client_->GetCompositor() && 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) client_->GetLayer()->has_external_content(); 210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DelegatedFrameHost::CanCopyToVideoFrame() const { 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return client_->GetCompositor() && 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) client_->GetLayer()->has_external_content(); 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DelegatedFrameHost::CanSubscribeFrame() const { 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::BeginFrameSubscription( 222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { 223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) frame_subscriber_ = subscriber.Pass(); 224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::EndFrameSubscription() { 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) idle_frame_subscriber_textures_.clear(); 228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) frame_subscriber_.reset(); 229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Should skip a frame only when another frame from the renderer is guaranteed 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // to replace it. Otherwise may cause hangs when the renderer is waiting for 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the completion of latency infos (such as when taking a Snapshot.) 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || 236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) can_lock_compositor_ == NO_PENDING_COMMIT || 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) !resize_lock_.get()) 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return size_in_dip != resize_lock_->expected_size(); 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::WasResized() { 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (client_->DesiredFrameSize() != current_frame_size_in_dip_ && 2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_->GetHost()->is_hidden()) 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EvictDelegatedFrame(); 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MaybeCreateResizeLock(); 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size DelegatedFrameHost::GetRequestedRendererSize() const { 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (resize_lock_) 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return resize_lock_->expected_size(); 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return client_->DesiredFrameSize(); 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::CheckResizeLock() { 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!resize_lock_ || 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resize_lock_->expected_size() != current_frame_size_in_dip_) 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Since we got the size we were looking for, unlock the compositor. But delay 263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // the release of the lock until we've kicked a frame with the new texture, to 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // avoid resizing the UI before we have a chance to draw a "good" frame. 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resize_lock_->UnlockCompositor(); 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor = client_->GetCompositor(); 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (compositor) { 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!compositor->HasObserver(this)) 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) compositor->AddObserver(this); 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void DelegatedFrameHost::DidReceiveFrameFromRenderer( 2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const gfx::Rect& damage_rect) { 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!frame_subscriber() || !CanCopyToVideoFrame()) 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::TimeTicks now = gfx::FrameTime::Now(); 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeTicks present_time; 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (vsync_timebase_.is_null() || vsync_interval_ <= base::TimeDelta()) { 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) present_time = now; 2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const int64 intervals_elapsed = (now - vsync_timebase_) / vsync_interval_; 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) present_time = vsync_timebase_ + (intervals_elapsed + 1) * vsync_interval_; 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<media::VideoFrame> frame; 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (frame_subscriber()->ShouldCaptureFrame(damage_rect, present_time, 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &frame, &callback)) { 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CopyFromCompositingSurfaceToVideoFrame( 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Rect(current_frame_size_in_dip_), 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame, 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(callback, present_time)); 295010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 296010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::SwapDelegatedFrame( 299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 output_surface_id, 300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::DelegatedFrameData> frame_data, 301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) float frame_device_scale_factor, 302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::vector<ui::LatencyInfo>& latency_info) { 303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl* host = client_->GetHost(); 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!frame_data->render_pass_list.empty()); 305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 306010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::RenderPass* root_pass = frame_data->render_pass_list.back(); 307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Size frame_size = root_pass->output_rect.size(); 309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Size frame_size_in_dip = 310010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ConvertSizeToDIP(frame_device_scale_factor, frame_size); 311010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect); 313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) damage_rect.Intersect(gfx::Rect(frame_size)); 314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect damage_rect_in_dip = 315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ConvertRectToDIP(frame_device_scale_factor, damage_rect); 316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (ShouldSkipFrame(frame_size_in_dip)) { 318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::CompositorFrameAck ack; 319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::TransferableResource::ReturnResources(frame_data->resource_list, 320010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &ack.resources); 321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) latency_info.begin(), latency_info.end()); 324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl::SendSwapCompositorFrameAck( 326010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) host->GetRoutingID(), output_surface_id, 327010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) host->GetProcess()->GetID(), ack); 328010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) skipped_frames_ = true; 329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (skipped_frames_) { 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) skipped_frames_ = false; 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) damage_rect = gfx::Rect(frame_size); 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) damage_rect_in_dip = gfx::Rect(frame_size_in_dip); 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Give the same damage rect to the compositor. 338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::RenderPass* root_pass = frame_data->render_pass_list.back(); 339010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) root_pass->damage_rect = damage_rect; 340010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (output_surface_id != last_output_surface_id_) { 343010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Resource ids are scoped by the output surface. 344010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If the originating output surface doesn't match the last one, it 345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // indicates the renderer's output surface may have been recreated, in which 346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // case we should recreate the DelegatedRendererLayer, to avoid matching 347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // resources from the old one with resources from the new one which would 348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // have the same id. Changing the layer to showing painted content destroys 349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // the DelegatedRendererLayer. 350010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EvictDelegatedFrame(); 351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Drop the cc::DelegatedFrameResourceCollection so that we will not return 353010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // any resources from the old output surface with the new output surface id. 354010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (resource_collection_.get()) { 355010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resource_collection_->SetClient(NULL); 356010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 357010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (resource_collection_->LoseAllResources()) 358010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendReturnedDelegatedResources(last_output_surface_id_); 359010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 360010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resource_collection_ = NULL; 361010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 362010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) last_output_surface_id_ = output_surface_id; 363010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 36403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool modified_layers = false; 3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::Compositor* compositor = client_->GetCompositor(); 366010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (frame_size.IsEmpty()) { 367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(frame_data->resource_list.empty()); 368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EvictDelegatedFrame(); 36903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) modified_layers = true; 370010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (use_surfaces_) { 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!surface_factory_) { 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cc::SurfaceManager* manager = factory->GetSurfaceManager(); 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) id_allocator_ = factory->CreateSurfaceIdAllocator(); 3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) surface_factory_ = 3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) make_scoped_ptr(new cc::SurfaceFactory(manager, this)); 3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (surface_id_.is_null() || frame_size != current_surface_size_ || 3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame_size_in_dip != current_frame_size_in_dip_) { 38103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // TODO(jbauman): Wait to destroy this surface until the parent has 38203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // finished using it. 3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!surface_id_.is_null()) 3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) surface_factory_->Destroy(surface_id_); 3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) surface_id_ = id_allocator_->GenerateId(); 3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) surface_factory_->Create(surface_id_, frame_size); 3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_->GetLayer()->SetShowSurface(surface_id_, frame_size_in_dip); 3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current_surface_size_ = frame_size; 38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) modified_layers = true; 3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<cc::CompositorFrame> compositor_frame = 3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) make_scoped_ptr(new cc::CompositorFrame()); 3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) compositor_frame->delegated_frame_data = frame_data.Pass(); 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci compositor_frame->metadata.latency_info.swap(skipped_latency_info_list_); 3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci compositor_frame->metadata.latency_info.insert( 3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci compositor_frame->metadata.latency_info.end(), 3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci latency_info.begin(), 3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci latency_info.end()); 4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Closure ack_callback; 4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (compositor) { 4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ack_callback = base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, 4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AsWeakPtr(), 4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output_surface_id); 4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci surface_factory_->SubmitFrame( 4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci surface_id_, compositor_frame.Pass(), ack_callback); 409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!resource_collection_.get()) { 4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resource_collection_ = new cc::DelegatedFrameResourceCollection; 4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resource_collection_->SetClient(this); 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the physical frame size changes, we need a new |frame_provider_|. If 4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the physical frame size is the same, but the size in DIP changed, we 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // need to adjust the scale at which the frames will be drawn, and we do 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // this by making a new |frame_provider_| also to ensure the scale change 4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // is presented in sync with the new frame content. 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!frame_provider_.get() || 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame_size != frame_provider_->frame_size() || 4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame_size_in_dip != current_frame_size_in_dip_) { 4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame_provider_ = new cc::DelegatedFrameProvider( 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resource_collection_.get(), frame_data.Pass()); 4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_->GetLayer()->SetShowDelegatedContent(frame_provider_.get(), 4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame_size_in_dip); 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame_provider_->SetFrameData(frame_data.Pass()); 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 42903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) modified_layers = true; 430010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 431010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 432010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) released_front_lock_ = NULL; 433010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) current_frame_size_in_dip_ = frame_size_in_dip; 434010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CheckResizeLock(); 435010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (modified_layers && !damage_rect_in_dip.IsEmpty()) { 43703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // TODO(jbauman): Need to always tell the window observer about the 43803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // damage. 4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->GetLayer()->OnDelegatedFrameDamage(damage_rect_in_dip); 44003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 441010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 442010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pending_delegated_ack_count_++; 443010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!compositor) { 445010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendDelegatedFrameAck(output_surface_id); 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (!use_surfaces_) { 447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<ui::LatencyInfo>::const_iterator it; 448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (it = latency_info.begin(); it != latency_info.end(); ++it) 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) compositor->SetLatencyInfo(*it); 450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If we've previously skipped any latency infos add them. 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (it = skipped_latency_info_list_.begin(); 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != skipped_latency_info_list_.end(); 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) compositor->SetLatencyInfo(*it); 455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) skipped_latency_info_list_.clear(); 456010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AddOnCommitCallbackAndDisableLocks( 457010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, 458010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AsWeakPtr(), 459010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) output_surface_id)); 460010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DidReceiveFrameFromRenderer(damage_rect); 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (frame_provider_.get() || !surface_id_.is_null()) 463010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); 464010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Note: the frame may have been evicted immediately. 465010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 467010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { 468010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl* host = client_->GetHost(); 469010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::CompositorFrameAck ack; 4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!surface_returned_resources_.empty()) 4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ack.resources.swap(surface_returned_resources_); 4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (resource_collection_.get()) 473010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); 474010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(), 475010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) output_surface_id, 476010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) host->GetProcess()->GetID(), 477010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ack); 478010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_GT(pending_delegated_ack_count_, 0); 479010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pending_delegated_ack_count_--; 480010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 481010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 482010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::UnusedResourcesAreAvailable() { 483010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pending_delegated_ack_count_) 484010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 485010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 486010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendReturnedDelegatedResources(last_output_surface_id_); 487010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 488010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 489010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::SendReturnedDelegatedResources( 490010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 output_surface_id) { 491010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl* host = client_->GetHost(); 492010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 493010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::CompositorFrameAck ack; 4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!surface_returned_resources_.empty()) { 4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ack.resources.swap(surface_returned_resources_); 4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(resource_collection_.get()); 4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); 4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 500010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(!ack.resources.empty()); 501010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 502010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl::SendReclaimCompositorResources( 503010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) host->GetRoutingID(), 504010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) output_surface_id, 505010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) host->GetProcess()->GetID(), 506010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ack); 507010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 508010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void DelegatedFrameHost::ReturnResources( 5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const cc::ReturnedResourceArray& resources) { 5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (resources.empty()) 5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::copy(resources.begin(), 5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resources.end(), 5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::back_inserter(surface_returned_resources_)); 5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!pending_delegated_ack_count_) 5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SendReturnedDelegatedResources(last_output_surface_id_); 5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 520010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::EvictDelegatedFrame() { 521010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) client_->GetLayer()->SetShowPaintedContent(); 522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) frame_provider_ = NULL; 5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!surface_id_.is_null()) { 5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) surface_factory_->Destroy(surface_id_); 5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) surface_id_ = cc::SurfaceId(); 5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 527010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegated_frame_evictor_->DiscardedFrame(); 528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 529010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 530010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( 532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const gfx::Size& dst_size_in_pixel, 533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const SkColorType color_type, 534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::Callback<void(bool, const SkBitmap&)>& callback, 535010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::CopyOutputResult> result) { 536010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result->IsEmpty() || result->size().IsEmpty()) { 537010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(false, SkBitmap()); 538010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 539010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 540010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result->HasTexture()) { 5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // GPU-accelerated path 543116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, 544010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback, 545010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result.Pass()); 546010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(result->HasBitmap()); 5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Software path 551116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, 552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result.Pass()); 553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static void CopyFromCompositingSurfaceFinished( 556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::Callback<void(bool, const SkBitmap&)>& callback, 557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::SingleReleaseCallback> release_callback, 558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<SkBitmap> bitmap, 559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, 560010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool result) { 561010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bitmap_pixels_lock.reset(); 562010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 sync_point = 0; 564010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result) { 565010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); 566010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) sync_point = gl_helper->InsertSyncPoint(); 567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 568010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool lost_resource = sync_point == 0; 569010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) release_callback->Run(sync_point, lost_resource); 570010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 571010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(result, *bitmap); 572010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 573010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 574010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 575010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::PrepareTextureCopyOutputResult( 576010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const gfx::Size& dst_size_in_pixel, 577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const SkColorType color_type, 578010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::Callback<void(bool, const SkBitmap&)>& callback, 579010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::CopyOutputResult> result) { 580010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(result->HasTexture()); 581010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::ScopedClosureRunner scoped_callback_runner( 582010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(callback, false, SkBitmap())); 583010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(sikugu): We should be able to validate the format here using 5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // GLHelper::IsReadbackConfigSupported before we processs the result. 5861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // See crbug.com/415682. 587010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<SkBitmap> bitmap(new SkBitmap); 5881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!bitmap->tryAllocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), 5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dst_size_in_pixel.height(), 5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci color_type, 5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kOpaque_SkAlphaType))) 592010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 593010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 594010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 595010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GLHelper* gl_helper = factory->GetGLHelper(); 596010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!gl_helper) 597010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 598010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 599010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock( 600010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new SkAutoLockPixels(*bitmap)); 601010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint8* pixels = static_cast<uint8*>(bitmap->getPixels()); 602010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 603010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::TextureMailbox texture_mailbox; 604010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::SingleReleaseCallback> release_callback; 605010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result->TakeTexture(&texture_mailbox, &release_callback); 606010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(texture_mailbox.IsTexture()); 607010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 608010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ignore_result(scoped_callback_runner.Release()); 609010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 610010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gl_helper->CropScaleReadbackAndCleanMailbox( 611010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) texture_mailbox.mailbox(), 612010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) texture_mailbox.sync_point(), 613010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result->size(), 614010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect(result->size()), 615010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dst_size_in_pixel, 616010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pixels, 617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch color_type, 618010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&CopyFromCompositingSurfaceFinished, 619010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback, 620010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Passed(&release_callback), 621010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Passed(&bitmap), 622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Passed(&bitmap_pixels_lock)), 623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GLHelper::SCALER_QUALITY_FAST); 624010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 625010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 626010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 627010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::PrepareBitmapCopyOutputResult( 628010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const gfx::Size& dst_size_in_pixel, 629116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const SkColorType color_type, 630010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::Callback<void(bool, const SkBitmap&)>& callback, 631010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::CopyOutputResult> result) { 6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (color_type != kN32_SkColorType && color_type != kAlpha_8_SkColorType) { 633010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NOTIMPLEMENTED(); 634010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(false, SkBitmap()); 635010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 636010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 637010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(result->HasBitmap()); 638010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<SkBitmap> source = result->TakeBitmap(); 639010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(source); 6401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SkBitmap scaled_bitmap; 6411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (source->width() != dst_size_in_pixel.width() || 6421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci source->height() != dst_size_in_pixel.height()) { 6431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scaled_bitmap = 6441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci skia::ImageOperations::Resize(*source, 6451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci skia::ImageOperations::RESIZE_BEST, 6461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dst_size_in_pixel.width(), 6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dst_size_in_pixel.height()); 6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scaled_bitmap = *source; 6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (color_type == kN32_SkColorType) { 6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); 6531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(true, scaled_bitmap); 6541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 6551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(color_type, kAlpha_8_SkColorType); 6571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The software path currently always returns N32 bitmap regardless of the 6581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |color_type| we ask for. 6591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(scaled_bitmap.colorType(), kN32_SkColorType); 6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Paint |scaledBitmap| to alpha-only |grayscale_bitmap|. 6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SkBitmap grayscale_bitmap; 6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool success = grayscale_bitmap.tryAllocPixels( 6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SkImageInfo::MakeA8(scaled_bitmap.width(), scaled_bitmap.height())); 6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!success) { 6651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(false, SkBitmap()); 6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 6671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SkCanvas canvas(grayscale_bitmap); 6691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SkPaint paint; 6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci skia::RefPtr<SkColorFilter> filter = 6711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci skia::AdoptRef(SkLumaColorFilter::Create()); 6721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci paint.setColorFilter(filter.get()); 6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci canvas.drawBitmap(scaled_bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); 6741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(true, grayscale_bitmap); 675010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 676010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 677010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 678010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::ReturnSubscriberTexture( 679010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::WeakPtr<DelegatedFrameHost> dfh, 680010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<OwnedMailbox> subscriber_texture, 681010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 sync_point) { 682010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!subscriber_texture.get()) 683010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 684010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!dfh) 685010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 686010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 687010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) subscriber_texture->UpdateSyncPoint(sync_point); 688010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 689010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (dfh->frame_subscriber_ && subscriber_texture->texture_id()) 690010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture); 691010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 692010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 6931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 694010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo( 695010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::WeakPtr<DelegatedFrameHost> dfh, 696010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::Callback<void(bool)>& callback, 697010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<OwnedMailbox> subscriber_texture, 698010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::SingleReleaseCallback> release_callback, 699010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool result) { 700010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(result); 701010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 702010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 sync_point = 0; 703010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result) { 704010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); 705010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) sync_point = gl_helper->InsertSyncPoint(); 706010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 707010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (release_callback) { 708010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // A release callback means the texture came from the compositor, so there 709010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // should be no |subscriber_texture|. 7101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!subscriber_texture.get()); 711010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool lost_resource = sync_point == 0; 712010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) release_callback->Run(sync_point, lost_resource); 713010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 714010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ReturnSubscriberTexture(dfh, subscriber_texture, sync_point); 715010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 716010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 717010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 718010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo( 719010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::WeakPtr<DelegatedFrameHost> dfh, 720010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<OwnedMailbox> subscriber_texture, 721010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<media::VideoFrame> video_frame, 722010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::Callback<void(bool)>& callback, 723010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::CopyOutputResult> result) { 724010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); 725010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::ScopedClosureRunner scoped_return_subscriber_texture( 726010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&ReturnSubscriberTexture, dfh, subscriber_texture, 0)); 727010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 728010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!dfh) 729010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 730010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result->IsEmpty()) 731010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 732010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result->size().IsEmpty()) 733010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 734010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 735010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Compute the dest size we want after the letterboxing resize. Make the 736010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // coordinates and sizes even because we letterbox in YUV space 737010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // (see CopyRGBToVideoFrame). They need to be even for the UV samples to 738010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // line up correctly. 739010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The video frame's coded_size() and the result's size() are both physical 740010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // pixels. 741010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect region_in_frame = 742010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), 743010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result->size()); 744010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) region_in_frame = gfx::Rect(region_in_frame.x() & ~1, 745010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) region_in_frame.y() & ~1, 746010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) region_in_frame.width() & ~1, 747010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) region_in_frame.height() & ~1); 748010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (region_in_frame.IsEmpty()) 749010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 750010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 751010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!result->HasTexture()) { 752010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(result->HasBitmap()); 753010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<SkBitmap> bitmap = result->TakeBitmap(); 754010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Scale the bitmap to the required size, if necessary. 755010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkBitmap scaled_bitmap; 756010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result->size().width() != region_in_frame.width() || 757010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result->size().height() != region_in_frame.height()) { 758010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) skia::ImageOperations::ResizeMethod method = 759010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) skia::ImageOperations::RESIZE_GOOD; 760010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scaled_bitmap = skia::ImageOperations::Resize(*bitmap.get(), method, 761010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) region_in_frame.width(), 762010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) region_in_frame.height()); 763010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 764010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scaled_bitmap = *bitmap.get(); 765010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 766010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 767010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { 768010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); 769010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 770010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) media::CopyRGBToVideoFrame( 771010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) reinterpret_cast<uint8*>(scaled_bitmap.getPixels()), 772010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scaled_bitmap.rowBytes(), 773010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) region_in_frame, 774010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) video_frame.get()); 775010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 776010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ignore_result(scoped_callback_runner.Release()); 777010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(true); 778010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 779010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 780010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 781010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 782010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GLHelper* gl_helper = factory->GetGLHelper(); 783010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!gl_helper) 784010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 785010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (subscriber_texture.get() && !subscriber_texture->texture_id()) 786010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 787010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 788010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cc::TextureMailbox texture_mailbox; 789010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<cc::SingleReleaseCallback> release_callback; 790010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result->TakeTexture(&texture_mailbox, &release_callback); 791010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(texture_mailbox.IsTexture()); 792010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 793010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect result_rect(result->size()); 794010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 795010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::ReadbackYUVInterface* yuv_readback_pipeline = 796010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dfh->yuv_readback_pipeline_.get(); 797010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (yuv_readback_pipeline == NULL || 798010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) yuv_readback_pipeline->scaler()->SrcSize() != result_rect.size() || 799010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) yuv_readback_pipeline->scaler()->SrcSubrect() != result_rect || 800010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) yuv_readback_pipeline->scaler()->DstSize() != region_in_frame.size()) { 801010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GLHelper::ScalerQuality quality = GLHelper::SCALER_QUALITY_FAST; 802010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string quality_switch = switches::kTabCaptureDownscaleQuality; 803010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If we're scaling up, we can use the "best" quality. 804010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result_rect.size().width() < region_in_frame.size().width() && 805010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result_rect.size().height() < region_in_frame.size().height()) 806010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) quality_switch = switches::kTabCaptureUpscaleQuality; 807010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 808010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string switch_value = 8096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 8106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) quality_switch); 811010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (switch_value == "fast") 812010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) quality = GLHelper::SCALER_QUALITY_FAST; 813010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else if (switch_value == "good") 814010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) quality = GLHelper::SCALER_QUALITY_GOOD; 815010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else if (switch_value == "best") 816010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) quality = GLHelper::SCALER_QUALITY_BEST; 817010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 818010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dfh->yuv_readback_pipeline_.reset( 819010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gl_helper->CreateReadbackPipelineYUV(quality, 820010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result_rect.size(), 821010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result_rect, 822010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) video_frame->coded_size(), 823010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) region_in_frame, 824010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) true, 825010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) true)); 826010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) yuv_readback_pipeline = dfh->yuv_readback_pipeline_.get(); 827010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 828010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 829010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ignore_result(scoped_callback_runner.Release()); 830010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ignore_result(scoped_return_subscriber_texture.Release()); 831010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Callback<void(bool result)> finished_callback = base::Bind( 832010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo, 833010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dfh->AsWeakPtr(), 834010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback, 835010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) subscriber_texture, 836010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Passed(&release_callback)); 837010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) yuv_readback_pipeline->ReadbackYUV(texture_mailbox.mailbox(), 838010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) texture_mailbox.sync_point(), 839010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) video_frame.get(), 840010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) finished_callback); 841010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 842010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 843010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 844010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// DelegatedFrameHost, ui::CompositorObserver implementation: 845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 846010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::OnCompositingDidCommit( 847010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor) { 848010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl* host = client_->GetHost(); 849010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (can_lock_compositor_ == NO_PENDING_COMMIT) { 850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) can_lock_compositor_ = YES_CAN_LOCK; 851010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (resize_lock_.get() && resize_lock_->GrabDeferredLock()) 852010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) can_lock_compositor_ = YES_DID_LOCK; 853010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 854010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RunOnCommitCallbacks(); 855010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (resize_lock_ && 856010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resize_lock_->expected_size() == current_frame_size_in_dip_) { 857010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resize_lock_.reset(); 858010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) host->WasResized(); 859010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // We may have had a resize while we had the lock (e.g. if the lock expired, 860010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // or if the UI still gave us some resizes), so make sure we grab a new lock 861010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // if necessary. 862010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MaybeCreateResizeLock(); 863010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 864010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 865010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 866010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::OnCompositingStarted( 867010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor, base::TimeTicks start_time) { 868010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) last_draw_ended_ = start_time; 869010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 870010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 871010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::OnCompositingEnded( 872010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor) { 873010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 874010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 87546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DelegatedFrameHost::OnCompositingAborted(ui::Compositor* compositor) { 876010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 877010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 878010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::OnCompositingLockStateChanged( 879010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor) { 880010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // A compositor lock that is part of a resize lock timed out. We 881010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // should display a renderer frame. 882010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { 883010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; 884010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 885010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 886010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 887010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::OnUpdateVSyncParameters( 888010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::TimeTicks timebase, 889010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::TimeDelta interval) { 8905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) vsync_timebase_ = timebase; 8915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) vsync_interval_ = interval; 892010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl* host = client_->GetHost(); 893010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (client_->IsVisible()) 894010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) host->UpdateVSyncParameters(timebase, interval); 895010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 896010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 897010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 898010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: 899010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 900010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::OnLostResources() { 901010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RenderWidgetHostImpl* host = client_->GetHost(); 9025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (frame_provider_.get() || !surface_id_.is_null()) 903010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EvictDelegatedFrame(); 904010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) idle_frame_subscriber_textures_.clear(); 905010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) yuv_readback_pipeline_.reset(); 906010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 907010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) host->ScheduleComposite(); 908010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 909010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 910010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 911010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// DelegatedFrameHost, private: 912010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 913010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)DelegatedFrameHost::~DelegatedFrameHost() { 914010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ImageTransportFactory::GetInstance()->RemoveObserver(this); 915010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 9165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!surface_id_.is_null()) 9175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) surface_factory_->Destroy(surface_id_); 918010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (resource_collection_.get()) 919010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resource_collection_->SetClient(NULL); 920010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 9211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!vsync_manager_.get()); 922010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 923010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 924010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::RunOnCommitCallbacks() { 925010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (std::vector<base::Closure>::const_iterator 926010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it = on_compositing_did_commit_callbacks_.begin(); 927010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != on_compositing_did_commit_callbacks_.end(); ++it) { 928010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it->Run(); 929010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 930010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) on_compositing_did_commit_callbacks_.clear(); 931010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 932010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 933010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::AddOnCommitCallbackAndDisableLocks( 934010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::Closure& callback) { 935010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor = client_->GetCompositor(); 936010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(compositor); 937010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 938010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!compositor->HasObserver(this)) 939010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) compositor->AddObserver(this); 940010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 941010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) can_lock_compositor_ = NO_PENDING_COMMIT; 942010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) on_compositing_did_commit_callbacks_.push_back(callback); 943010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 944010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 945010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::AddedToWindow() { 946010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor = client_->GetCompositor(); 947010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (compositor) { 9481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!vsync_manager_.get()); 949010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) vsync_manager_ = compositor->vsync_manager(); 950010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) vsync_manager_->AddObserver(this); 951010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 952010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 953010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 954010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::RemovingFromWindow() { 955010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RunOnCommitCallbacks(); 956010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) resize_lock_.reset(); 957010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) client_->GetHost()->WasResized(); 958010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Compositor* compositor = client_->GetCompositor(); 959010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (compositor && compositor->HasObserver(this)) 960010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) compositor->RemoveObserver(this); 961010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 9621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (vsync_manager_.get()) { 963010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) vsync_manager_->RemoveObserver(this); 964010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) vsync_manager_ = NULL; 965010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 966010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 967010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 968010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::LockResources() { 9691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(frame_provider_.get() || !surface_id_.is_null()); 970010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegated_frame_evictor_->LockFrame(); 971010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 972010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 973010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::UnlockResources() { 9741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(frame_provider_.get() || !surface_id_.is_null()); 975010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegated_frame_evictor_->UnlockFrame(); 976010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 977010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 978010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 979010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// DelegatedFrameHost, ui::LayerOwnerDelegate implementation: 980010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 981010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer, 982010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::Layer* new_layer) { 983010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The new_layer is the one that will be used by our Window, so that's the one 984010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // that should keep our frame. old_layer will be returned to the 985010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // RecreateLayer caller, and should have a copy. 986010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (frame_provider_.get()) { 987010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new_layer->SetShowDelegatedContent(frame_provider_.get(), 988010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) current_frame_size_in_dip_); 989010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 9905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!surface_id_.is_null()) { 9915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_layer->SetShowSurface(surface_id_, current_frame_size_in_dip_); 9925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 993010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 994010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 995010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace content 996