/* * 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 #include #include #include #include #include #include #include #include #include "EventThread.h" #include "FrameRateCompatibility.h" #include "RefreshRateSelector.h" namespace android { class Layer; namespace scheduler { class LayerInfo; struct LayerProps; class LayerHistory { public: using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride; using LayerVoteType = RefreshRateSelector::LayerVoteType; static constexpr std::chrono::nanoseconds kMaxPeriodForHistory = 1s; LayerHistory(); ~LayerHistory(); // Layers are unregistered when the weak reference expires. void registerLayer(Layer*, bool contentDetectionEnabled); // Sets the display size. Client is responsible for synchronization. void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; } // Sets whether a mode change is pending to be applied void setModeChangePending(bool pending) { mModeChangePending = pending; } // 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. void record(int32_t id, const LayerProps& props, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType); // Updates the default frame rate compatibility which takes effect when the app // does not set a preference for refresh rate. void setDefaultFrameRateCompatibility(int32_t id, FrameRateCompatibility frameRateCompatibility, bool contentDetectionEnabled); void setLayerProperties(int32_t id, const LayerProps&); using Summary = std::vector; // Rebuilds sets of active/inactive layers, and accumulates stats for active layers. Summary summarize(const RefreshRateSelector&, nsecs_t now); void clear(); void deregisterLayer(Layer*); std::string dump() const; // return the frames per second of the layer with the given sequence id. float getLayerFramerate(nsecs_t now, int32_t id) const; bool isSmallDirtyArea(uint32_t dirtyArea, float threshold) const; // Updates the frame rate override set by game mode intervention void updateGameModeFrameRateOverride(FrameRateOverride frameRateOverride) EXCLUDES(mLock); // Updates the frame rate override set by game default frame rate void updateGameDefaultFrameRateOverride(FrameRateOverride frameRateOverride) EXCLUDES(mLock); std::pair getGameFrameRateOverride(uid_t uid) const EXCLUDES(mLock); std::pair getGameFrameRateOverrideLocked(uid_t uid) const REQUIRES(mLock); private: friend class LayerHistoryTest; friend class LayerHistoryIntegrationTest; friend class TestableScheduler; using LayerPair = std::pair>; // keyed by id as returned from Layer::getSequence() using LayerInfos = std::unordered_map; std::string dumpGameFrameRateOverridesLocked() const REQUIRES(mLock); // Iterates over layers maps moving all active layers to mActiveLayerInfos and all inactive // layers to mInactiveLayerInfos. Layer's active state is determined by multiple factors // such as update activity, visibility, and frame rate vote. // worst case time complexity is O(2 * inactive + active) // now: the current time (system time) when calling the method // isVrrDevice: true if the device has DisplayMode with VrrConfig specified. void partitionLayers(nsecs_t now, bool isVrrDevice) REQUIRES(mLock); enum class LayerStatus { NotFound, LayerInActiveMap, LayerInInactiveMap, }; // looks up a layer by sequence id in both layerInfo maps. // The first element indicates if and where the item was found std::pair findLayer(int32_t id) REQUIRES(mLock); std::pair findLayer(int32_t id) const REQUIRES(mLock) { return const_cast(this)->findLayer(id); } mutable std::mutex mLock; // Partitioned into two maps to facility two kinds of retrieval: // 1. retrieval of a layer by id (attempt lookup in both maps) // 2. retrieval of all active layers (iterate that map) // The partitioning is allowed to become out of date but calling partitionLayers refreshes the // validity of each map. LayerInfos mActiveLayerInfos GUARDED_BY(mLock); LayerInfos mInactiveLayerInfos GUARDED_BY(mLock); 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 mode change is in progress or not std::atomic mModeChangePending = false; // A list to look up the game frame rate overrides // Each entry includes: // 1. the uid of the app // 2. a pair of game mode intervention frame frame and game default frame rate override // set to 0.0 if there is no such override std::map> mGameFrameRateOverride GUARDED_BY(mLock); }; } // namespace scheduler } // namespace android