blob: 228b8a06afb4381d88fa226acd67a6b2d93e0f87 [file] [log] [blame]
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <android-base/thread_annotations.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <memory>
#include <mutex>
#include <utility>
#include <vector>
#include "RefreshRateConfigs.h"
namespace android {
class Layer;
class TestableScheduler;
namespace scheduler {
class LayerHistoryTest;
class LayerHistoryTestV2;
class LayerInfo;
class LayerInfoV2;
class LayerHistory {
public:
using LayerVoteType = RefreshRateConfigs::LayerVoteType;
virtual ~LayerHistory() = default;
// Layers are unregistered when the weak reference expires.
virtual void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
LayerVoteType type) = 0;
// Sets the display size. Client is responsible for synchronization.
virtual void setDisplayArea(uint32_t displayArea) = 0;
// Sets whether a config change is pending to be applied
virtual void setConfigChangePending(bool pending) = 0;
// Represents which layer activity is recorded
enum class LayerUpdateType {
Buffer, // a new buffer queued
AnimationTX, // a new transaction with eAnimation flag set
SetFrameRate, // setFrameRate API was called
};
// Marks the layer as active, and records the given state to its history.
virtual void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) = 0;
using Summary = std::vector<RefreshRateConfigs::LayerRequirement>;
// Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
virtual Summary summarize(nsecs_t now) = 0;
virtual void clear() = 0;
};
namespace impl {
// Records per-layer history of scheduling-related information (primarily present time),
// heuristically categorizes layers as active or inactive, and summarizes stats about
// active layers (primarily maximum refresh rate). See go/content-fps-detection-in-scheduler.
class LayerHistory : public android::scheduler::LayerHistory {
public:
LayerHistory();
virtual ~LayerHistory();
// Layers are unregistered when the weak reference expires.
void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
LayerVoteType type) override;
void setDisplayArea(uint32_t /*displayArea*/) override {}
void setConfigChangePending(bool /*pending*/) override {}
// Marks the layer as active, and records the given state to its history.
void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) override;
// Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
android::scheduler::LayerHistory::Summary summarize(nsecs_t now) override;
void clear() override;
private:
friend class android::scheduler::LayerHistoryTest;
friend TestableScheduler;
using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfo>>;
using LayerInfos = std::vector<LayerPair>;
struct ActiveLayers {
LayerInfos& infos;
const size_t index;
auto begin() { return infos.begin(); }
auto end() { return begin() + static_cast<long>(index); }
};
ActiveLayers activeLayers() REQUIRES(mLock) { return {mLayerInfos, mActiveLayersEnd}; }
// Iterates over layers in a single pass, swapping pairs such that active layers precede
// inactive layers, and inactive layers precede expired layers. Removes expired layers by
// truncating after inactive layers.
void partitionLayers(nsecs_t now) REQUIRES(mLock);
mutable std::mutex mLock;
// Partitioned such that active layers precede inactive layers. For fast lookup, the few active
// layers are at the front, and weak pointers are stored in contiguous memory to hit the cache.
LayerInfos mLayerInfos GUARDED_BY(mLock);
size_t mActiveLayersEnd GUARDED_BY(mLock) = 0;
// Whether to emit systrace output and debug logs.
const bool mTraceEnabled;
// Whether to use priority sent from WindowManager to determine the relevancy of the layer.
const bool mUseFrameRatePriority;
};
class LayerHistoryV2 : public android::scheduler::LayerHistory {
public:
LayerHistoryV2(const scheduler::RefreshRateConfigs&);
virtual ~LayerHistoryV2();
// Layers are unregistered when the weak reference expires.
void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
LayerVoteType type) override;
// Sets the display size. Client is responsible for synchronization.
void setDisplayArea(uint32_t displayArea) override { mDisplayArea = displayArea; }
void setConfigChangePending(bool pending) override { mConfigChangePending = pending; }
// Marks the layer as active, and records the given state to its history.
void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) override;
// Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
android::scheduler::LayerHistory::Summary summarize(nsecs_t /*now*/) override;
void clear() override;
private:
friend android::scheduler::LayerHistoryTestV2;
friend TestableScheduler;
using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfoV2>>;
using LayerInfos = std::vector<LayerPair>;
struct ActiveLayers {
LayerInfos& infos;
const size_t index;
auto begin() { return infos.begin(); }
auto end() { return begin() + static_cast<long>(index); }
};
ActiveLayers activeLayers() REQUIRES(mLock) { return {mLayerInfos, mActiveLayersEnd}; }
// Iterates over layers in a single pass, swapping pairs such that active layers precede
// inactive layers, and inactive layers precede expired layers. Removes expired layers by
// truncating after inactive layers.
void partitionLayers(nsecs_t now) REQUIRES(mLock);
mutable std::mutex mLock;
// Partitioned such that active layers precede inactive layers. For fast lookup, the few active
// layers are at the front, and weak pointers are stored in contiguous memory to hit the cache.
LayerInfos mLayerInfos GUARDED_BY(mLock);
size_t mActiveLayersEnd GUARDED_BY(mLock) = 0;
uint32_t mDisplayArea = 0;
// Whether to emit systrace output and debug logs.
const bool mTraceEnabled;
// Whether to use priority sent from WindowManager to determine the relevancy of the layer.
const bool mUseFrameRatePriority;
// Whether a config change is in progress or not
std::atomic<bool> mConfigChangePending = false;
};
} // namespace impl
} // namespace scheduler
} // namespace android