1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_
#define CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_
#include "cc/layers/delegated_frame_provider.h"
#include "cc/layers/delegated_frame_resource_collection.h"
#include "cc/output/copy_output_result.h"
#include "cc/surfaces/surface_factory_client.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/compositor/owned_mailbox.h"
#include "content/browser/renderer_host/delegated_frame_evictor.h"
#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/public/browser/render_process_host.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/compositor/compositor_vsync_manager.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_owner_delegate.h"
#include "ui/gfx/geometry/rect_conversions.h"
namespace cc {
class SurfaceFactory;
}
namespace media {
class VideoFrame;
}
namespace content {
class DelegatedFrameHost;
class ReadbackYUVInterface;
class RenderWidgetHostViewFrameSubscriber;
class RenderWidgetHostImpl;
class ResizeLock;
// The DelegatedFrameHostClient is the interface from the DelegatedFrameHost,
// which manages delegated frames, and the ui::Compositor being used to
// display them.
class CONTENT_EXPORT DelegatedFrameHostClient {
public:
virtual ui::Compositor* GetCompositor() const = 0;
virtual ui::Layer* GetLayer() = 0;
virtual RenderWidgetHostImpl* GetHost() = 0;
virtual bool IsVisible() = 0;
virtual scoped_ptr<ResizeLock> CreateResizeLock(
bool defer_compositor_lock) = 0;
virtual gfx::Size DesiredFrameSize() = 0;
// TODO(ccameron): It is likely that at least one of these two functions is
// redundant. Find which one, and delete it.
virtual float CurrentDeviceScaleFactor() = 0;
virtual gfx::Size ConvertViewSizeToPixel(const gfx::Size& size) = 0;
// These are to be overridden for testing only.
// TODO(ccameron): This is convoluted. Make the tests that need to override
// these functions test DelegatedFrameHost directly (rather than do it
// through RenderWidgetHostViewAura).
virtual DelegatedFrameHost* GetDelegatedFrameHost() const = 0;
virtual bool ShouldCreateResizeLock();
virtual void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request);
};
// The DelegatedFrameHost is used to host all of the RenderWidgetHostView state
// and functionality that is associated with delegated frames being sent from
// the RenderWidget. The DelegatedFrameHost will push these changes through to
// the ui::Compositor associated with its DelegatedFrameHostClient.
class CONTENT_EXPORT DelegatedFrameHost
: public ui::CompositorObserver,
public ui::CompositorVSyncManager::Observer,
public ui::LayerOwnerDelegate,
public ImageTransportFactoryObserver,
public DelegatedFrameEvictorClient,
public cc::DelegatedFrameResourceCollectionClient,
public cc::SurfaceFactoryClient,
public base::SupportsWeakPtr<DelegatedFrameHost> {
public:
DelegatedFrameHost(DelegatedFrameHostClient* client);
~DelegatedFrameHost() override;
bool CanCopyToBitmap() const;
// Public interface exposed to RenderWidgetHostView.
void SwapDelegatedFrame(
uint32 output_surface_id,
scoped_ptr<cc::DelegatedFrameData> frame_data,
float frame_device_scale_factor,
const std::vector<ui::LatencyInfo>& latency_info);
void WasHidden();
void WasShown(const ui::LatencyInfo& latency_info);
void WasResized();
bool HasSavedFrame();
gfx::Size GetRequestedRendererSize() const;
void AddedToWindow();
void RemovingFromWindow();
void CopyFromCompositingSurface(const gfx::Rect& src_subrect,
const gfx::Size& output_size,
ReadbackRequestCallback& callback,
const SkColorType color_type);
void CopyFromCompositingSurfaceToVideoFrame(
const gfx::Rect& src_subrect,
const scoped_refptr<media::VideoFrame>& target,
const base::Callback<void(bool)>& callback);
bool CanCopyToVideoFrame() const;
bool CanSubscribeFrame() const;
void BeginFrameSubscription(
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber);
void EndFrameSubscription();
bool HasFrameSubscriber() const { return frame_subscriber_; }
// Exposed for tests.
cc::DelegatedFrameProvider* FrameProviderForTesting() const {
return frame_provider_.get();
}
cc::SurfaceId SurfaceIdForTesting() const { return surface_id_; }
void OnCompositingDidCommitForTesting(ui::Compositor* compositor) {
OnCompositingDidCommit(compositor);
}
bool ShouldCreateResizeLockForTesting() { return ShouldCreateResizeLock(); }
bool ReleasedFrontLockActiveForTesting() const {
return !!released_front_lock_.get();
}
private:
friend class DelegatedFrameHostClient;
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
SkippedDelegatedFrames);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
DiscardDelegatedFramesWithLocking);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraCopyRequestTest,
DestroyedAfterCopyRequest);
RenderWidgetHostViewFrameSubscriber* frame_subscriber() const {
return frame_subscriber_.get();
}
bool ShouldCreateResizeLock();
void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request);
void LockResources();
void UnlockResources();
// Overridden from ui::CompositorObserver:
void OnCompositingDidCommit(ui::Compositor* compositor) override;
void OnCompositingStarted(ui::Compositor* compositor,
base::TimeTicks start_time) override;
void OnCompositingEnded(ui::Compositor* compositor) override;
void OnCompositingAborted(ui::Compositor* compositor) override;
void OnCompositingLockStateChanged(ui::Compositor* compositor) override;
// Overridden from ui::CompositorVSyncManager::Observer:
void OnUpdateVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) override;
// Overridden from ui::LayerOwnerObserver:
void OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) override;
// Overridden from ImageTransportFactoryObserver:
void OnLostResources() override;
bool ShouldSkipFrame(gfx::Size size_in_dip) const;
// Lazily grab a resize lock if the aura window size doesn't match the current
// frame size, to give time to the renderer.
void MaybeCreateResizeLock();
// Checks if the resize lock can be released because we received an new frame.
void CheckResizeLock();
// Run all on compositing commit callbacks.
void RunOnCommitCallbacks();
// Add on compositing commit callback.
void AddOnCommitCallbackAndDisableLocks(const base::Closure& callback);
// Called after async thumbnailer task completes. Scales and crops the result
// of the copy.
static void CopyFromCompositingSurfaceHasResult(
const gfx::Size& dst_size_in_pixel,
const SkColorType color_type,
ReadbackRequestCallback& callback,
scoped_ptr<cc::CopyOutputResult> result);
static void PrepareTextureCopyOutputResult(
const gfx::Size& dst_size_in_pixel,
const SkColorType color_type,
ReadbackRequestCallback& callback,
scoped_ptr<cc::CopyOutputResult> result);
static void PrepareBitmapCopyOutputResult(
const gfx::Size& dst_size_in_pixel,
const SkColorType color_type,
ReadbackRequestCallback& callback,
scoped_ptr<cc::CopyOutputResult> result);
static void CopyFromCompositingSurfaceHasResultForVideo(
base::WeakPtr<DelegatedFrameHost> rwhva,
scoped_refptr<OwnedMailbox> subscriber_texture,
scoped_refptr<media::VideoFrame> video_frame,
const base::Callback<void(bool)>& callback,
scoped_ptr<cc::CopyOutputResult> result);
static void CopyFromCompositingSurfaceFinishedForVideo(
base::WeakPtr<DelegatedFrameHost> rwhva,
const base::Callback<void(bool)>& callback,
scoped_refptr<OwnedMailbox> subscriber_texture,
scoped_ptr<cc::SingleReleaseCallback> release_callback,
bool result);
static void ReturnSubscriberTexture(
base::WeakPtr<DelegatedFrameHost> rwhva,
scoped_refptr<OwnedMailbox> subscriber_texture,
uint32 sync_point);
void SendDelegatedFrameAck(uint32 output_surface_id);
void SurfaceDrawn(uint32 output_surface_id, bool drawn);
void SendReturnedDelegatedResources(uint32 output_surface_id);
// DelegatedFrameEvictorClient implementation.
void EvictDelegatedFrame() override;
// cc::DelegatedFrameProviderClient implementation.
void UnusedResourcesAreAvailable() override;
// cc::SurfaceFactoryClient implementation.
void ReturnResources(const cc::ReturnedResourceArray& resources) override;
void DidReceiveFrameFromRenderer(const gfx::Rect& damage_rect);
DelegatedFrameHostClient* client_;
// True if this renders into a Surface, false if it renders into a delegated
// layer.
bool use_surfaces_;
std::vector<base::Closure> on_compositing_did_commit_callbacks_;
// The vsync manager we are observing for changes, if any.
scoped_refptr<ui::CompositorVSyncManager> vsync_manager_;
// The current VSync timebase and interval. These are zero until the first
// call to OnUpdateVSyncParameters().
base::TimeTicks vsync_timebase_;
base::TimeDelta vsync_interval_;
// With delegated renderer, this is the last output surface, used to
// disambiguate resources with the same id coming from different output
// surfaces.
uint32 last_output_surface_id_;
// The number of delegated frame acks that are pending, to delay resource
// returns until the acks are sent.
int pending_delegated_ack_count_;
// True after a delegated frame has been skipped, until a frame is not
// skipped.
bool skipped_frames_;
std::vector<ui::LatencyInfo> skipped_latency_info_list_;
// Holds delegated resources that have been given to a DelegatedFrameProvider,
// and gives back resources when they are no longer in use for return to the
// renderer.
scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection_;
// Provides delegated frame updates to the cc::DelegatedRendererLayer.
scoped_refptr<cc::DelegatedFrameProvider> frame_provider_;
// State for rendering into a Surface.
scoped_ptr<cc::SurfaceIdAllocator> id_allocator_;
scoped_ptr<cc::SurfaceFactory> surface_factory_;
cc::SurfaceId surface_id_;
gfx::Size current_surface_size_;
float current_scale_factor_;
cc::ReturnedResourceArray surface_returned_resources_;
// This lock is the one waiting for a frame of the right size to come back
// from the renderer/GPU process. It is set from the moment the aura window
// got resized, to the moment we committed the renderer frame of the same
// size. It keeps track of the size we expect from the renderer, and locks the
// compositor, as well as the UI for a short time to give a chance to the
// renderer of producing a frame of the right size.
scoped_ptr<ResizeLock> resize_lock_;
// Keeps track of the current frame size.
gfx::Size current_frame_size_in_dip_;
// This lock is for waiting for a front surface to become available to draw.
scoped_refptr<ui::CompositorLock> released_front_lock_;
enum CanLockCompositorState {
YES_CAN_LOCK,
// We locked, so at some point we'll need to kick a frame.
YES_DID_LOCK,
// No. A lock timed out, we need to kick a new frame before locking again.
NO_PENDING_RENDERER_FRAME,
// No. We've got a frame, but it hasn't been committed.
NO_PENDING_COMMIT,
};
CanLockCompositorState can_lock_compositor_;
base::TimeTicks last_draw_ended_;
// Subscriber that listens to frame presentation events.
scoped_ptr<RenderWidgetHostViewFrameSubscriber> frame_subscriber_;
std::vector<scoped_refptr<OwnedMailbox> > idle_frame_subscriber_textures_;
// YUV readback pipeline.
scoped_ptr<content::ReadbackYUVInterface>
yuv_readback_pipeline_;
scoped_ptr<DelegatedFrameEvictor> delegated_frame_evictor_;
};
} // namespace content
#endif // CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_
|