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
|
// Copyright 2019 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_VIZ_SERVICE_DISPLAY_DISPLAY_DAMAGE_TRACKER_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_DAMAGE_TRACKER_H_
#include <memory>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/service/surfaces/surface_observer.h"
#include "components/viz/service/viz_service_export.h"
namespace viz {
class SurfaceAggregator;
class SurfaceManager;
// DisplayDamageTracker is used to track Surfaces damage that belong to current
// Display. It tracks pending damage when clients received BeginFrames but
// didn't replied yet and it tracks whether damage to those surfaces contribute
// to Display damage. Used by DisplayScheduler to determine frame deadlines.
class VIZ_SERVICE_EXPORT DisplayDamageTracker : public SurfaceObserver {
public:
class VIZ_SERVICE_EXPORT Delegate {
public:
virtual ~Delegate() = default;
virtual void OnDisplayDamaged(SurfaceId surface_id) = 0;
virtual void OnRootFrameMissing(bool missing) = 0;
virtual void OnPendingSurfacesChanged() = 0;
};
DisplayDamageTracker(SurfaceManager* surface_manager,
SurfaceAggregator* aggregator);
~DisplayDamageTracker() override;
DisplayDamageTracker(const DisplayDamageTracker&) = delete;
DisplayDamageTracker& operator=(const DisplayDamageTracker&) = delete;
// Sets the source_id associated with this displays begin frame source.
// DisplayDamageTracker ignores expected damage from frame sinks that received
// a begin frame from a different begin frame source after this is set.
void SetDisplayBeginFrameSourceId(uint64_t begin_frame_source_id);
void SetDelegate(Delegate* delegate);
// Notification that there was a resize and we should expect root surface
// damage.
void DisplayResized();
// Notification that the root surface changed.
void SetNewRootSurface(const SurfaceId& root_surface_id);
// Mark root surface as damaged.
void SetRootSurfaceDamaged();
// Send Surface Acks to damaged surfaces after draw.
void RunDrawCallbacks();
// This returns whether there are pending surfaces. SurfaceIs pending if the
// corresponding CompositorFrameSink has received BeginFrame but hasn't
// replied with Ack yet.
bool HasPendingSurfaces(const BeginFrameArgs& begin_frame_args);
// Returns true if any of the damage received was due to an ongoing scroll or
// touch interaction.
bool HasDamageDueToInteraction();
// Called after a frame finishes (may or may not result in a draw).
void DidFinishFrame();
// Returns true if damage to this Surface could affect the display.
bool CheckForDisplayDamage(const SurfaceId& surface_id);
bool root_frame_missing() const { return root_frame_missing_; }
bool IsRootSurfaceValid() const;
bool expecting_root_surface_damage_because_of_resize() const {
return expecting_root_surface_damage_because_of_resize_;
}
void reset_expecting_root_surface_damage_because_of_resize() {
expecting_root_surface_damage_because_of_resize_ = false;
}
// SurfaceObserver implementation.
void OnSurfaceMarkedForDestruction(const SurfaceId& surface_id) override;
bool OnSurfaceDamaged(const SurfaceId& surface_id,
const BeginFrameAck& ack,
HandleInteraction handle_interaction) override;
void OnSurfaceDamageExpected(const SurfaceId& surface_id,
const BeginFrameArgs& args) override;
protected:
struct SurfaceBeginFrameState {
BeginFrameArgs last_args;
BeginFrameAck last_ack;
};
virtual bool SurfaceHasUnackedFrame(const SurfaceId& surface_id) const;
virtual void UpdateRootFrameMissing();
void SetRootFrameMissing(bool missing);
// Checks if the begin frame `source_id` is for this display. This will return
// true if:
// 1. `source_id` matches the display source id.
// 2. Display source id was never set.
// 3. `source_id` is a manual source id since that could be relevant for any
// display.
bool CheckBeginFrameSourceId(uint64_t source_id);
// Indicates that there was damage to one of the surfaces.
void ProcessSurfaceDamage(const SurfaceId& surface_id,
const BeginFrameAck& ack,
bool display_damaged,
HandleInteraction handle_interaction);
// Used to send corresponding notifications to observers.
void NotifyDisplayDamaged(SurfaceId surface_id);
void NotifyRootFrameMissing(bool missing);
void NotifyPendingSurfacesChanged();
raw_ptr<Delegate> delegate_ = nullptr;
const raw_ptr<SurfaceManager> surface_manager_;
const raw_ptr<SurfaceAggregator> aggregator_;
std::optional<uint64_t> begin_frame_source_id_;
bool root_frame_missing_ = true;
bool expecting_root_surface_damage_because_of_resize_ = false;
bool has_surface_damage_due_to_interaction_ = false;
base::flat_map<SurfaceId, SurfaceBeginFrameState> surface_states_;
std::vector<SurfaceId> surfaces_to_ack_on_next_draw_;
SurfaceId root_surface_id_;
};
} // namespace viz
#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_DAMAGE_TRACKER_H_
|