diff options
Diffstat (limited to 'services/surfaceflinger/DisplayDevice.cpp')
-rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 264 |
1 files changed, 148 insertions, 116 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 730f29744a..ca4b6abc03 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -29,6 +29,7 @@ #include <compositionengine/DisplayColorProfileCreationArgs.h> #include <compositionengine/DisplayCreationArgs.h> #include <compositionengine/DisplaySurface.h> +#include <compositionengine/ProjectionSpace.h> #include <compositionengine/RenderSurface.h> #include <compositionengine/RenderSurfaceCreationArgs.h> #include <compositionengine/impl/OutputCompositionState.h> @@ -50,25 +51,33 @@ using android::base::StringAppendF; ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::Transform::ROT_0; DisplayDeviceCreationArgs::DisplayDeviceCreationArgs( - const sp<SurfaceFlinger>& flinger, const wp<IBinder>& displayToken, + const sp<SurfaceFlinger>& flinger, HWComposer& hwComposer, const wp<IBinder>& displayToken, std::shared_ptr<compositionengine::Display> compositionDisplay) - : flinger(flinger), displayToken(displayToken), compositionDisplay(compositionDisplay) {} + : flinger(flinger), + hwComposer(hwComposer), + displayToken(displayToken), + compositionDisplay(compositionDisplay) {} DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) : mFlinger(args.flinger), + mHwComposer(args.hwComposer), mDisplayToken(args.displayToken), mSequenceId(args.sequenceId), mConnectionType(args.connectionType), mCompositionDisplay{args.compositionDisplay}, mPhysicalOrientation(args.physicalOrientation), + mSupportedModes(std::move(args.supportedModes)), mIsPrimary(args.isPrimary) { mCompositionDisplay->editState().isSecure = args.isSecure; mCompositionDisplay->createRenderSurface( - compositionengine::RenderSurfaceCreationArgs{ANativeWindow_getWidth( - args.nativeWindow.get()), - ANativeWindow_getHeight( - args.nativeWindow.get()), - args.nativeWindow, args.displaySurface}); + compositionengine::RenderSurfaceCreationArgsBuilder() + .setDisplayWidth(ANativeWindow_getWidth(args.nativeWindow.get())) + .setDisplayHeight(ANativeWindow_getHeight(args.nativeWindow.get())) + .setNativeWindow(std::move(args.nativeWindow)) + .setDisplaySurface(std::move(args.displaySurface)) + .setMaxTextureCacheSize( + static_cast<size_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers)) + .build()); if (!mFlinger->mDisableClientCompositionCache && SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) { @@ -101,11 +110,11 @@ void DisplayDevice::disconnect() { } int DisplayDevice::getWidth() const { - return mCompositionDisplay->getState().bounds.getWidth(); + return mCompositionDisplay->getState().displaySpace.bounds.getWidth(); } int DisplayDevice::getHeight() const { - return mCompositionDisplay->getState().bounds.getHeight(); + return mCompositionDisplay->getState().displaySpace.bounds.getHeight(); } void DisplayDevice::setDisplayName(const std::string& displayName) { @@ -116,6 +125,10 @@ void DisplayDevice::setDisplayName(const std::string& displayName) { } } +void DisplayDevice::setDeviceProductInfo(std::optional<DeviceProductInfo> info) { + mDeviceProductInfo = std::move(info); +} + uint32_t DisplayDevice::getPageFlipCount() const { return mCompositionDisplay->getRenderSurface()->getPageFlipCount(); } @@ -126,6 +139,10 @@ void DisplayDevice::setPowerMode(hal::PowerMode mode) { getCompositionDisplay()->setCompositionEnabled(mPowerMode != hal::PowerMode::OFF); } +void DisplayDevice::enableLayerCaching(bool enable) { + getCompositionDisplay()->setLayerCachingEnabled(enable); +} + hal::PowerMode DisplayDevice::getPowerMode() const { return mPowerMode; } @@ -134,113 +151,108 @@ bool DisplayDevice::isPoweredOn() const { return mPowerMode != hal::PowerMode::OFF; } -void DisplayDevice::setActiveConfig(HwcConfigIndexType mode) { - mActiveConfig = mode; +void DisplayDevice::setActiveMode(DisplayModeId id) { + const auto mode = getMode(id); + LOG_FATAL_IF(!mode, "Cannot set active mode which is not supported."); + mActiveMode = mode; } -HwcConfigIndexType DisplayDevice::getActiveConfig() const { - return mActiveConfig; -} - -ui::Dataspace DisplayDevice::getCompositionDataSpace() const { - return mCompositionDisplay->getState().dataspace; +status_t DisplayDevice::initiateModeChange(DisplayModeId modeId, + const hal::VsyncPeriodChangeConstraints& constraints, + hal::VsyncPeriodChangeTimeline* outTimeline) const { + const auto mode = getMode(modeId); + if (!mode) { + ALOGE("Trying to initiate a mode change to invalid mode %s on display %s", + std::to_string(modeId.value()).c_str(), to_string(getId()).c_str()); + return BAD_VALUE; + } + return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), mode->getHwcId(), constraints, + outTimeline); } -void DisplayDevice::setLayerStack(ui::LayerStack stack) { - mCompositionDisplay->setLayerStackFilter(stack, isPrimary()); +const DisplayModePtr& DisplayDevice::getActiveMode() const { + return mActiveMode; } -void DisplayDevice::setDisplaySize(int width, int height) { - mCompositionDisplay->setBounds(ui::Size(width, height)); +const DisplayModes& DisplayDevice::getSupportedModes() const { + return mSupportedModes; } -void DisplayDevice::setProjection(ui::Rotation orientation, Rect viewport, Rect frame) { - mOrientation = orientation; - - const Rect& displayBounds = getCompositionDisplay()->getState().bounds; - const int displayWidth = displayBounds.width(); - const int displayHeight = displayBounds.height(); - - ui::Transform rotation; - if (const auto flags = ui::Transform::toRotationFlags(orientation); - flags != ui::Transform::ROT_INVALID) { - rotation.set(flags, displayWidth, displayHeight); +DisplayModePtr DisplayDevice::getMode(DisplayModeId modeId) const { + const auto it = std::find_if(mSupportedModes.begin(), mSupportedModes.end(), + [&](DisplayModePtr mode) { return mode->getId() == modeId; }); + if (it != mSupportedModes.end()) { + return *it; } + return nullptr; +} - if (!frame.isValid()) { - // the destination frame can be invalid if it has never been set, - // in that case we assume the whole display frame. - frame = Rect(displayWidth, displayHeight); +nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const { + const auto physicalId = getPhysicalId(); + if (!mHwComposer.isConnected(physicalId)) { + return 0; } - if (viewport.isEmpty()) { - // viewport can be invalid if it has never been set, in that case - // we assume the whole display size. - // it's also invalid to have an empty viewport, so we handle that - // case in the same way. - viewport = Rect(displayWidth, displayHeight); - if (rotation.getOrientation() & ui::Transform::ROT_90) { - // viewport is always specified in the logical orientation - // of the display (ie: post-rotation). - std::swap(viewport.right, viewport.bottom); - } + nsecs_t vsyncPeriod; + const auto status = mHwComposer.getDisplayVsyncPeriod(physicalId, &vsyncPeriod); + if (status == NO_ERROR) { + return vsyncPeriod; } - ui::Transform logicalTranslation, physicalTranslation, scale; - const float sourceWidth = viewport.width(); - const float sourceHeight = viewport.height(); - const float destWidth = frame.width(); - const float destHeight = frame.height(); - if (sourceWidth != destWidth || sourceHeight != destHeight) { - const float scaleX = destWidth / sourceWidth; - const float scaleY = destHeight / sourceHeight; - scale.set(scaleX, 0, 0, scaleY); - } + return getActiveMode()->getFps().getPeriodNsecs(); +} - const float sourceX = viewport.left; - const float sourceY = viewport.top; - const float destX = frame.left; - const float destY = frame.top; - logicalTranslation.set(-sourceX, -sourceY); - physicalTranslation.set(destX, destY); +nsecs_t DisplayDevice::getRefreshTimestamp() const { + const nsecs_t now = systemTime(CLOCK_MONOTONIC); + const auto vsyncPeriodNanos = getVsyncPeriodFromHWC(); + return now - ((now - mLastHwVsync) % vsyncPeriodNanos); +} - // need to take care of primary display rotation for globalTransform - // for case if the panel is not installed aligned with device orientation - if (isPrimary()) { - if (const auto flags = ui::Transform::toRotationFlags(orientation + mPhysicalOrientation); - flags != ui::Transform::ROT_INVALID) { - rotation.set(flags, displayWidth, displayHeight); - } - } +void DisplayDevice::onVsync(nsecs_t timestamp) { + mLastHwVsync = timestamp; +} - // The viewport and frame are both in the logical orientation. - // Apply the logical translation, scale to physical size, apply the - // physical translation and finally rotate to the physical orientation. - ui::Transform globalTransform = rotation * physicalTranslation * scale * logicalTranslation; +ui::Dataspace DisplayDevice::getCompositionDataSpace() const { + return mCompositionDisplay->getState().dataspace; +} - const uint8_t type = globalTransform.getType(); - const bool needsFiltering = - (!globalTransform.preserveRects() || (type >= ui::Transform::SCALE)); +void DisplayDevice::setLayerStack(ui::LayerStack stack) { + mCompositionDisplay->setLayerStackFilter(stack, isPrimary()); +} - const Rect& sourceClip = viewport; - Rect destinationClip = globalTransform.transform(viewport); - if (destinationClip.isEmpty()) { - destinationClip = displayBounds; - } - // Make sure the destination clip is contained in the display bounds - destinationClip.intersect(displayBounds, &destinationClip); +void DisplayDevice::setDisplaySize(int width, int height) { + LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays."); + mCompositionDisplay->setDisplaySize(ui::Size(width, height)); +} - uint32_t transformOrientation; +void DisplayDevice::setProjection(ui::Rotation orientation, Rect layerStackSpaceRect, + Rect orientedDisplaySpaceRect) { + mOrientation = orientation; if (isPrimary()) { sPrimaryDisplayRotationFlags = ui::Transform::toRotationFlags(orientation); - transformOrientation = ui::Transform::toRotationFlags(orientation + mPhysicalOrientation); - } else { - transformOrientation = ui::Transform::toRotationFlags(orientation); } - getCompositionDisplay()->setProjection(globalTransform, transformOrientation, frame, viewport, - sourceClip, destinationClip, needsFiltering); + if (!orientedDisplaySpaceRect.isValid()) { + // The destination frame can be invalid if it has never been set, + // in that case we assume the whole display size. + orientedDisplaySpaceRect = getCompositionDisplay()->getState().displaySpace.bounds; + } + + if (layerStackSpaceRect.isEmpty()) { + // The layerStackSpaceRect can be invalid if it has never been set, in that case + // we assume the whole framebuffer size. + layerStackSpaceRect = getCompositionDisplay()->getState().framebufferSpace.bounds; + if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) { + std::swap(layerStackSpaceRect.right, layerStackSpaceRect.bottom); + } + } + + // We need to take care of display rotation for globalTransform for case if the panel is not + // installed aligned with device orientation. + const auto transformOrientation = orientation + mPhysicalOrientation; + getCompositionDisplay()->setProjection(transformOrientation, layerStackSpaceRect, + orientedDisplaySpaceRect); } ui::Transform::RotationFlags DisplayDevice::getPrimaryDisplayRotationFlags() { @@ -248,27 +260,37 @@ ui::Transform::RotationFlags DisplayDevice::getPrimaryDisplayRotationFlags() { } std::string DisplayDevice::getDebugName() const { - std::string displayId; - if (const auto id = getId()) { - displayId = to_string(*id) + ", "; - } - const char* type = "virtual"; if (mConnectionType) { - type = *mConnectionType == DisplayConnectionType::Internal ? "internal" : "external"; + type = *mConnectionType == ui::DisplayConnectionType::Internal ? "internal" : "external"; } - return base::StringPrintf("DisplayDevice{%s%s%s, \"%s\"}", displayId.c_str(), type, + return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type, isPrimary() ? ", primary" : "", mDisplayName.c_str()); } void DisplayDevice::dump(std::string& result) const { StringAppendF(&result, "+ %s\n", getDebugName().c_str()); - - result.append(" "); - StringAppendF(&result, "powerMode=%s (%d), ", to_string(mPowerMode).c_str(), + StringAppendF(&result, " powerMode=%s (%d)\n", to_string(mPowerMode).c_str(), static_cast<int32_t>(mPowerMode)); - StringAppendF(&result, "activeConfig=%d, ", mActiveConfig.value()); + const auto activeMode = getActiveMode(); + StringAppendF(&result, " activeMode=%s\n", + activeMode ? to_string(*activeMode).c_str() : "none"); + + result.append(" supportedModes=\n"); + + for (const auto& mode : mSupportedModes) { + result.append(" "); + result.append(to_string(*mode)); + result.append("\n"); + } + StringAppendF(&result, " deviceProductInfo="); + if (mDeviceProductInfo) { + mDeviceProductInfo->dump(result); + } else { + result.append("{}"); + } + result.append("\n"); getCompositionDisplay()->dump(result); } @@ -276,9 +298,7 @@ bool DisplayDevice::hasRenderIntent(ui::RenderIntent intent) const { return mCompositionDisplay->getDisplayColorProfile()->hasRenderIntent(intent); } -// ---------------------------------------------------------------------------- - -const std::optional<DisplayId>& DisplayDevice::getId() const { +DisplayId DisplayDevice::getId() const { return mCompositionDisplay->getId(); } @@ -287,7 +307,7 @@ bool DisplayDevice::isSecure() const { } const Rect& DisplayDevice::getBounds() const { - return mCompositionDisplay->getState().bounds; + return mCompositionDisplay->getState().displaySpace.bounds; } const Region& DisplayDevice::getUndefinedRegion() const { @@ -302,20 +322,20 @@ ui::LayerStack DisplayDevice::getLayerStack() const { return mCompositionDisplay->getState().layerStackId; } -const ui::Transform& DisplayDevice::getTransform() const { - return mCompositionDisplay->getState().transform; +ui::Transform::RotationFlags DisplayDevice::getTransformHint() const { + return mCompositionDisplay->getTransformHint(); } -const Rect& DisplayDevice::getViewport() const { - return mCompositionDisplay->getState().viewport; +const ui::Transform& DisplayDevice::getTransform() const { + return mCompositionDisplay->getState().transform; } -const Rect& DisplayDevice::getFrame() const { - return mCompositionDisplay->getState().frame; +const Rect& DisplayDevice::getLayerStackSpaceRect() const { + return mCompositionDisplay->getState().layerStackSpace.content; } -const Rect& DisplayDevice::getSourceClip() const { - return mCompositionDisplay->getState().sourceClip; +const Rect& DisplayDevice::getOrientedDisplaySpaceRect() const { + return mCompositionDisplay->getState().orientedDisplaySpace.content; } bool DisplayDevice::hasWideColorGamut() const { @@ -342,8 +362,20 @@ int DisplayDevice::getSupportedPerFrameMetadata() const { return mCompositionDisplay->getDisplayColorProfile()->getSupportedPerFrameMetadata(); } -const HdrCapabilities& DisplayDevice::getHdrCapabilities() const { - return mCompositionDisplay->getDisplayColorProfile()->getHdrCapabilities(); +void DisplayDevice::overrideHdrTypes(const std::vector<ui::Hdr>& hdrTypes) { + mOverrideHdrTypes = hdrTypes; +} + +HdrCapabilities DisplayDevice::getHdrCapabilities() const { + const HdrCapabilities& capabilities = + mCompositionDisplay->getDisplayColorProfile()->getHdrCapabilities(); + std::vector<ui::Hdr> hdrTypes = capabilities.getSupportedHdrTypes(); + if (!mOverrideHdrTypes.empty()) { + hdrTypes = mOverrideHdrTypes; + } + return HdrCapabilities(hdrTypes, capabilities.getDesiredMaxLuminance(), + capabilities.getDesiredMaxAverageLuminance(), + capabilities.getDesiredMinLuminance()); } std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1); |