blob: 337f3ca108d68714777435b29e1bdc9ad5bc228c [file] [log] [blame]
// 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_