blob: 778169d05f91861b2cd65b2f6e6e3f3c5284e453 [file] [log] [blame]
#ifndef ANDROID_DVR_SERVICES_DISPLAYD_DEBUG_HUD_DATA_H_
#define ANDROID_DVR_SERVICES_DISPLAYD_DEBUG_HUD_DATA_H_
#include <stdint.h>
#include <private/dvr/clock_ns.h>
#include <private/dvr/frame_time_history.h>
namespace android {
namespace dvr {
// Tracks debug stats for the displayd debug HUD. Unless otherwise noted,
// there is no synchronization of data accesses to avoid performance impact.
// All accesses to this data are on the displayd HWC post thread. Accesses from
// other threads will need to be duly protected from races.
// This is a lightweight struct to make it easy to add and remove
// tracking data.
struct DebugHudData {
// Maximum supported layers for the debug HUD.
enum { kMaxLayers = 4 };
// The global singleton HUD data instance.
static DebugHudData data;
// Tracks framerate and skipped frames.
struct FrameStats {
void AddFrame() {
int64_t now = GetSystemClockNs();
frame_time.AddSample(now - last_frame_ts);
last_frame_ts = now;
}
void SkipFrame() {
AddFrame();
++drops;
}
int drops = 0;
int64_t last_frame_ts = 0;
FrameTimeHistory frame_time;
};
// Debug data for compositor layers (applications, system UI, etc).
struct LayerData {
void Reset() {
ResetStats();
width = 0;
height = 0;
is_separate = false;
}
void ResetStats() { frame_stats.drops = 0; }
FrameStats frame_stats;
int width = 0;
int height = 0;
bool is_separate = false;
};
// Resets the stats.
void ResetStats() {
hwc_frame_stats.drops = 0;
hwc_latency = 0;
for (auto& l : layer_data)
l.ResetStats();
}
// Resets the layer configuration.
void ResetLayers() {
num_layers = 0;
for (auto& l : layer_data)
l.Reset();
}
// Tracks a frame arrival for the given layer.
void AddLayerFrame(size_t layer) {
if (layer < kMaxLayers) {
num_layers = std::max(layer + 1, num_layers);
layer_data[layer].frame_stats.AddFrame();
}
}
// Tracks a frame skip/drop for the given layer.
void SkipLayerFrame(size_t layer) {
if (layer < kMaxLayers) {
num_layers = std::max(layer + 1, num_layers);
layer_data[layer].frame_stats.SkipFrame();
}
}
// Sets the resolution and other details of the layer.
void SetLayerInfo(size_t layer, int width, int height, bool is_separate) {
if (layer < kMaxLayers) {
num_layers = std::max(layer + 1, num_layers);
layer_data[layer].width = width;
layer_data[layer].height = height;
layer_data[layer].is_separate = is_separate;
}
}
FrameStats hwc_frame_stats;
int64_t hwc_latency = 0;
size_t num_layers = 0;
LayerData layer_data[kMaxLayers];
};
} // namespace dvr
} // namespace android
#endif // ANDROID_DVR_SERVICES_DISPLAYD_DEBUG_HUD_DATA_H_