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
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_EXO_LAYER_TREE_FRAME_SINK_HOLDER_H_
#define COMPONENTS_EXO_LAYER_TREE_FRAME_SINK_HOLDER_H_
#include <memory>
#include <optional>
#include <vector>
#include "base/containers/queue.h"
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "cc/trees/layer_tree_frame_sink_client.h"
#include "components/exo/frame_sink_resource_manager.h"
#include "components/exo/frame_timing_history.h"
#include "components/exo/wm_helper.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/quads/compositor_frame.h"
namespace viz {
struct FrameTimingDetails;
}
namespace cc::mojo_embedder {
class AsyncLayerTreeFrameSink;
}
namespace exo {
class SurfaceTreeHost;
// This class talks to CompositorFrameSink and keeps track of references to
// the contents of Buffers.
class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient,
public WMHelper::LifetimeManager::Observer,
public viz::BeginFrameObserverBase {
public:
LayerTreeFrameSinkHolder(
SurfaceTreeHost* surface_tree_host,
std::unique_ptr<cc::mojo_embedder::AsyncLayerTreeFrameSink> frame_sink);
LayerTreeFrameSinkHolder(const LayerTreeFrameSinkHolder&) = delete;
LayerTreeFrameSinkHolder& operator=(const LayerTreeFrameSinkHolder&) = delete;
~LayerTreeFrameSinkHolder() override;
// Delete frame sink after having reclaimed and called all resource
// release callbacks.
// TODO(reveman): Find a better way to handle deletion of in-flight resources.
// crbug.com/765763
static void DeleteWhenLastResourceHasBeenReclaimed(
std::unique_ptr<LayerTreeFrameSinkHolder> holder);
// If a frame is submitted "now" (meaning before returning to event loop)
// via SubmitCompositorFrame(), whether it needs full damage.
bool NeedsFullDamageForNextFrame() const { return cached_frame_.has_value(); }
void SubmitCompositorFrame(viz::CompositorFrame frame,
bool submit_now = false);
void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id);
// Properties of the `frame` from the last `SubmitCompositorFrame()` call,
// either from `cached_frame_`, or `frame_sink_`.
float LastDeviceScaleFactor() const;
const gfx::Size& LastSizeInPixels() const;
// Returns true if owned LayerTreeFrameSink has been lost.
bool is_lost() const { return is_lost_; }
FrameSinkResourceManager* resource_manager() { return &resource_manager_; }
// Overridden from cc::LayerTreeFrameSinkClient:
void SetBeginFrameSource(viz::BeginFrameSource* source) override;
std::optional<viz::HitTestRegionList> BuildHitTestData() override;
void ReclaimResources(std::vector<viz::ReturnedResource> resources) override;
void SetTreeActivationCallback(base::RepeatingClosure callback) override {}
void DidReceiveCompositorFrameAck() override;
void DidPresentCompositorFrame(
uint32_t frame_token,
const viz::FrameTimingDetails& details) override;
void DidLoseLayerTreeFrameSink() override;
void OnDraw(const gfx::Transform& transform,
const gfx::Rect& viewport,
bool resourceless_software_draw,
bool skip_draw) override {}
void SetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override {}
void SetExternalTilePriorityConstraints(
const gfx::Rect& viewport_rect,
const gfx::Transform& transform) override {}
void ClearPendingBeginFramesForTesting();
void DeleteFrameTimingHistory() { frame_timing_history_.reset(); }
private:
struct PendingBeginFrame {
viz::BeginFrameAck begin_frame_ack;
base::TimeTicks send_deadline_estimate;
};
void ScheduleDelete();
// WMHelper::LifetimeManager::Observer:
void OnDestroyed() override;
// viz::BeginFrameObserverBase:
bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) override;
void OnBeginFrameSourcePausedChanged(bool paused) override;
void SubmitCompositorFrameToRemote(viz::CompositorFrame* frame);
// Discards `cached_frame_`, reclaims resources and returns failure
// presentation feedback.
void DiscardCachedFrame(const viz::CompositorFrame* new_frame);
void SendDiscardedFrameNotifications(uint32_t frame_token);
void StopProcessingPendingFrames();
void OnSendDeadlineExpired(bool update_timer);
// Starts timer based on estimated deadline of the first pending BeginFrame
// request; or stops timer if there is no pending BeginFrame request.
void UpdateSubmitFrameTimer();
void ProcessFirstPendingBeginFrame(viz::CompositorFrame* frame);
bool ShouldSubmitFrameNow() const;
void ObserveBeginFrameSource(bool start);
// Returns true if the feature AutoNeedsBeginFrame is enabled, and currently
// we are not receiving BeginFrame requests. In this case, it is allowed to
// submit an unsolicited frame.
bool UnsolicitedFrameAllowed() const;
raw_ptr<SurfaceTreeHost> surface_tree_host_;
std::unique_ptr<cc::mojo_embedder::AsyncLayerTreeFrameSink> frame_sink_;
FrameSinkResourceManager resource_manager_;
std::vector<viz::ResourceId> last_frame_resources_;
std::optional<viz::CompositorFrame> cached_frame_;
// Resources that are submitted and still in use by the remote side.
std::set<viz::ResourceId> in_use_resources_;
bool is_lost_ = false;
bool delete_pending_ = false;
raw_ptr<WMHelper::LifetimeManager> lifetime_manager_ = nullptr;
raw_ptr<viz::BeginFrameSource> begin_frame_source_ = nullptr;
bool observing_begin_frame_source_ = false;
base::queue<PendingBeginFrame> pending_begin_frames_;
// The number of frames submitted to the remote side for which acks haven't
// been received.
int pending_submit_frames_ = 0;
// A queue of discarded frame tokens for which acks and presentation feedbacks
// haven't been sent to `surface_tree_host_`.
base::queue<uint32_t> pending_discarded_frame_notifications_;
base::DeadlineTimer submit_frame_timer_;
std::optional<FrameTimingHistory> frame_timing_history_;
};
} // namespace exo
#endif // COMPONENTS_EXO_LAYER_TREE_FRAME_SINK_HOLDER_H_
|