• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 #ifndef ANDROID_SF_HWCOMPOSER_H
18 #define ANDROID_SF_HWCOMPOSER_H
19 
20 #include <cstdint>
21 #include <future>
22 #include <memory>
23 #include <mutex>
24 #include <optional>
25 #include <unordered_map>
26 #include <unordered_set>
27 #include <vector>
28 
29 #include <android-base/thread_annotations.h>
30 #include <ui/FenceTime.h>
31 
32 // TODO(b/129481165): remove the #pragma below and fix conversion issues
33 #pragma clang diagnostic push
34 #pragma clang diagnostic ignored "-Wconversion"
35 #pragma clang diagnostic ignored "-Wextra"
36 #include <ui/GraphicTypes.h>
37 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
38 
39 #include <utils/StrongPointer.h>
40 #include <utils/Timers.h>
41 
42 #include "DisplayIdentification.h"
43 #include "DisplayMode.h"
44 #include "HWC2.h"
45 #include "Hal.h"
46 
47 namespace android {
48 
49 namespace hal = hardware::graphics::composer::hal;
50 
51 struct DisplayedFrameStats;
52 class GraphicBuffer;
53 class TestableSurfaceFlinger;
54 struct CompositionInfo;
55 
56 namespace Hwc2 {
57 class Composer;
58 } // namespace Hwc2
59 
60 namespace compositionengine {
61 class Output;
62 } // namespace compositionengine
63 
64 struct KnownHWCGenericLayerMetadata {
65     const char* name;
66     const uint32_t id;
67 };
68 
69 // See the comment for SurfaceFlinger::getHwComposer for the thread safety rules for accessing
70 // this class.
71 class HWComposer {
72 public:
73     struct DeviceRequestedChanges {
74         using ChangedTypes = std::unordered_map<HWC2::Layer*, hal::Composition>;
75         using ClientTargetProperty = hal::ClientTargetProperty;
76         using DisplayRequests = hal::DisplayRequest;
77         using LayerRequests = std::unordered_map<HWC2::Layer*, hal::LayerRequest>;
78 
79         ChangedTypes changedTypes;
80         DisplayRequests displayRequests;
81         LayerRequests layerRequests;
82         ClientTargetProperty clientTargetProperty;
83     };
84 
85     struct HWCDisplayMode {
86         hal::HWConfigId hwcId;
87         int32_t width = -1;
88         int32_t height = -1;
89         nsecs_t vsyncPeriod = -1;
90         int32_t dpiX = -1;
91         int32_t dpiY = -1;
92         int32_t configGroup = -1;
93 
94         friend std::ostream& operator<<(std::ostream& os, const HWCDisplayMode& mode) {
95             return os << "id=" << mode.hwcId << " res=" << mode.width << "x" << mode.height
96                       << " vsyncPeriod=" << mode.vsyncPeriod << " dpi=" << mode.dpiX << "x"
97                       << mode.dpiY << " group=" << mode.configGroup;
98         }
99     };
100 
101     virtual ~HWComposer();
102 
103     virtual void setCallback(HWC2::ComposerCallback*) = 0;
104 
105     virtual bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort,
106                                               DisplayIdentificationData* outData) const = 0;
107 
108     virtual bool hasCapability(hal::Capability) const = 0;
109     virtual bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const = 0;
110 
111     virtual size_t getMaxVirtualDisplayCount() const = 0;
112     virtual size_t getMaxVirtualDisplayDimension() const = 0;
113 
114     // Attempts to allocate a virtual display on the HWC. The maximum number of virtual displays
115     // supported by the HWC can be queried in advance, but allocation may fail for other reasons.
116     // For virtualized compositors, the PhysicalDisplayId is a hint that this virtual display is
117     // a mirror of a physical display, and that the screen should be captured by the host rather
118     // than guest compositor.
119     virtual bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*,
120                                         std::optional<PhysicalDisplayId> mirror) = 0;
121 
122     virtual void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) = 0;
123 
124     // Attempts to create a new layer on this display
125     virtual std::shared_ptr<HWC2::Layer> createLayer(HalDisplayId) = 0;
126 
127     // Gets any required composition change requests from the HWC device.
128     //
129     // Note that frameUsesClientComposition must be set correctly based on
130     // whether the current frame appears to use client composition. If it is
131     // false some internal optimizations are allowed to present the display
132     // with fewer handshakes, but this does not work if client composition is
133     // expected.
134     virtual status_t getDeviceCompositionChanges(
135             HalDisplayId, bool frameUsesClientComposition,
136             std::chrono::steady_clock::time_point earliestPresentTime,
137             const std::shared_ptr<FenceTime>& previousPresentFence,
138             std::optional<DeviceRequestedChanges>* outChanges) = 0;
139 
140     virtual status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
141                                      const sp<GraphicBuffer>& target, ui::Dataspace) = 0;
142 
143     // Present layers to the display and read releaseFences.
144     virtual status_t presentAndGetReleaseFences(
145             HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime,
146             const std::shared_ptr<FenceTime>& previousPresentFence) = 0;
147 
148     // set power mode
149     virtual status_t setPowerMode(PhysicalDisplayId, hal::PowerMode) = 0;
150 
151     // Sets a color transform to be applied to the result of composition
152     virtual status_t setColorTransform(HalDisplayId, const mat4& transform) = 0;
153 
154     // reset state when a display is disconnected
155     virtual void disconnectDisplay(HalDisplayId) = 0;
156 
157     // get the present fence received from the last call to present.
158     virtual sp<Fence> getPresentFence(HalDisplayId) const = 0;
159 
160     // Get last release fence for the given layer
161     virtual sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const = 0;
162 
163     // Set the output buffer and acquire fence for a virtual display.
164     virtual status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
165                                      const sp<GraphicBuffer>& buffer) = 0;
166 
167     // After SurfaceFlinger has retrieved the release fences for all the frames,
168     // it can call this to clear the shared pointers in the release fence map
169     virtual void clearReleaseFences(HalDisplayId) = 0;
170 
171     // Fetches the HDR capabilities of the given display
172     virtual status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) = 0;
173 
174     virtual int32_t getSupportedPerFrameMetadata(HalDisplayId) const = 0;
175 
176     // Returns the available RenderIntent of the given display.
177     virtual std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const = 0;
178 
179     virtual mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) = 0;
180 
181     // Returns the attributes of the color sampling engine.
182     virtual status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
183                                                            ui::Dataspace* outDataspace,
184                                                            uint8_t* outComponentMask) = 0;
185     virtual status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled,
186                                                       uint8_t componentMask,
187                                                       uint64_t maxFrames) = 0;
188     virtual status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
189                                                DisplayedFrameStats* outStats) = 0;
190 
191     // Sets the brightness of a display.
192     virtual std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) = 0;
193 
194     // Events handling ---------------------------------------------------------
195 
196     // Returns stable display ID (and display name on connection of new or previously disconnected
197     // display), or std::nullopt if hotplug event was ignored.
198     // This function is called from SurfaceFlinger.
199     virtual std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId,
200                                                                hal::Connection) = 0;
201 
202     // If true we'll update the DeviceProductInfo on subsequent hotplug connected events.
203     // TODO(b/157555476): Remove when the framework has proper support for headless mode
204     virtual bool updatesDeviceProductInfoOnHotplugReconnect() const = 0;
205 
206     virtual bool onVsync(hal::HWDisplayId, int64_t timestamp) = 0;
207     virtual void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0;
208 
209     virtual bool isConnected(PhysicalDisplayId) const = 0;
210 
211     virtual std::vector<HWCDisplayMode> getModes(PhysicalDisplayId) const = 0;
212 
213     virtual std::optional<hal::HWConfigId> getActiveMode(PhysicalDisplayId) const = 0;
214 
215     virtual std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const = 0;
216 
217     virtual status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode mode,
218                                         ui::RenderIntent) = 0;
219 
220     // Composer 2.4
221     virtual ui::DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const = 0;
222     virtual bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const = 0;
223     virtual status_t getDisplayVsyncPeriod(PhysicalDisplayId displayId,
224                                            nsecs_t* outVsyncPeriod) const = 0;
225     virtual status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId,
226                                                   const hal::VsyncPeriodChangeConstraints&,
227                                                   hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
228     virtual status_t setAutoLowLatencyMode(PhysicalDisplayId, bool on) = 0;
229     virtual status_t getSupportedContentTypes(
230             PhysicalDisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
231     virtual status_t setContentType(PhysicalDisplayId, hal::ContentType) = 0;
232     virtual const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata()
233             const = 0;
234 
235     // for debugging ----------------------------------------------------------
236     virtual void dump(std::string& out) const = 0;
237 
238     virtual Hwc2::Composer* getComposer() const = 0;
239 
240     // TODO(b/74619554): Remove special cases for internal/external display.
241     virtual std::optional<hal::HWDisplayId> getInternalHwcDisplayId() const = 0;
242     virtual std::optional<hal::HWDisplayId> getExternalHwcDisplayId() const = 0;
243 
244     virtual std::optional<PhysicalDisplayId> toPhysicalDisplayId(hal::HWDisplayId) const = 0;
245     virtual std::optional<hal::HWDisplayId> fromPhysicalDisplayId(PhysicalDisplayId) const = 0;
246 };
247 
248 namespace impl {
249 
250 class HWComposer final : public android::HWComposer {
251 public:
252     explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);
253     explicit HWComposer(const std::string& composerServiceName);
254 
255     ~HWComposer() override;
256 
257     void setCallback(HWC2::ComposerCallback*) override;
258 
259     bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort,
260                                       DisplayIdentificationData* outData) const override;
261 
262     bool hasCapability(hal::Capability) const override;
263     bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const override;
264 
265     size_t getMaxVirtualDisplayCount() const override;
266     size_t getMaxVirtualDisplayDimension() const override;
267 
268     bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*,
269                                 std::optional<PhysicalDisplayId>) override;
270 
271     // Called from SurfaceFlinger, when the state for a new physical display needs to be recreated.
272     void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) override;
273 
274     // Attempts to create a new layer on this display
275     std::shared_ptr<HWC2::Layer> createLayer(HalDisplayId) override;
276 
277     status_t getDeviceCompositionChanges(
278             HalDisplayId, bool frameUsesClientComposition,
279             std::chrono::steady_clock::time_point earliestPresentTime,
280             const std::shared_ptr<FenceTime>& previousPresentFence,
281             std::optional<DeviceRequestedChanges>* outChanges) override;
282 
283     status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
284                              const sp<GraphicBuffer>& target, ui::Dataspace) override;
285 
286     // Present layers to the display and read releaseFences.
287     status_t presentAndGetReleaseFences(
288             HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime,
289             const std::shared_ptr<FenceTime>& previousPresentFence) override;
290 
291     // set power mode
292     status_t setPowerMode(PhysicalDisplayId, hal::PowerMode mode) override;
293 
294     // Sets a color transform to be applied to the result of composition
295     status_t setColorTransform(HalDisplayId, const mat4& transform) override;
296 
297     // reset state when a display is disconnected
298     void disconnectDisplay(HalDisplayId) override;
299 
300     // get the present fence received from the last call to present.
301     sp<Fence> getPresentFence(HalDisplayId) const override;
302 
303     // Get last release fence for the given layer
304     sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const override;
305 
306     // Set the output buffer and acquire fence for a virtual display.
307     status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
308                              const sp<GraphicBuffer>& buffer) override;
309 
310     // After SurfaceFlinger has retrieved the release fences for all the frames,
311     // it can call this to clear the shared pointers in the release fence map
312     void clearReleaseFences(HalDisplayId) override;
313 
314     // Fetches the HDR capabilities of the given display
315     status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) override;
316 
317     int32_t getSupportedPerFrameMetadata(HalDisplayId) const override;
318 
319     // Returns the available RenderIntent of the given display.
320     std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const override;
321 
322     mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) override;
323 
324     // Returns the attributes of the color sampling engine.
325     status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
326                                                    ui::Dataspace* outDataspace,
327                                                    uint8_t* outComponentMask) override;
328     status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled, uint8_t componentMask,
329                                               uint64_t maxFrames) override;
330     status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
331                                        DisplayedFrameStats* outStats) override;
332     std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) override;
333 
334     // Events handling ---------------------------------------------------------
335 
336     // Returns PhysicalDisplayId (and display name on connection of new or previously disconnected
337     // display), or std::nullopt if hotplug event was ignored.
338     std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, hal::Connection) override;
339 
340     bool updatesDeviceProductInfoOnHotplugReconnect() const override;
341 
342     bool onVsync(hal::HWDisplayId, int64_t timestamp) override;
343     void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) override;
344 
345     bool isConnected(PhysicalDisplayId) const override;
346 
347     std::vector<HWCDisplayMode> getModes(PhysicalDisplayId) const override;
348 
349     std::optional<hal::HWConfigId> getActiveMode(PhysicalDisplayId) const override;
350 
351     std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const override;
352 
353     status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent) override;
354 
355     // Composer 2.4
356     ui::DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const override;
357     bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const override;
358     status_t getDisplayVsyncPeriod(PhysicalDisplayId displayId,
359                                    nsecs_t* outVsyncPeriod) const override;
360     status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId,
361                                           const hal::VsyncPeriodChangeConstraints&,
362                                           hal::VsyncPeriodChangeTimeline* outTimeline) override;
363     status_t setAutoLowLatencyMode(PhysicalDisplayId, bool) override;
364     status_t getSupportedContentTypes(PhysicalDisplayId, std::vector<hal::ContentType>*) override;
365     status_t setContentType(PhysicalDisplayId, hal::ContentType) override;
366 
367     const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override;
368 
369     // for debugging ----------------------------------------------------------
370     void dump(std::string& out) const override;
371 
getComposer()372     Hwc2::Composer* getComposer() const override { return mComposer.get(); }
373 
374     // TODO(b/74619554): Remove special cases for internal/external display.
getInternalHwcDisplayId()375     std::optional<hal::HWDisplayId> getInternalHwcDisplayId() const override {
376         return mInternalHwcDisplayId;
377     }
getExternalHwcDisplayId()378     std::optional<hal::HWDisplayId> getExternalHwcDisplayId() const override {
379         return mExternalHwcDisplayId;
380     }
381 
382     std::optional<PhysicalDisplayId> toPhysicalDisplayId(hal::HWDisplayId) const override;
383     std::optional<hal::HWDisplayId> fromPhysicalDisplayId(PhysicalDisplayId) const override;
384 
385 private:
386     // For unit tests
387     friend TestableSurfaceFlinger;
388 
389     struct DisplayData {
390         bool isVirtual = false;
391         std::unique_ptr<HWC2::Display> hwcDisplay;
392         sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires
393         std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
394         buffer_handle_t outbufHandle = nullptr;
395         sp<Fence> outbufAcquireFence = Fence::NO_FENCE;
396 
397         bool validateWasSkipped;
398         hal::Error presentError;
399 
400         bool vsyncTraceToggle = false;
401 
402         std::mutex vsyncEnabledLock;
403         hal::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = hal::Vsync::DISABLE;
404 
405         nsecs_t lastHwVsync = 0;
406     };
407 
408     std::optional<DisplayIdentificationInfo> onHotplugConnect(hal::HWDisplayId);
409     std::optional<DisplayIdentificationInfo> onHotplugDisconnect(hal::HWDisplayId);
410     bool shouldIgnoreHotplugConnect(hal::HWDisplayId, bool hasDisplayIdentificationData) const;
411 
412     int32_t getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId,
413                          hal::Attribute attribute) const;
414 
415     void loadCapabilities();
416     void loadLayerMetadataSupport();
417 
418     std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
419 
420     std::unique_ptr<android::Hwc2::Composer> mComposer;
421     std::unordered_set<hal::Capability> mCapabilities;
422     std::unordered_map<std::string, bool> mSupportedLayerGenericMetadata;
423     bool mRegisteredCallback = false;
424 
425     std::unordered_map<hal::HWDisplayId, PhysicalDisplayId> mPhysicalDisplayIdMap;
426     std::optional<hal::HWDisplayId> mInternalHwcDisplayId;
427     std::optional<hal::HWDisplayId> mExternalHwcDisplayId;
428     bool mHasMultiDisplaySupport = false;
429 
430     const size_t mMaxVirtualDisplayDimension;
431     const bool mUpdateDeviceProductInfoOnHotplugReconnect;
432 };
433 
434 } // namespace impl
435 } // namespace android
436 
437 #endif // ANDROID_SF_HWCOMPOSER_H
438