blob: a08691e519c0ec5725fb67a1a9035e4e3b32ebad [file] [log] [blame]
// 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 COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_SINK_MANAGER_IMPL_H_
#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_SINK_MANAGER_IMPL_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_piece.h"
#include "base/threading/thread_checker.h"
#include "components/viz/common/constants.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/service/frame_sinks/frame_sink_observer.h"
#include "components/viz/service/frame_sinks/primary_begin_frame_source.h"
#include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_manager.h"
#include "components/viz/service/frame_sinks/video_detector.h"
#include "components/viz/service/hit_test/hit_test_aggregator_delegate.h"
#include "components/viz/service/hit_test/hit_test_manager.h"
#include "components/viz/service/surfaces/surface_manager.h"
#include "components/viz/service/surfaces/surface_observer.h"
#include "components/viz/service/viz_service_export.h"
#include "gpu/ipc/common/surface_handle.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h"
#include "services/viz/privileged/interfaces/compositing/frame_sink_video_capture.mojom.h"
#include "services/viz/public/interfaces/compositing/video_detector_observer.mojom.h"
namespace viz {
class CapturableFrameSink;
class CompositorFrameSinkSupport;
class DisplayProvider;
class SharedBitmapManager;
// FrameSinkManagerImpl manages BeginFrame hierarchy. This is the implementation
// detail for FrameSinkManagerImpl.
class VIZ_SERVICE_EXPORT FrameSinkManagerImpl
: public SurfaceObserver,
public FrameSinkVideoCapturerManager,
public mojom::FrameSinkManager,
public HitTestAggregatorDelegate {
public:
explicit FrameSinkManagerImpl(
SharedBitmapManager* shared_bitmap_manager,
base::Optional<uint32_t> activation_deadline_in_frames =
kDefaultActivationDeadlineInFrames,
DisplayProvider* display_provider = nullptr);
~FrameSinkManagerImpl() override;
// Performs cleanup needed to force shutdown from the GPU process. Stops all
// incoming IPCs and destroys all [Root]CompositorFrameSinkImpls.
void ForceShutdown();
// Binds |this| as a FrameSinkManagerImpl for |request| on |task_runner|. On
// Mac |task_runner| will be the resize helper task runner. May only be called
// once.
void BindAndSetClient(mojom::FrameSinkManagerRequest request,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
mojom::FrameSinkManagerClientPtr client);
// Sets up a direction connection to |client| without using Mojo.
void SetLocalClient(mojom::FrameSinkManagerClient* client);
// mojom::FrameSinkManager implementation:
void RegisterFrameSinkId(const FrameSinkId& frame_sink_id) override;
void InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) override;
void EnableSynchronizationReporting(
const FrameSinkId& frame_sink_id,
const std::string& reporting_label) override;
void SetFrameSinkDebugLabel(const FrameSinkId& frame_sink_id,
const std::string& debug_label) override;
void CreateRootCompositorFrameSink(
mojom::RootCompositorFrameSinkParamsPtr params) override;
void CreateCompositorFrameSink(
const FrameSinkId& frame_sink_id,
mojom::CompositorFrameSinkRequest request,
mojom::CompositorFrameSinkClientPtr client) override;
void DestroyCompositorFrameSink(
const FrameSinkId& frame_sink_id,
DestroyCompositorFrameSinkCallback callback) override;
void RegisterFrameSinkHierarchy(
const FrameSinkId& parent_frame_sink_id,
const FrameSinkId& child_frame_sink_id) override;
void UnregisterFrameSinkHierarchy(
const FrameSinkId& parent_frame_sink_id,
const FrameSinkId& child_frame_sink_id) override;
void AssignTemporaryReference(const SurfaceId& surface_id,
const FrameSinkId& owner) override;
void DropTemporaryReference(const SurfaceId& surface_id) override;
void AddVideoDetectorObserver(
mojom::VideoDetectorObserverPtr observer) override;
void CreateVideoCapturer(
mojom::FrameSinkVideoCapturerRequest request) override;
void EvictSurfaces(const std::vector<SurfaceId>& surface_ids) override;
void RequestCopyOfOutput(const SurfaceId& surface_id,
std::unique_ptr<CopyOutputRequest> request) override;
// SurfaceObserver implementation.
void OnSurfaceCreated(const SurfaceId& surface_id) override;
void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override;
void OnSurfaceActivated(const SurfaceId& surface_id,
base::Optional<base::TimeDelta> duration) override;
bool OnSurfaceDamaged(const SurfaceId& surface_id,
const BeginFrameAck& ack) override;
void OnSurfaceDiscarded(const SurfaceId& surface_id) override;
void OnSurfaceDestroyed(const SurfaceId& surface_id) override;
void OnSurfaceDamageExpected(const SurfaceId& surface_id,
const BeginFrameArgs& args) override;
// HitTestAggregatorDelegate implementation:
void OnAggregatedHitTestRegionListUpdated(
const FrameSinkId& frame_sink_id,
const std::vector<AggregatedHitTestRegion>& hit_test_data) override;
// CompositorFrameSinkSupport, hierarchy, and BeginFrameSource can be
// registered and unregistered in any order with respect to each other.
//
// This happens in practice, e.g. the relationship to between ui::Compositor /
// DelegatedFrameHost is known before ui::Compositor has a surface/client).
// However, DelegatedFrameHost can register itself as a client before its
// relationship with the ui::Compositor is known.
// Registers a CompositorFrameSinkSupport for |frame_sink_id|. |frame_sink_id|
// must be unregistered when |support| is destroyed.
void RegisterCompositorFrameSinkSupport(const FrameSinkId& frame_sink_id,
CompositorFrameSinkSupport* support);
void UnregisterCompositorFrameSinkSupport(const FrameSinkId& frame_sink_id);
// Associates a |source| with a particular framesink. That framesink and
// any children of that framesink with valid clients can potentially use
// that |source|.
void RegisterBeginFrameSource(BeginFrameSource* source,
const FrameSinkId& frame_sink_id);
void UnregisterBeginFrameSource(BeginFrameSource* source);
// Returns a stable BeginFrameSource that forwards BeginFrames from the first
// available BeginFrameSource.
BeginFrameSource* GetPrimaryBeginFrameSource();
SurfaceManager* surface_manager() { return &surface_manager_; }
const HitTestManager* hit_test_manager() { return &hit_test_manager_; }
SharedBitmapManager* shared_bitmap_manager() {
return shared_bitmap_manager_;
}
void SubmitHitTestRegionList(
const SurfaceId& surface_id,
uint64_t frame_index,
base::Optional<HitTestRegionList> hit_test_region_list);
// Instantiates |video_detector_| for tests where we simulate the passage of
// time.
VideoDetector* CreateVideoDetectorForTesting(
const base::TickClock* tick_clock,
scoped_refptr<base::SequencedTaskRunner> task_runner);
// Called when |frame_token| is changed on a submitted CompositorFrame.
void OnFrameTokenChanged(const FrameSinkId& frame_sink_id,
uint32_t frame_token);
void AddObserver(FrameSinkObserver* obs);
void RemoveObserver(FrameSinkObserver* obs);
// Returns the debug label associated with |frame_sink_id| if any.
base::StringPiece GetFrameSinkDebugLabel(
const FrameSinkId& frame_sink_id) const;
// Returns ids of all FrameSinks that were created.
std::vector<FrameSinkId> GetCreatedFrameSinkIds() const;
// Returns ids of all FrameSinks that were registered.
std::vector<FrameSinkId> GetRegisteredFrameSinkIds() const;
// Returns children of a FrameSink that has |parent_frame_sink_id|.
// Returns an empty set if a parent doesn't have any children.
base::flat_set<FrameSinkId> GetChildrenByParent(
const FrameSinkId& parent_frame_sink_id) const;
const CompositorFrameSinkSupport* GetFrameSinkForId(
const FrameSinkId& frame_sink_id) const;
private:
friend class FrameSinkManagerTest;
// Metadata for a CompositorFrameSink.
struct FrameSinkData {
FrameSinkData();
FrameSinkData(FrameSinkData&& other);
~FrameSinkData();
FrameSinkData& operator=(FrameSinkData&& other);
// A label to identify frame sink.
std::string debug_label;
// Record synchronization events for this FrameSinkId if not empty.
std::string synchronization_label;
private:
DISALLOW_COPY_AND_ASSIGN(FrameSinkData);
};
// BeginFrameSource routing information for a FrameSinkId.
struct FrameSinkSourceMapping {
FrameSinkSourceMapping();
FrameSinkSourceMapping(FrameSinkSourceMapping&& other);
~FrameSinkSourceMapping();
FrameSinkSourceMapping& operator=(FrameSinkSourceMapping&& other);
bool has_children() const { return !children.empty(); }
// The currently assigned begin frame source for this client.
BeginFrameSource* source = nullptr;
// This represents a dag of parent -> children mapping.
base::flat_set<FrameSinkId> children;
private:
DISALLOW_COPY_AND_ASSIGN(FrameSinkSourceMapping);
};
void RecursivelyAttachBeginFrameSource(const FrameSinkId& frame_sink_id,
BeginFrameSource* source);
void RecursivelyDetachBeginFrameSource(const FrameSinkId& frame_sink_id,
BeginFrameSource* source);
// FrameSinkVideoCapturerManager implementation:
CapturableFrameSink* FindCapturableFrameSink(
const FrameSinkId& frame_sink_id) override;
void OnCapturerConnectionLost(FrameSinkVideoCapturerImpl* capturer) override;
// Returns true if |child framesink| is or has |search_frame_sink_id| as a
// child.
bool ChildContains(const FrameSinkId& child_frame_sink_id,
const FrameSinkId& search_frame_sink_id) const;
// SharedBitmapManager for the viz display service for receiving software
// resources in CompositorFrameSinks.
SharedBitmapManager* const shared_bitmap_manager_;
// Provides a Display for CreateRootCompositorFrameSink().
DisplayProvider* const display_provider_;
PrimaryBeginFrameSource primary_source_;
// Must be created after and destroyed before |primary_source_|.
SurfaceManager surface_manager_;
// Must be created after and destroyed before |surface_manager_|.
HitTestManager hit_test_manager_;
// Contains registered frame sink ids, debug labels and synchronization
// labels. Map entries will be created when frame sink is registered and
// destroyed when frame sink is invalidated.
base::flat_map<FrameSinkId, FrameSinkData> frame_sink_data_;
// Set of BeginFrameSource along with associated FrameSinkIds. Any child
// that is implicitly using this frame sink must be reachable by the
// parent in the dag.
base::flat_map<BeginFrameSource*, FrameSinkId> registered_sources_;
// Contains FrameSinkId hierarchy and BeginFrameSource mapping.
base::flat_map<FrameSinkId, FrameSinkSourceMapping> frame_sink_source_map_;
// CompositorFrameSinkSupports get added to this map on creation and removed
// on destruction.
base::flat_map<FrameSinkId, CompositorFrameSinkSupport*> support_map_;
// [Root]CompositorFrameSinkImpls are owned in this map.
base::flat_map<FrameSinkId, std::unique_ptr<mojom::CompositorFrameSink>>
sink_map_;
base::flat_set<std::unique_ptr<FrameSinkVideoCapturerImpl>,
base::UniquePtrComparator>
video_capturers_;
THREAD_CHECKER(thread_checker_);
// |video_detector_| is instantiated lazily in order to avoid overhead on
// platforms that don't need video detection.
std::unique_ptr<VideoDetector> video_detector_;
// This will point to |client_ptr_| if using Mojo or a provided client if
// directly connected. Use this to make function calls.
mojom::FrameSinkManagerClient* client_ = nullptr;
mojom::FrameSinkManagerClientPtr client_ptr_;
mojo::Binding<mojom::FrameSinkManager> binding_;
base::ObserverList<FrameSinkObserver>::Unchecked observer_list_;
DISALLOW_COPY_AND_ASSIGN(FrameSinkManagerImpl);
};
} // namespace viz
#endif // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_SINK_MANAGER_IMPL_H_