1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "Utils/OverlayUtils.h"
20 
21 #include <vector>
22 
23 #include <ftl/flags.h>
24 #include <ftl/small_map.h>
25 #include <ui/LayerStack.h>
26 #include <ui/Size.h>
27 #include <ui/Transform.h>
28 #include <utils/StrongPointer.h>
29 
30 #include <scheduler/Fps.h>
31 
32 class SkCanvas;
33 
34 namespace android {
35 
36 class GraphicBuffer;
37 class SurfaceFlinger;
38 
39 class RefreshRateOverlay {
40 private:
41     // Effectively making the constructor private, while keeping std::make_unique work
42     struct ConstructorTag {};
43 
44 public:
45     enum class Features {
46         Spinner = 1 << 0,
47         RenderRate = 1 << 1,
48         ShowInMiddle = 1 << 2,
49         SetByHwc = 1 << 3,
50     };
51 
52     static std::unique_ptr<RefreshRateOverlay> create(FpsRange, ftl::Flags<Features>);
53 
54     void setLayerStack(ui::LayerStack);
55     void setViewport(ui::Size);
56     void changeRefreshRate(Fps, Fps);
57     void changeRenderRate(Fps);
58     void animate();
isSetByHwc()59     bool isSetByHwc() const { return mFeatures.test(RefreshRateOverlay::Features::SetByHwc); }
60     void onVrrIdle(bool idle);
61 
62     RefreshRateOverlay(ConstructorTag, FpsRange, ftl::Flags<Features>);
63 
64 private:
65     bool initCheck() const;
66 
67     using Buffers = std::vector<sp<GraphicBuffer>>;
68 
69     static Buffers draw(int refreshRate, int renderFps, bool idle, SkColor,
70                         ui::Transform::RotationFlags, ftl::Flags<Features>);
71     static void drawNumber(int number, int left, SkColor, SkCanvas&);
72     static void drawDash(int left, SkCanvas&);
73 
74     const Buffers& getOrCreateBuffers(Fps, Fps, bool);
75 
76     SurfaceComposerClient::Transaction createTransaction() const;
77 
78     struct Key {
79         int refreshRate;
80         int renderFps;
81         ui::Transform::RotationFlags flags;
82         bool idle;
83 
84         bool operator==(Key other) const {
85             return refreshRate == other.refreshRate && renderFps == other.renderFps &&
86                     flags == other.flags && idle == other.idle;
87         }
88     };
89 
90     using BufferCache = ftl::SmallMap<Key, Buffers, 9>;
91     BufferCache mBufferCache;
92 
93     std::optional<Fps> mRefreshRate;
94     std::optional<Fps> mRenderFps;
95     bool mIsVrrIdle = false;
96     size_t mFrame = 0;
97 
98     const FpsRange mFpsRange; // For color interpolation.
99     const ftl::Flags<Features> mFeatures;
100 
101     const std::unique_ptr<SurfaceControlHolder> mSurfaceControl;
102 };
103 
104 } // namespace android
105