1 /*
2  * Copyright (C) 2007 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 <memory>
20 #include <optional>
21 #include <string>
22 #include <unordered_map>
23 
24 #include <android/native_window.h>
25 #include <binder/IBinder.h>
26 #include <gui/LayerState.h>
27 #include <math/mat4.h>
28 #include <renderengine/RenderEngine.h>
29 #include <system/window.h>
30 #include <ui/DisplayInfo.h>
31 #include <ui/DisplayState.h>
32 #include <ui/GraphicTypes.h>
33 #include <ui/HdrCapabilities.h>
34 #include <ui/Region.h>
35 #include <ui/Transform.h>
36 #include <utils/Mutex.h>
37 #include <utils/RefBase.h>
38 #include <utils/Timers.h>
39 
40 #include "DisplayHardware/DisplayIdentification.h"
41 #include "DisplayHardware/Hal.h"
42 #include "DisplayHardware/PowerAdvisor.h"
43 #include "RenderArea.h"
44 #include "Scheduler/HwcStrongTypes.h"
45 
46 namespace android {
47 
48 class Fence;
49 class HWComposer;
50 class IGraphicBufferProducer;
51 class Layer;
52 class SurfaceFlinger;
53 
54 struct CompositionInfo;
55 struct DisplayDeviceCreationArgs;
56 
57 namespace compositionengine {
58 class Display;
59 class DisplaySurface;
60 } // namespace compositionengine
61 
62 class DisplayDevice : public LightRefBase<DisplayDevice> {
63 public:
64     constexpr static float sDefaultMinLumiance = 0.0;
65     constexpr static float sDefaultMaxLumiance = 500.0;
66 
67     explicit DisplayDevice(DisplayDeviceCreationArgs& args);
68     virtual ~DisplayDevice();
69 
getCompositionDisplay()70     std::shared_ptr<compositionengine::Display> getCompositionDisplay() const {
71         return mCompositionDisplay;
72     }
73 
getConnectionType()74     std::optional<DisplayConnectionType> getConnectionType() const { return mConnectionType; }
75 
isVirtual()76     bool isVirtual() const { return !mConnectionType; }
isPrimary()77     bool isPrimary() const { return mIsPrimary; }
78 
79     // isSecure indicates whether this display can be trusted to display
80     // secure surfaces.
81     bool isSecure() const;
82 
83     int getWidth() const;
84     int getHeight() const;
getSize()85     ui::Size getSize() const { return {getWidth(), getHeight()}; }
86 
87     void setLayerStack(ui::LayerStack);
88     void setDisplaySize(int width, int height);
89     void setProjection(ui::Rotation orientation, Rect viewport, Rect frame);
90 
getPhysicalOrientation()91     ui::Rotation getPhysicalOrientation() const { return mPhysicalOrientation; }
getOrientation()92     ui::Rotation getOrientation() const { return mOrientation; }
93 
94     static ui::Transform::RotationFlags getPrimaryDisplayRotationFlags();
95 
getTransformHint()96     ui::Transform::RotationFlags getTransformHint() const {
97         return static_cast<ui::Transform::RotationFlags>(getTransform().getOrientation());
98     }
99 
100     const ui::Transform& getTransform() const;
101     const Rect& getViewport() const;
102     const Rect& getFrame() const;
103     const Rect& getSourceClip() const;
104     bool needsFiltering() const;
105     ui::LayerStack getLayerStack() const;
106 
107     const std::optional<DisplayId>& getId() const;
getDisplayToken()108     const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
getSequenceId()109     int32_t getSequenceId() const { return mSequenceId; }
110 
111     const Region& getUndefinedRegion() const;
112 
113     int32_t getSupportedPerFrameMetadata() const;
114 
115     bool hasWideColorGamut() const;
116     // Whether h/w composer has native support for specific HDR type.
117     bool hasHDR10PlusSupport() const;
118     bool hasHDR10Support() const;
119     bool hasHLGSupport() const;
120     bool hasDolbyVisionSupport() const;
121 
122     // The returned HdrCapabilities is the combination of HDR capabilities from
123     // hardware composer and RenderEngine. When the DisplayDevice supports wide
124     // color gamut, RenderEngine is able to simulate HDR support in Display P3
125     // color space for both PQ and HLG HDR contents. The minimum and maximum
126     // luminance will be set to sDefaultMinLumiance and sDefaultMaxLumiance
127     // respectively if hardware composer doesn't return meaningful values.
128     const HdrCapabilities& getHdrCapabilities() const;
129 
130     // Return true if intent is supported by the display.
131     bool hasRenderIntent(ui::RenderIntent intent) const;
132 
133     const Rect& getBounds() const;
bounds()134     const Rect& bounds() const { return getBounds(); }
135 
136     void setDisplayName(const std::string& displayName);
getDisplayName()137     const std::string& getDisplayName() const { return mDisplayName; }
138 
139     /* ------------------------------------------------------------------------
140      * Display power mode management.
141      */
142     hardware::graphics::composer::hal::PowerMode getPowerMode() const;
143     void setPowerMode(hardware::graphics::composer::hal::PowerMode mode);
144     bool isPoweredOn() const;
145 
146     ui::Dataspace getCompositionDataSpace() const;
147 
148     /* ------------------------------------------------------------------------
149      * Display active config management.
150      */
151     HwcConfigIndexType getActiveConfig() const;
152     void setActiveConfig(HwcConfigIndexType mode);
153 
154     // release HWC resources (if any) for removable displays
155     void disconnect();
156 
157     /* ------------------------------------------------------------------------
158      * Debugging
159      */
160     uint32_t getPageFlipCount() const;
161     std::string getDebugName() const;
162     void dump(std::string& result) const;
163 
164 private:
165     const sp<SurfaceFlinger> mFlinger;
166     const wp<IBinder> mDisplayToken;
167     const int32_t mSequenceId;
168     const std::optional<DisplayConnectionType> mConnectionType;
169 
170     const std::shared_ptr<compositionengine::Display> mCompositionDisplay;
171 
172     std::string mDisplayName;
173 
174     const ui::Rotation mPhysicalOrientation;
175     ui::Rotation mOrientation = ui::ROTATION_0;
176 
177     static ui::Transform::RotationFlags sPrimaryDisplayRotationFlags;
178 
179     hardware::graphics::composer::hal::PowerMode mPowerMode =
180             hardware::graphics::composer::hal::PowerMode::OFF;
181     HwcConfigIndexType mActiveConfig;
182 
183     // TODO(b/74619554): Remove special cases for primary display.
184     const bool mIsPrimary;
185 };
186 
187 struct DisplayDeviceState {
188     struct Physical {
189         DisplayId id;
190         DisplayConnectionType type;
191         hardware::graphics::composer::hal::HWDisplayId hwcDisplayId;
192 
193         bool operator==(const Physical& other) const {
194             return id == other.id && type == other.type && hwcDisplayId == other.hwcDisplayId;
195         }
196     };
197 
isVirtualDisplayDeviceState198     bool isVirtual() const { return !physical; }
199 
200     int32_t sequenceId = sNextSequenceId++;
201     std::optional<Physical> physical;
202     sp<IGraphicBufferProducer> surface;
203     ui::LayerStack layerStack = ui::NO_LAYER_STACK;
204     Rect viewport;
205     Rect frame;
206     ui::Rotation orientation = ui::ROTATION_0;
207     uint32_t width = 0;
208     uint32_t height = 0;
209     std::string displayName;
210     bool isSecure = false;
211 
212 private:
213     static std::atomic<int32_t> sNextSequenceId;
214 };
215 
216 struct DisplayDeviceCreationArgs {
217     // We use a constructor to ensure some of the values are set, without
218     // assuming a default value.
219     DisplayDeviceCreationArgs(const sp<SurfaceFlinger>&, const wp<IBinder>& displayToken,
220                               std::shared_ptr<compositionengine::Display>);
221     const sp<SurfaceFlinger> flinger;
222     const wp<IBinder> displayToken;
223     const std::shared_ptr<compositionengine::Display> compositionDisplay;
224 
225     int32_t sequenceId{0};
226     std::optional<DisplayConnectionType> connectionType;
227     bool isSecure{false};
228     sp<ANativeWindow> nativeWindow;
229     sp<compositionengine::DisplaySurface> displaySurface;
230     ui::Rotation physicalOrientation{ui::ROTATION_0};
231     bool hasWideColorGamut{false};
232     HdrCapabilities hdrCapabilities;
233     int32_t supportedPerFrameMetadata{0};
234     std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hwcColorModes;
235     hardware::graphics::composer::hal::PowerMode initialPowerMode{
236             hardware::graphics::composer::hal::PowerMode::ON};
237     bool isPrimary{false};
238 };
239 
240 class DisplayRenderArea : public RenderArea {
241 public:
242     DisplayRenderArea(const sp<const DisplayDevice>& display,
243                       RotationFlags rotation = ui::Transform::ROT_0)
244           : DisplayRenderArea(display, display->getBounds(),
245                               static_cast<uint32_t>(display->getWidth()),
246                               static_cast<uint32_t>(display->getHeight()),
247                               display->getCompositionDataSpace(), rotation) {}
248 
249     DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, uint32_t reqWidth,
250                       uint32_t reqHeight, ui::Dataspace reqDataSpace, RotationFlags rotation,
251                       bool allowSecureLayers = true)
252           : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, reqDataSpace,
253                        display->getViewport(), applyDeviceOrientation(rotation, display)),
254             mDisplay(std::move(display)),
255             mSourceCrop(sourceCrop),
256             mAllowSecureLayers(allowSecureLayers) {}
257 
getTransform()258     const ui::Transform& getTransform() const override { return mTransform; }
getBounds()259     Rect getBounds() const override { return mDisplay->getBounds(); }
getHeight()260     int getHeight() const override { return mDisplay->getHeight(); }
getWidth()261     int getWidth() const override { return mDisplay->getWidth(); }
isSecure()262     bool isSecure() const override { return mAllowSecureLayers && mDisplay->isSecure(); }
getDisplayDevice()263     sp<const DisplayDevice> getDisplayDevice() const override { return mDisplay; }
264 
needsFiltering()265     bool needsFiltering() const override {
266         // check if the projection from the logical render area
267         // to the physical render area requires filtering
268         const Rect& sourceCrop = getSourceCrop();
269         int width = sourceCrop.width();
270         int height = sourceCrop.height();
271         if (getRotationFlags() & ui::Transform::ROT_90) {
272             std::swap(width, height);
273         }
274         return width != getReqWidth() || height != getReqHeight();
275     }
276 
getSourceCrop()277     Rect getSourceCrop() const override {
278         // use the projected display viewport by default.
279         if (mSourceCrop.isEmpty()) {
280             return mDisplay->getSourceClip();
281         }
282 
283         // If there is a source crop provided then it is assumed that the device
284         // was in portrait orientation. This may not logically be true, so
285         // correct for the orientation error by undoing the rotation
286 
287         ui::Rotation logicalOrientation = mDisplay->getOrientation();
288         if (logicalOrientation == ui::Rotation::Rotation90) {
289             logicalOrientation = ui::Rotation::Rotation270;
290         } else if (logicalOrientation == ui::Rotation::Rotation270) {
291             logicalOrientation = ui::Rotation::Rotation90;
292         }
293 
294         const auto flags = ui::Transform::toRotationFlags(logicalOrientation);
295         int width = mDisplay->getSourceClip().getWidth();
296         int height = mDisplay->getSourceClip().getHeight();
297         ui::Transform rotation;
298         rotation.set(flags, width, height);
299         return rotation.transform(mSourceCrop);
300     }
301 
302 private:
applyDeviceOrientation(RotationFlags orientationFlag,const sp<const DisplayDevice> & device)303     static RotationFlags applyDeviceOrientation(RotationFlags orientationFlag,
304                                                 const sp<const DisplayDevice>& device) {
305         uint32_t inverseRotate90 = 0;
306         uint32_t inverseReflect = 0;
307 
308         // Reverse the logical orientation.
309         ui::Rotation logicalOrientation = device->getOrientation();
310         if (logicalOrientation == ui::Rotation::Rotation90) {
311             logicalOrientation = ui::Rotation::Rotation270;
312         } else if (logicalOrientation == ui::Rotation::Rotation270) {
313             logicalOrientation = ui::Rotation::Rotation90;
314         }
315 
316         const ui::Rotation orientation = device->getPhysicalOrientation() + logicalOrientation;
317 
318         switch (orientation) {
319             case ui::ROTATION_0:
320                 return orientationFlag;
321 
322             case ui::ROTATION_90:
323                 inverseRotate90 = ui::Transform::ROT_90;
324                 inverseReflect = ui::Transform::ROT_180;
325                 break;
326 
327             case ui::ROTATION_180:
328                 inverseReflect = ui::Transform::ROT_180;
329                 break;
330 
331             case ui::ROTATION_270:
332                 inverseRotate90 = ui::Transform::ROT_90;
333                 break;
334         }
335 
336         const uint32_t rotate90 = orientationFlag & ui::Transform::ROT_90;
337         uint32_t reflect = orientationFlag & ui::Transform::ROT_180;
338 
339         // Apply reflection for double rotation.
340         if (rotate90 & inverseRotate90) {
341             reflect = ~reflect & ui::Transform::ROT_180;
342         }
343 
344         return static_cast<RotationFlags>((rotate90 ^ inverseRotate90) |
345                                           (reflect ^ inverseReflect));
346     }
347 
348     const sp<const DisplayDevice> mDisplay;
349     const Rect mSourceCrop;
350     const bool mAllowSecureLayers;
351     const ui::Transform mTransform = ui::Transform();
352 };
353 
354 } // namespace android
355