|  | /* | 
|  | * Copyright (C) 2007 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. | 
|  | */ | 
|  |  | 
|  | #ifndef ANDROID_DISPLAY_DEVICE_H | 
|  | #define ANDROID_DISPLAY_DEVICE_H | 
|  |  | 
|  | #include <stdlib.h> | 
|  |  | 
|  | #include <memory> | 
|  | #include <optional> | 
|  | #include <string> | 
|  | #include <unordered_map> | 
|  |  | 
|  | #include <android/native_window.h> | 
|  | #include <binder/IBinder.h> | 
|  | #include <gui/LayerState.h> | 
|  | #include <hardware/hwcomposer_defs.h> | 
|  | #include <math/mat4.h> | 
|  | #include <renderengine/RenderEngine.h> | 
|  | #include <system/window.h> | 
|  | #include <ui/GraphicTypes.h> | 
|  | #include <ui/HdrCapabilities.h> | 
|  | #include <ui/Region.h> | 
|  | #include <ui/Transform.h> | 
|  | #include <utils/Mutex.h> | 
|  | #include <utils/RefBase.h> | 
|  | #include <utils/Timers.h> | 
|  |  | 
|  | #include "DisplayHardware/DisplayIdentification.h" | 
|  | #include "RenderArea.h" | 
|  |  | 
|  | namespace android { | 
|  |  | 
|  | class Fence; | 
|  | class HWComposer; | 
|  | class IGraphicBufferProducer; | 
|  | class Layer; | 
|  | class SurfaceFlinger; | 
|  |  | 
|  | struct CompositionInfo; | 
|  | struct DisplayDeviceCreationArgs; | 
|  | struct DisplayInfo; | 
|  |  | 
|  | namespace compositionengine { | 
|  | class Display; | 
|  | class DisplaySurface; | 
|  | } // namespace compositionengine | 
|  |  | 
|  | class DisplayDevice : public LightRefBase<DisplayDevice> { | 
|  | public: | 
|  | constexpr static float sDefaultMinLumiance = 0.0; | 
|  | constexpr static float sDefaultMaxLumiance = 500.0; | 
|  |  | 
|  | enum { | 
|  | NO_LAYER_STACK = 0xFFFFFFFF, | 
|  | }; | 
|  |  | 
|  | explicit DisplayDevice(DisplayDeviceCreationArgs&& args); | 
|  | virtual ~DisplayDevice(); | 
|  |  | 
|  | std::shared_ptr<compositionengine::Display> getCompositionDisplay() const { | 
|  | return mCompositionDisplay; | 
|  | } | 
|  |  | 
|  | bool isVirtual() const { return mIsVirtual; } | 
|  | bool isPrimary() const { return mIsPrimary; } | 
|  |  | 
|  | // isSecure indicates whether this display can be trusted to display | 
|  | // secure surfaces. | 
|  | bool isSecure() const; | 
|  |  | 
|  | int         getWidth() const; | 
|  | int         getHeight() const; | 
|  | int         getInstallOrientation() const { return mDisplayInstallOrientation; } | 
|  |  | 
|  | void                    setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers); | 
|  | const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const; | 
|  | void                    setLayersNeedingFences(const Vector< sp<Layer> >& layers); | 
|  | const Vector< sp<Layer> >& getLayersNeedingFences() const; | 
|  |  | 
|  | void                    setLayerStack(uint32_t stack); | 
|  | void                    setDisplaySize(const int newWidth, const int newHeight); | 
|  | void                    setProjection(int orientation, const Rect& viewport, const Rect& frame); | 
|  |  | 
|  | int                     getOrientation() const { return mOrientation; } | 
|  | static uint32_t         getPrimaryDisplayOrientationTransform(); | 
|  | const ui::Transform& getTransform() const; | 
|  | const Rect& getViewport() const; | 
|  | const Rect& getFrame() const; | 
|  | const Rect& getScissor() const; | 
|  | bool needsFiltering() const; | 
|  | uint32_t getLayerStack() const; | 
|  |  | 
|  | const std::optional<DisplayId>& getId() const; | 
|  | const wp<IBinder>& getDisplayToken() const { return mDisplayToken; } | 
|  | int32_t getSequenceId() const { return mSequenceId; } | 
|  |  | 
|  | const Region& getUndefinedRegion() const; | 
|  |  | 
|  | int32_t getSupportedPerFrameMetadata() const; | 
|  |  | 
|  | bool hasWideColorGamut() const; | 
|  | // Whether h/w composer has native support for specific HDR type. | 
|  | bool hasHDR10PlusSupport() const; | 
|  | bool hasHDR10Support() const; | 
|  | bool hasHLGSupport() const; | 
|  | bool hasDolbyVisionSupport() const; | 
|  |  | 
|  | // The returned HdrCapabilities is the combination of HDR capabilities from | 
|  | // hardware composer and RenderEngine. When the DisplayDevice supports wide | 
|  | // color gamut, RenderEngine is able to simulate HDR support in Display P3 | 
|  | // color space for both PQ and HLG HDR contents. The minimum and maximum | 
|  | // luminance will be set to sDefaultMinLumiance and sDefaultMaxLumiance | 
|  | // respectively if hardware composer doesn't return meaningful values. | 
|  | const HdrCapabilities& getHdrCapabilities() const; | 
|  |  | 
|  | // Return true if intent is supported by the display. | 
|  | bool hasRenderIntent(ui::RenderIntent intent) const; | 
|  |  | 
|  | const Rect& getBounds() const; | 
|  | const Rect& bounds() const { return getBounds(); } | 
|  |  | 
|  | void setDisplayName(const std::string& displayName); | 
|  | const std::string& getDisplayName() const { return mDisplayName; } | 
|  |  | 
|  | /* ------------------------------------------------------------------------ | 
|  | * Display power mode management. | 
|  | */ | 
|  | int getPowerMode() const; | 
|  | void setPowerMode(int mode); | 
|  | bool isPoweredOn() const; | 
|  |  | 
|  | ui::Dataspace getCompositionDataSpace() const; | 
|  |  | 
|  | /* ------------------------------------------------------------------------ | 
|  | * Display active config management. | 
|  | */ | 
|  | int getActiveConfig() const; | 
|  | void setActiveConfig(int mode); | 
|  |  | 
|  | // release HWC resources (if any) for removable displays | 
|  | void disconnect(); | 
|  |  | 
|  | /* ------------------------------------------------------------------------ | 
|  | * Debugging | 
|  | */ | 
|  | uint32_t getPageFlipCount() const; | 
|  | std::string getDebugName() const; | 
|  | void dump(std::string& result) const; | 
|  |  | 
|  | private: | 
|  | /* | 
|  | *  Constants, set during initialization | 
|  | */ | 
|  | const sp<SurfaceFlinger> mFlinger; | 
|  | const wp<IBinder> mDisplayToken; | 
|  | const int32_t mSequenceId; | 
|  |  | 
|  | const int mDisplayInstallOrientation; | 
|  | const std::shared_ptr<compositionengine::Display> mCompositionDisplay; | 
|  |  | 
|  | std::string mDisplayName; | 
|  | const bool mIsVirtual; | 
|  |  | 
|  | /* | 
|  | * Can only accessed from the main thread, these members | 
|  | * don't need synchronization. | 
|  | */ | 
|  |  | 
|  | // list of visible layers on that display | 
|  | Vector< sp<Layer> > mVisibleLayersSortedByZ; | 
|  | // list of layers needing fences | 
|  | Vector< sp<Layer> > mLayersNeedingFences; | 
|  |  | 
|  | /* | 
|  | * Transaction state | 
|  | */ | 
|  | static uint32_t displayStateOrientationToTransformOrientation(int orientation); | 
|  | static status_t orientationToTransfrom(int orientation, | 
|  | int w, int h, ui::Transform* tr); | 
|  |  | 
|  | int mOrientation; | 
|  | static uint32_t sPrimaryDisplayOrientation; | 
|  |  | 
|  | // Current power mode | 
|  | int mPowerMode; | 
|  | // Current active config | 
|  | int mActiveConfig; | 
|  |  | 
|  | // TODO(b/74619554): Remove special cases for primary display. | 
|  | const bool mIsPrimary; | 
|  | }; | 
|  |  | 
|  | struct DisplayDeviceState { | 
|  | bool isVirtual() const { return !displayId.has_value(); } | 
|  |  | 
|  | int32_t sequenceId = sNextSequenceId++; | 
|  | std::optional<DisplayId> displayId; | 
|  | sp<IGraphicBufferProducer> surface; | 
|  | uint32_t layerStack = DisplayDevice::NO_LAYER_STACK; | 
|  | Rect viewport; | 
|  | Rect frame; | 
|  | uint8_t orientation = 0; | 
|  | uint32_t width = 0; | 
|  | uint32_t height = 0; | 
|  | std::string displayName; | 
|  | bool isSecure = false; | 
|  |  | 
|  | private: | 
|  | static std::atomic<int32_t> sNextSequenceId; | 
|  | }; | 
|  |  | 
|  | struct DisplayDeviceCreationArgs { | 
|  | // We use a constructor to ensure some of the values are set, without | 
|  | // assuming a default value. | 
|  | DisplayDeviceCreationArgs(const sp<SurfaceFlinger>& flinger, const wp<IBinder>& displayToken, | 
|  | const std::optional<DisplayId>& displayId); | 
|  |  | 
|  | const sp<SurfaceFlinger> flinger; | 
|  | const wp<IBinder> displayToken; | 
|  | const std::optional<DisplayId> displayId; | 
|  |  | 
|  | int32_t sequenceId{0}; | 
|  | bool isVirtual{false}; | 
|  | bool isSecure{false}; | 
|  | sp<ANativeWindow> nativeWindow; | 
|  | sp<compositionengine::DisplaySurface> displaySurface; | 
|  | int displayInstallOrientation{DisplayState::eOrientationDefault}; | 
|  | bool hasWideColorGamut{false}; | 
|  | HdrCapabilities hdrCapabilities; | 
|  | int32_t supportedPerFrameMetadata{0}; | 
|  | std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hwcColorModes; | 
|  | int initialPowerMode{HWC_POWER_MODE_NORMAL}; | 
|  | bool isPrimary{false}; | 
|  | }; | 
|  |  | 
|  | class DisplayRenderArea : public RenderArea { | 
|  | public: | 
|  | DisplayRenderArea(const sp<const DisplayDevice> device, | 
|  | ui::Transform::orientation_flags rotation = ui::Transform::ROT_0) | 
|  | : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(), | 
|  | device->getCompositionDataSpace(), rotation) {} | 
|  | DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth, | 
|  | uint32_t reqHeight, ui::Dataspace reqDataSpace, | 
|  | ui::Transform::orientation_flags rotation, bool allowSecureLayers = true) | 
|  | : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, reqDataSpace, | 
|  | getDisplayRotation(rotation, device->getInstallOrientation())), | 
|  | mDevice(device), | 
|  | mSourceCrop(sourceCrop), | 
|  | mAllowSecureLayers(allowSecureLayers) {} | 
|  |  | 
|  | const ui::Transform& getTransform() const override { return mDevice->getTransform(); } | 
|  | Rect getBounds() const override { return mDevice->getBounds(); } | 
|  | int getHeight() const override { return mDevice->getHeight(); } | 
|  | int getWidth() const override { return mDevice->getWidth(); } | 
|  | bool isSecure() const override { return mAllowSecureLayers && mDevice->isSecure(); } | 
|  | const sp<const DisplayDevice> getDisplayDevice() const override { return mDevice; } | 
|  |  | 
|  | bool needsFiltering() const override { | 
|  | // check if the projection from the logical display to the physical | 
|  | // display needs filtering | 
|  | if (mDevice->needsFiltering()) { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // check if the projection from the logical render area (i.e., the | 
|  | // physical display) to the physical render area requires filtering | 
|  | const Rect sourceCrop = getSourceCrop(); | 
|  | int width = sourceCrop.width(); | 
|  | int height = sourceCrop.height(); | 
|  | if (getRotationFlags() & ui::Transform::ROT_90) { | 
|  | std::swap(width, height); | 
|  | } | 
|  | return width != getReqWidth() || height != getReqHeight(); | 
|  | } | 
|  |  | 
|  | Rect getSourceCrop() const override { | 
|  | // use the projected display viewport by default. | 
|  | if (mSourceCrop.isEmpty()) { | 
|  | return mDevice->getScissor(); | 
|  | } | 
|  |  | 
|  | // Recompute the device transformation for the source crop. | 
|  | ui::Transform rotation; | 
|  | ui::Transform translatePhysical; | 
|  | ui::Transform translateLogical; | 
|  | ui::Transform scale; | 
|  | const Rect& viewport = mDevice->getViewport(); | 
|  | const Rect& scissor = mDevice->getScissor(); | 
|  | const Rect& frame = mDevice->getFrame(); | 
|  |  | 
|  | const int orientation = mDevice->getInstallOrientation(); | 
|  | // Install orientation is transparent to the callers.  Apply it now. | 
|  | uint32_t flags = 0x00; | 
|  | switch (orientation) { | 
|  | case DisplayState::eOrientation90: | 
|  | flags = ui::Transform::ROT_90; | 
|  | break; | 
|  | case DisplayState::eOrientation180: | 
|  | flags = ui::Transform::ROT_180; | 
|  | break; | 
|  | case DisplayState::eOrientation270: | 
|  | flags = ui::Transform::ROT_270; | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | rotation.set(flags, getWidth(), getHeight()); | 
|  | translateLogical.set(-viewport.left, -viewport.top); | 
|  | translatePhysical.set(scissor.left, scissor.top); | 
|  | scale.set(frame.getWidth() / float(viewport.getWidth()), 0, 0, | 
|  | frame.getHeight() / float(viewport.getHeight())); | 
|  | const ui::Transform finalTransform = | 
|  | rotation * translatePhysical * scale * translateLogical; | 
|  | return finalTransform.transform(mSourceCrop); | 
|  | } | 
|  |  | 
|  | private: | 
|  | // Install orientation is transparent to the callers.  We need to cancel | 
|  | // it out by modifying rotation flags. | 
|  | static ui::Transform::orientation_flags getDisplayRotation( | 
|  | ui::Transform::orientation_flags rotation, int orientation) { | 
|  | if (orientation == DisplayState::eOrientationDefault) { | 
|  | return rotation; | 
|  | } | 
|  |  | 
|  | // convert hw orientation into flag presentation | 
|  | // here inverse transform needed | 
|  | uint8_t hw_rot_90 = 0x00; | 
|  | uint8_t hw_flip_hv = 0x00; | 
|  | switch (orientation) { | 
|  | case DisplayState::eOrientation90: | 
|  | hw_rot_90 = ui::Transform::ROT_90; | 
|  | hw_flip_hv = ui::Transform::ROT_180; | 
|  | break; | 
|  | case DisplayState::eOrientation180: | 
|  | hw_flip_hv = ui::Transform::ROT_180; | 
|  | break; | 
|  | case DisplayState::eOrientation270: | 
|  | hw_rot_90 = ui::Transform::ROT_90; | 
|  | break; | 
|  | } | 
|  |  | 
|  | // transform flags operation | 
|  | // 1) flip H V if both have ROT_90 flag | 
|  | // 2) XOR these flags | 
|  | uint8_t rotation_rot_90 = rotation & ui::Transform::ROT_90; | 
|  | uint8_t rotation_flip_hv = rotation & ui::Transform::ROT_180; | 
|  | if (rotation_rot_90 & hw_rot_90) { | 
|  | rotation_flip_hv = (~rotation_flip_hv) & ui::Transform::ROT_180; | 
|  | } | 
|  |  | 
|  | return static_cast<ui::Transform::orientation_flags>( | 
|  | (rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv)); | 
|  | } | 
|  |  | 
|  | const sp<const DisplayDevice> mDevice; | 
|  | const Rect mSourceCrop; | 
|  | const bool mAllowSecureLayers; | 
|  | }; | 
|  |  | 
|  | }; // namespace android | 
|  |  | 
|  | #endif // ANDROID_DISPLAY_DEVICE_H |