diff options
Diffstat (limited to 'services/surfaceflinger/Layer.cpp')
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 727 |
1 files changed, 358 insertions, 369 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index f94917cf1c..38662bdaff 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -36,6 +36,8 @@ #include <cutils/compiler.h> #include <cutils/native_handle.h> #include <cutils/properties.h> +#include <ftl/enum.h> +#include <ftl/fake_guard.h> #include <gui/BufferItem.h> #include <gui/LayerDebugInfo.h> #include <gui/Surface.h> @@ -45,6 +47,8 @@ #include <stdint.h> #include <stdlib.h> #include <sys/types.h> +#include <system/graphics-base-v1.0.h> +#include <ui/DataspaceUtils.h> #include <ui/DebugUtils.h> #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> @@ -79,35 +83,38 @@ namespace { constexpr int kDumpTableRowLength = 159; } // namespace +using namespace ftl::flag_operators; + using base::StringAppendF; -using namespace android::flag_operators; -using PresentState = frametimeline::SurfaceFrame::PresentState; using gui::WindowInfo; +using PresentState = frametimeline::SurfaceFrame::PresentState; + std::atomic<int32_t> Layer::sSequence{1}; Layer::Layer(const LayerCreationArgs& args) - : mFlinger(args.flinger), - mName(args.name), + : sequence(args.sequence.value_or(sSequence++)), + mFlinger(args.flinger), + mName(base::StringPrintf("%s#%d", args.name.c_str(), sequence)), mClientRef(args.client), - mWindowType( - static_cast<WindowInfo::Type>(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))) { + mWindowType(static_cast<WindowInfo::Type>(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))), + mLayerCreationFlags(args.flags) { uint32_t layerFlags = 0; if (args.flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden; if (args.flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque; if (args.flags & ISurfaceComposerClient::eSecure) layerFlags |= layer_state_t::eLayerSecure; if (args.flags & ISurfaceComposerClient::eSkipScreenshot) layerFlags |= layer_state_t::eLayerSkipScreenshot; - - mDrawingState.active_legacy.w = args.w; - mDrawingState.active_legacy.h = args.h; + if (args.sequence) { + sSequence = *args.sequence + 1; + } mDrawingState.flags = layerFlags; mDrawingState.active_legacy.transform.set(0, 0); mDrawingState.crop.makeInvalid(); mDrawingState.requestedCrop = mDrawingState.crop; mDrawingState.z = 0; mDrawingState.color.a = 1.0f; - mDrawingState.layerStack = 0; + mDrawingState.layerStack = ui::DEFAULT_LAYER_STACK; mDrawingState.sequence = 0; mDrawingState.requested_legacy = mDrawingState.active_legacy; mDrawingState.width = UINT32_MAX; @@ -136,6 +143,7 @@ Layer::Layer(const LayerCreationArgs& args) mDrawingState.destinationFrame.makeInvalid(); mDrawingState.isTrustedOverlay = false; mDrawingState.dropInputMode = gui::DropInputMode::NONE; + mDrawingState.dimmingEnabled = true; if (args.flags & ISurfaceComposerClient::eNoColorFill) { // Set an invalid color so there is no color fill. @@ -143,10 +151,8 @@ Layer::Layer(const LayerCreationArgs& args) mDrawingState.color.g = -1.0_hf; mDrawingState.color.b = -1.0_hf; } - CompositorTiming compositorTiming; args.flinger->getCompositorTiming(&compositorTiming); - mFrameEventHistory.initializeCompositorTiming(compositorTiming); mFrameTracker.setDisplayRefreshPeriod(compositorTiming.interval); mCallingPid = args.callingPid; @@ -185,12 +191,10 @@ Layer::~Layer() { } LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, std::string name, - uint32_t w, uint32_t h, uint32_t flags, LayerMetadata metadata) + uint32_t flags, LayerMetadata metadata) : flinger(flinger), client(std::move(client)), name(std::move(name)), - w(w), - h(h), flags(flags), metadata(std::move(metadata)) { IPCThreadState* ipc = IPCThreadState::self(); @@ -207,7 +211,7 @@ LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, * Layer. So, the implementation is done in BufferLayer. When called on a * EffectLayer object, it's essentially a NOP. */ -void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {} +void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult>) {} void Layer::removeRelativeZ(const std::vector<Layer*>& layersInTree) { if (mDrawingState.zOrderRelativeOf == nullptr) { @@ -336,6 +340,12 @@ void Layer::computeBounds(FloatRect parentBounds, ui::Transform parentTransform, // Calculate effective layer transform mEffectiveTransform = parentTransform * getActiveTransform(s); + if (CC_UNLIKELY(!isTransformValid())) { + ALOGW("Stop computing bounds for %s because it has invalid transformation.", + getDebugName()); + return; + } + // Transform parent bounds to layer space parentBounds = getActiveTransform(s).inverse().transform(parentBounds); @@ -393,7 +403,6 @@ void Layer::setupRoundedCornersCropCoordinates(Rect win, void Layer::prepareBasicGeometryCompositionState() { const auto& drawingState{getDrawingState()}; - const uint32_t layerStack = getLayerStack(); const auto alpha = static_cast<float>(getAlpha()); const bool opaque = isOpaque(drawingState); const bool usesRoundedCorners = getRoundedCornerState().radius != 0.f; @@ -405,9 +414,7 @@ void Layer::prepareBasicGeometryCompositionState() { } auto* compositionState = editCompositionState(); - compositionState->layerStackId = - (layerStack != ~0u) ? std::make_optional(layerStack) : std::nullopt; - compositionState->internalOnly = getPrimaryDisplayOnly(); + compositionState->outputFilter = getOutputFilter(); compositionState->isVisible = isVisible(); compositionState->isOpaque = opaque && !usesRoundedCorners && alpha == 1.f; compositionState->shadowRadius = mEffectiveShadowRadius; @@ -422,25 +429,13 @@ void Layer::prepareBasicGeometryCompositionState() { compositionState->blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode); compositionState->alpha = alpha; + compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius; + compositionState->blurRegions = drawingState.blurRegions; compositionState->stretchEffect = getStretchEffect(); } void Layer::prepareGeometryCompositionState() { const auto& drawingState{getDrawingState()}; - - int type = drawingState.metadata.getInt32(METADATA_WINDOW_TYPE, 0); - int appId = drawingState.metadata.getInt32(METADATA_OWNER_UID, 0); - sp<Layer> parent = mDrawingParent.promote(); - if (parent.get()) { - auto& parentState = parent->getDrawingState(); - const int parentType = parentState.metadata.getInt32(METADATA_WINDOW_TYPE, 0); - const int parentAppId = parentState.metadata.getInt32(METADATA_OWNER_UID, 0); - if (parentType > 0 && parentAppId > 0) { - type = parentType; - appId = parentAppId; - } - } - auto* compositionState = editCompositionState(); compositionState->geomBufferSize = getBufferSize(drawingState); @@ -484,6 +479,7 @@ void Layer::preparePerFrameCompositionState() { compositionState->colorTransformIsIdentity = !hasColorTransform(); compositionState->surfaceDamage = surfaceDamageRegion; compositionState->hasProtectedContent = isProtected(); + compositionState->dimmingEnabled = isDimmingEnabled(); const bool usesRoundedCorners = getRoundedCornerState().radius != 0.f; @@ -500,6 +496,11 @@ void Layer::preparePerFrameCompositionState() { // If there are no visible region changes, we still need to update blur parameters. compositionState->blurRegions = drawingState.blurRegions; compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius; + + // Layer framerate is used in caching decisions. + // Retrieve it from the scheduler which maintains an instance of LayerHistory, and store it in + // LayerFECompositionState where it would be visible to Flattener. + compositionState->fps = mFlinger->getLayerFramerate(systemTime(), getSequence()); } void Layer::prepareCursorCompositionState() { @@ -596,6 +597,20 @@ std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCom layerSettings.alpha = alpha; layerSettings.sourceDataspace = getDataSpace(); + + // Override the dataspace transfer from 170M to sRGB if the device configuration requests this. + // We do this here instead of in buffer info so that dumpsys can still report layers that are + // using the 170M transfer. + if (mFlinger->mTreat170mAsSrgb && + (layerSettings.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) == + HAL_DATASPACE_TRANSFER_SMPTE_170M) { + layerSettings.sourceDataspace = static_cast<ui::Dataspace>( + (layerSettings.sourceDataspace & HAL_DATASPACE_STANDARD_MASK) | + (layerSettings.sourceDataspace & HAL_DATASPACE_RANGE_MASK) | + HAL_DATASPACE_TRANSFER_SRGB); + } + + layerSettings.whitePointNits = targetSettings.whitePointNits; switch (targetSettings.blurSetting) { case LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled: layerSettings.backgroundBlurRadius = getBackgroundBlurRadius(); @@ -658,15 +673,16 @@ std::vector<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCompo return {*layerSettings}; } -Hwc2::IComposerClient::Composition Layer::getCompositionType(const DisplayDevice& display) const { +aidl::android::hardware::graphics::composer3::Composition Layer::getCompositionType( + const DisplayDevice& display) const { const auto outputLayer = findOutputLayerForDisplay(&display); if (outputLayer == nullptr) { - return Hwc2::IComposerClient::Composition::INVALID; + return aidl::android::hardware::graphics::composer3::Composition::INVALID; } if (outputLayer->getState().hwc) { return (*outputLayer->getState().hwc).hwcCompositionType; } else { - return Hwc2::IComposerClient::Composition::CLIENT; + return aidl::android::hardware::graphics::composer3::Composition::CLIENT; } } @@ -731,14 +747,14 @@ void Layer::commitTransaction(State&) { mDrawingState.bufferlessSurfaceFramesTX.clear(); } -uint32_t Layer::getTransactionFlags(uint32_t flags) { - auto ret = mTransactionFlags & flags; - mTransactionFlags &= ~flags; - return ret; +uint32_t Layer::clearTransactionFlags(uint32_t mask) { + const auto flags = mTransactionFlags & mask; + mTransactionFlags &= ~mask; + return flags; } -uint32_t Layer::setTransactionFlags(uint32_t flags) { - return mTransactionFlags |= flags; +void Layer::setTransactionFlags(uint32_t mask) { + mTransactionFlags |= mask; } bool Layer::setPosition(float x, float y) { @@ -832,6 +848,14 @@ bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relati return false; } + if (CC_UNLIKELY(relative->usingRelativeZ(LayerVector::StateSet::Drawing)) && + (relative->mDrawingState.zOrderRelativeOf == this)) { + ALOGE("Detected relative layer loop between %s and %s", + mName.c_str(), relative->mName.c_str()); + ALOGE("Ignoring new call to set relative layer"); + return false; + } + mFlinger->mSomeChildrenChanged = true; mDrawingState.sequence++; @@ -903,7 +927,7 @@ bool Layer::setBackgroundColor(const half3& color, float alpha, ui::Dataspace da uint32_t flags = ISurfaceComposerClient::eFXSurfaceEffect; std::string name = mName + "BackgroundColorLayer"; mDrawingState.bgColorLayer = mFlinger->getFactory().createEffectLayer( - LayerCreationArgs(mFlinger.get(), nullptr, std::move(name), 0, 0, flags, + LayerCreationArgs(mFlinger.get(), nullptr, std::move(name), flags, LayerMetadata())); // add to child list @@ -950,17 +974,10 @@ bool Layer::setBackgroundBlurRadius(int backgroundBlurRadius) { setTransactionFlags(eTransactionNeeded); return true; } - -bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix, - bool allowNonRectPreservingTransforms) { +bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { ui::Transform t; t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); - if (!allowNonRectPreservingTransforms && !t.preserveRects()) { - ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER nor " - "ROTATE_SURFACE_FLINGER ignored"); - return false; - } mDrawingState.sequence++; mDrawingState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mDrawingState.modified = true; @@ -1016,7 +1033,7 @@ bool Layer::setMetadata(const LayerMetadata& data) { return true; } -bool Layer::setLayerStack(uint32_t layerStack) { +bool Layer::setLayerStack(ui::LayerStack layerStack) { if (mDrawingState.layerStack == layerStack) return false; mDrawingState.sequence++; mDrawingState.layerStack = layerStack; @@ -1036,6 +1053,16 @@ bool Layer::setColorSpaceAgnostic(const bool agnostic) { return true; } +bool Layer::setDimmingEnabled(const bool dimmingEnabled) { + if (mDrawingState.dimmingEnabled == dimmingEnabled) return false; + + mDrawingState.sequence++; + mDrawingState.dimmingEnabled = dimmingEnabled; + mDrawingState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + bool Layer::setFrameRateSelectionPriority(int32_t priority) { if (mDrawingState.frameRateSelectionPriority == priority) return false; mDrawingState.frameRateSelectionPriority = priority; @@ -1063,12 +1090,11 @@ bool Layer::isLayerFocusedBasedOnPriority(int32_t priority) { return priority == PRIORITY_FOCUSED_WITH_MODE || priority == PRIORITY_FOCUSED_WITHOUT_MODE; }; -uint32_t Layer::getLayerStack() const { - auto p = mDrawingParent.promote(); - if (p == nullptr) { - return getDrawingState().layerStack; +ui::LayerStack Layer::getLayerStack() const { + if (const auto parent = mDrawingParent.promote()) { + return parent->getLayerStack(); } - return p->getLayerStack(); + return getDrawingState().layerStack; } bool Layer::setShadowRadius(float shadowRadius) { @@ -1149,7 +1175,7 @@ bool Layer::propagateFrameRateForLayerTree(FrameRate parentFrameRate, bool* tran if (!frameRate.rate.isValid() && frameRate.type != FrameRateCompatibility::NoVote && childrenHaveFrameRate) { *transactionNeeded |= - setFrameRateForLayerTree(FrameRate(Fps(0.0f), FrameRateCompatibility::NoVote)); + setFrameRateForLayerTree(FrameRate(Fps(), FrameRateCompatibility::NoVote)); } // We return whether this layer ot its children has a vote. We ignore ExactOrMultiple votes for @@ -1183,9 +1209,6 @@ void Layer::updateTreeHasFrameRateVote() { } bool Layer::setFrameRate(FrameRate frameRate) { - if (!mFlinger->useFrameRateApi) { - return false; - } if (mDrawingState.frameRate == frameRate) { return false; } @@ -1275,6 +1298,7 @@ std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransac getSequence(), mName, mTransactionName, /*isBuffer*/ false, getGameMode()); + surfaceFrame->setActualStartTime(info.startTimeNanos); // For Transactions, the post time is considered to be both queue and acquire fence time. surfaceFrame->setActualQueueTime(postTime); surfaceFrame->setAcquireFenceTime(postTime); @@ -1292,6 +1316,7 @@ std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer( mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid, getSequence(), mName, debugName, /*isBuffer*/ true, getGameMode()); + surfaceFrame->setActualStartTime(info.startTimeNanos); // For buffers, acquire fence time will set during latch. surfaceFrame->setActualQueueTime(queueTime); const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid()); @@ -1316,8 +1341,8 @@ bool Layer::setFrameRateForLayerTree(FrameRate frameRate) { mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); - mFlinger->mScheduler->recordLayerHistory(this, systemTime(), - LayerHistory::LayerUpdateType::SetFrameRate); + using LayerUpdateType = scheduler::LayerHistory::LayerUpdateType; + mFlinger->mScheduler->recordLayerHistory(this, systemTime(), LayerUpdateType::SetFrameRate); return true; } @@ -1340,6 +1365,10 @@ bool Layer::isHiddenByPolicy() const { } } } + if (CC_UNLIKELY(!isTransformValid())) { + ALOGW("Hide layer %s because it has invalid transformation.", getDebugName()); + return true; + } return s.flags & layer_state_t::eLayerHidden; } @@ -1382,7 +1411,7 @@ LayerDebugInfo Layer::getLayerDebugInfo(const DisplayDevice* display) const { info.mVisibleRegion = getVisibleRegion(display); info.mSurfaceDamageRegion = surfaceDamageRegion; - info.mLayerStack = getLayerStack(); + info.mLayerStack = getLayerStack().id; info.mX = ds.transform.tx(); info.mY = ds.transform.ty(); info.mZ = ds.z; @@ -1412,7 +1441,6 @@ LayerDebugInfo Layer::getLayerDebugInfo(const DisplayDevice* display) const { } } info.mNumQueuedFrames = getQueuedFrameCount(); - info.mRefreshPending = isBufferLatched(); info.mIsOpaque = isOpaque(ds); info.mContentDirty = contentDirty; info.mStretchEffect = getStretchEffect(); @@ -1434,19 +1462,6 @@ void Layer::miniDumpHeader(std::string& result) { result.append("\n"); } -std::string Layer::frameRateCompatibilityString(Layer::FrameRateCompatibility compatibility) { - switch (compatibility) { - case FrameRateCompatibility::Default: - return "Default"; - case FrameRateCompatibility::ExactOrMultiple: - return "ExactOrMultiple"; - case FrameRateCompatibility::NoVote: - return "NoVote"; - case FrameRateCompatibility::Exact: - return "Exact"; - } -} - void Layer::miniDump(std::string& result, const DisplayDevice& display) const { const auto outputLayer = findOutputLayerForDisplay(&display); if (!outputLayer) { @@ -1485,8 +1500,8 @@ void Layer::miniDump(std::string& result, const DisplayDevice& display) const { const auto frameRate = getFrameRateForLayerTree(); if (frameRate.rate.isValid() || frameRate.type != FrameRateCompatibility::Default) { StringAppendF(&result, "%s %15s %17s", to_string(frameRate.rate).c_str(), - frameRateCompatibilityString(frameRate.type).c_str(), - toString(frameRate.seamlessness).c_str()); + ftl::enum_string(frameRate.type).c_str(), + ftl::enum_string(frameRate.seamlessness).c_str()); } else { result.append(41, ' '); } @@ -1514,53 +1529,17 @@ void Layer::getFrameStats(FrameStats* outStats) const { mFrameTracker.getStats(outStats); } -void Layer::dumpFrameEvents(std::string& result) { - StringAppendF(&result, "- Layer %s (%s, %p)\n", getName().c_str(), getType(), this); - Mutex::Autolock lock(mFrameEventHistoryMutex); - mFrameEventHistory.checkFencesForCompletion(); - mFrameEventHistory.dump(result); -} - void Layer::dumpCallingUidPid(std::string& result) const { StringAppendF(&result, "Layer %s (%s) callingPid:%d callingUid:%d ownerUid:%d\n", getName().c_str(), getType(), mCallingPid, mCallingUid, mOwnerUid); } void Layer::onDisconnect() { - Mutex::Autolock lock(mFrameEventHistoryMutex); - mFrameEventHistory.onDisconnect(); const int32_t layerId = getSequence(); mFlinger->mTimeStats->onDestroy(layerId); mFlinger->mFrameTracer->onDestroy(layerId); } -void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, - FrameEventHistoryDelta* outDelta) { - if (newTimestamps) { - mFlinger->mTimeStats->setPostTime(getSequence(), newTimestamps->frameNumber, - getName().c_str(), mOwnerUid, newTimestamps->postedTime, - getGameMode()); - mFlinger->mTimeStats->setAcquireFence(getSequence(), newTimestamps->frameNumber, - newTimestamps->acquireFence); - } - - Mutex::Autolock lock(mFrameEventHistoryMutex); - if (newTimestamps) { - // If there are any unsignaled fences in the aquire timeline at this - // point, the previously queued frame hasn't been latched yet. Go ahead - // and try to get the signal time here so the syscall is taken out of - // the main thread's critical path. - mAcquireTimeline.updateSignalTimes(); - // Push the new fence after updating since it's likely still pending. - mAcquireTimeline.push(newTimestamps->acquireFence); - mFrameEventHistory.addQueue(*newTimestamps); - } - - if (outDelta) { - mFrameEventHistory.getAndResetDelta(outDelta); - } -} - size_t Layer::getChildrenCount() const { size_t count = 0; for (const sp<Layer>& child : mCurrentChildren) { @@ -1569,11 +1548,10 @@ size_t Layer::getChildrenCount() const { return count; } -void Layer::setGameModeForTree(int parentGameMode) { - int gameMode = parentGameMode; - auto& currentState = getDrawingState(); +void Layer::setGameModeForTree(GameMode gameMode) { + const auto& currentState = getDrawingState(); if (currentState.metadata.has(METADATA_GAME_MODE)) { - gameMode = currentState.metadata.getInt32(METADATA_GAME_MODE, 0); + gameMode = static_cast<GameMode>(currentState.metadata.getInt32(METADATA_GAME_MODE, 0)); } setGameMode(gameMode); for (const sp<Layer>& child : mCurrentChildren) { @@ -1599,7 +1577,7 @@ ssize_t Layer::removeChild(const sp<Layer>& layer) { const auto removeResult = mCurrentChildren.remove(layer); updateTreeHasFrameRateVote(); - layer->setGameModeForTree(0); + layer->setGameModeForTree(GameMode::Unsupported); layer->updateTreeHasFrameRateVote(); return removeResult; @@ -1889,6 +1867,11 @@ ui::Transform Layer::getTransform() const { return mEffectiveTransform; } +bool Layer::isTransformValid() const { + float transformDet = getTransform().det(); + return transformDet != 0 && !isinf(transformDet) && !isnan(transformDet); +} + half Layer::getAlpha() const { const auto& p = mDrawingParent.promote(); @@ -2006,6 +1989,18 @@ void Layer::prepareShadowClientComposition(LayerFE::LayerSettings& caster, } } +bool Layer::findInHierarchy(const sp<Layer>& l) { + if (l == this) { + return true; + } + for (auto& child : mDrawingChildren) { + if (child->findInHierarchy(l)) { + return true; + } + } + return false; +} + void Layer::commitChildList() { for (size_t i = 0; i < mCurrentChildren.size(); i++) { const auto& child = mCurrentChildren[i]; @@ -2013,6 +2008,17 @@ void Layer::commitChildList() { } mDrawingChildren = mCurrentChildren; mDrawingParent = mCurrentParent; + if (CC_UNLIKELY(usingRelativeZ(LayerVector::StateSet::Drawing))) { + auto zOrderRelativeOf = mDrawingState.zOrderRelativeOf.promote(); + if (zOrderRelativeOf == nullptr) return; + if (findInHierarchy(zOrderRelativeOf)) { + ALOGE("Detected Z ordering loop between %s and %s", mName.c_str(), + zOrderRelativeOf->mName.c_str()); + ALOGE("Severing rel Z loop, potentially dangerous"); + mDrawingState.isRelativeOf = false; + zOrderRelativeOf->removeZOrderRelative(this); + } + } } @@ -2024,67 +2030,59 @@ void Layer::setInputInfo(const WindowInfo& info) { setTransactionFlags(eTransactionNeeded); } -LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags, - const DisplayDevice* display) { +LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags) { LayerProto* layerProto = layersProto.add_layers(); - writeToProtoDrawingState(layerProto, traceFlags, display); + writeToProtoDrawingState(layerProto); writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags); - if (traceFlags & SurfaceTracing::TRACE_COMPOSITION) { + if (traceFlags & LayerTracing::TRACE_COMPOSITION) { + ftl::FakeGuard guard(mFlinger->mStateLock); // Called from the main thread. + // Only populate for the primary display. - if (display) { - const Hwc2::IComposerClient::Composition compositionType = getCompositionType(*display); + if (const auto display = mFlinger->getDefaultDisplayDeviceLocked()) { + const auto compositionType = getCompositionType(*display); layerProto->set_hwc_composition_type(static_cast<HwcCompositionType>(compositionType)); + LayerProtoHelper::writeToProto(getVisibleRegion(display.get()), + [&]() { return layerProto->mutable_visible_region(); }); } } for (const sp<Layer>& layer : mDrawingChildren) { - layer->writeToProto(layersProto, traceFlags, display); + layer->writeToProto(layersProto, traceFlags); } return layerProto; } -void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags, - const DisplayDevice* display) { +void Layer::writeToProtoDrawingState(LayerProto* layerInfo) { const ui::Transform transform = getTransform(); + auto buffer = getExternalTexture(); + if (buffer != nullptr) { + LayerProtoHelper::writeToProto(*buffer, + [&]() { return layerInfo->mutable_active_buffer(); }); + LayerProtoHelper::writeToProtoDeprecated(ui::Transform(getBufferTransform()), + layerInfo->mutable_buffer_transform()); + } + layerInfo->set_invalidate(contentDirty); + layerInfo->set_is_protected(isProtected()); + layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(getDataSpace()))); + layerInfo->set_queued_frames(getQueuedFrameCount()); + layerInfo->set_curr_frame(mCurrentFrameNumber); + layerInfo->set_effective_scaling_mode(getEffectiveScalingMode()); + + layerInfo->set_requested_corner_radius(getDrawingState().cornerRadius); + layerInfo->set_corner_radius(getRoundedCornerState().radius); + layerInfo->set_background_blur_radius(getBackgroundBlurRadius()); + layerInfo->set_is_trusted_overlay(isTrustedOverlay()); + LayerProtoHelper::writeToProtoDeprecated(transform, layerInfo->mutable_transform()); + LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(), + [&]() { return layerInfo->mutable_position(); }); + LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); }); + LayerProtoHelper::writeToProto(surfaceDamageRegion, + [&]() { return layerInfo->mutable_damage_region(); }); - if (traceFlags & SurfaceTracing::TRACE_CRITICAL) { - - auto buffer = getBuffer(); - if (buffer != nullptr) { - LayerProtoHelper::writeToProto(buffer, - [&]() { return layerInfo->mutable_active_buffer(); }); - LayerProtoHelper::writeToProtoDeprecated(ui::Transform(getBufferTransform()), - layerInfo->mutable_buffer_transform()); - } - layerInfo->set_invalidate(contentDirty); - layerInfo->set_is_protected(isProtected()); - layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(getDataSpace()))); - layerInfo->set_queued_frames(getQueuedFrameCount()); - layerInfo->set_refresh_pending(isBufferLatched()); - layerInfo->set_curr_frame(mCurrentFrameNumber); - layerInfo->set_effective_scaling_mode(getEffectiveScalingMode()); - - layerInfo->set_requested_corner_radius(getDrawingState().cornerRadius); - layerInfo->set_corner_radius(getRoundedCornerState().radius); - layerInfo->set_background_blur_radius(getBackgroundBlurRadius()); - layerInfo->set_is_trusted_overlay(isTrustedOverlay()); - LayerProtoHelper::writeToProtoDeprecated(transform, layerInfo->mutable_transform()); - LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(), - [&]() { return layerInfo->mutable_position(); }); - LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); }); - if (traceFlags & SurfaceTracing::TRACE_COMPOSITION) { - LayerProtoHelper::writeToProto(getVisibleRegion(display), - [&]() { return layerInfo->mutable_visible_region(); }); - } - LayerProtoHelper::writeToProto(surfaceDamageRegion, - [&]() { return layerInfo->mutable_damage_region(); }); - - if (hasColorTransform()) { - LayerProtoHelper::writeToProto(getColorTransform(), - layerInfo->mutable_color_transform()); - } + if (hasColorTransform()) { + LayerProtoHelper::writeToProto(getColorTransform(), layerInfo->mutable_color_transform()); } LayerProtoHelper::writeToProto(mSourceBounds, @@ -2104,73 +2102,69 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet ui::Transform requestedTransform = state.transform; - if (traceFlags & SurfaceTracing::TRACE_CRITICAL) { - layerInfo->set_id(sequence); - layerInfo->set_name(getName().c_str()); - layerInfo->set_type(getType()); + layerInfo->set_id(sequence); + layerInfo->set_name(getName().c_str()); + layerInfo->set_type(getType()); - for (const auto& child : children) { - layerInfo->add_children(child->sequence); - } + for (const auto& child : children) { + layerInfo->add_children(child->sequence); + } - for (const wp<Layer>& weakRelative : state.zOrderRelatives) { - sp<Layer> strongRelative = weakRelative.promote(); - if (strongRelative != nullptr) { - layerInfo->add_relatives(strongRelative->sequence); - } + for (const wp<Layer>& weakRelative : state.zOrderRelatives) { + sp<Layer> strongRelative = weakRelative.promote(); + if (strongRelative != nullptr) { + layerInfo->add_relatives(strongRelative->sequence); } + } - LayerProtoHelper::writeToProto(state.activeTransparentRegion_legacy, - [&]() { return layerInfo->mutable_transparent_region(); }); - - layerInfo->set_layer_stack(getLayerStack()); - layerInfo->set_z(state.z); + LayerProtoHelper::writeToProto(state.activeTransparentRegion_legacy, + [&]() { return layerInfo->mutable_transparent_region(); }); - LayerProtoHelper::writePositionToProto(requestedTransform.tx(), requestedTransform.ty(), - [&]() { - return layerInfo->mutable_requested_position(); - }); + layerInfo->set_layer_stack(getLayerStack().id); + layerInfo->set_z(state.z); - LayerProtoHelper::writeSizeToProto(state.width, state.height, - [&]() { return layerInfo->mutable_size(); }); + LayerProtoHelper::writePositionToProto(requestedTransform.tx(), requestedTransform.ty(), [&]() { + return layerInfo->mutable_requested_position(); + }); - LayerProtoHelper::writeToProto(state.crop, [&]() { return layerInfo->mutable_crop(); }); + LayerProtoHelper::writeSizeToProto(state.width, state.height, + [&]() { return layerInfo->mutable_size(); }); - layerInfo->set_is_opaque(isOpaque(state)); + LayerProtoHelper::writeToProto(state.crop, [&]() { return layerInfo->mutable_crop(); }); + layerInfo->set_is_opaque(isOpaque(state)); - layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat())); - LayerProtoHelper::writeToProto(getColor(), [&]() { return layerInfo->mutable_color(); }); - LayerProtoHelper::writeToProto(state.color, - [&]() { return layerInfo->mutable_requested_color(); }); - layerInfo->set_flags(state.flags); + layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat())); + LayerProtoHelper::writeToProto(getColor(), [&]() { return layerInfo->mutable_color(); }); + LayerProtoHelper::writeToProto(state.color, + [&]() { return layerInfo->mutable_requested_color(); }); + layerInfo->set_flags(state.flags); - LayerProtoHelper::writeToProtoDeprecated(requestedTransform, - layerInfo->mutable_requested_transform()); + LayerProtoHelper::writeToProtoDeprecated(requestedTransform, + layerInfo->mutable_requested_transform()); - auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote(); - if (parent != nullptr) { - layerInfo->set_parent(parent->sequence); - } else { - layerInfo->set_parent(-1); - } + auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote(); + if (parent != nullptr) { + layerInfo->set_parent(parent->sequence); + } else { + layerInfo->set_parent(-1); + } - auto zOrderRelativeOf = state.zOrderRelativeOf.promote(); - if (zOrderRelativeOf != nullptr) { - layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence); - } else { - layerInfo->set_z_order_relative_of(-1); - } + auto zOrderRelativeOf = state.zOrderRelativeOf.promote(); + if (zOrderRelativeOf != nullptr) { + layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence); + } else { + layerInfo->set_z_order_relative_of(-1); + } - layerInfo->set_is_relative_of(state.isRelativeOf); + layerInfo->set_is_relative_of(state.isRelativeOf); - layerInfo->set_owner_uid(mOwnerUid); - } + layerInfo->set_owner_uid(mOwnerUid); - if (traceFlags & SurfaceTracing::TRACE_INPUT) { + if ((traceFlags & LayerTracing::TRACE_INPUT) && needsInputInfo()) { WindowInfo info; if (useDrawing) { - info = fillInputInfo({nullptr}); + info = fillInputInfo(ui::Transform(), /* displayIsSecure */ true); } else { info = state.inputInfo; } @@ -2179,12 +2173,15 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet [&]() { return layerInfo->mutable_input_window_info(); }); } - if (traceFlags & SurfaceTracing::TRACE_EXTRA) { + if (traceFlags & LayerTracing::TRACE_EXTRA) { auto protoMap = layerInfo->mutable_metadata(); for (const auto& entry : state.metadata.mMap) { (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend()); } } + + LayerProtoHelper::writeToProto(state.destinationFrame, + [&]() { return layerInfo->mutable_destination_frame(); }); } bool Layer::isRemovedFromCurrentState() const { @@ -2199,101 +2196,101 @@ Rect Layer::getInputBounds() const { return getCroppedBufferSize(getDrawingState()); } -void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& toNonRotatedDisplay) { - // Transform layer size to screen space and inset it by surface insets. - // If this is a portal window, set the touchableRegion to the layerBounds. - Rect layerBounds = info.portalToDisplayId == ADISPLAY_ID_NONE - ? getInputBounds() - : info.touchableRegion.getBounds(); - if (!layerBounds.isValid()) { - layerBounds = getInputBounds(); - } - - if (!layerBounds.isValid()) { - // If the layer bounds is empty, set the frame to empty and clear the transform - info.frameLeft = 0; - info.frameTop = 0; - info.frameRight = 0; - info.frameBottom = 0; - info.transform.reset(); - info.touchableRegion = Region(); - info.flags = WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::NOT_FOCUSABLE; - return; - } - - ui::Transform layerToDisplay = getInputTransform(); - // Transform that takes window coordinates to non-rotated display coordinates - ui::Transform t = toNonRotatedDisplay * layerToDisplay; - int32_t xSurfaceInset = info.surfaceInset; - int32_t ySurfaceInset = info.surfaceInset; - // Bring screenBounds into non-rotated space - Rect screenBounds = toNonRotatedDisplay.transform(Rect{mScreenBounds}); - - const float xScale = t.getScaleX(); - const float yScale = t.getScaleY(); - if (xScale != 1.0f || yScale != 1.0f) { - xSurfaceInset = std::round(xSurfaceInset * xScale); - ySurfaceInset = std::round(ySurfaceInset * yScale); +// Applies the given transform to the region, while protecting against overflows caused by any +// offsets. If applying the offset in the transform to any of the Rects in the region would result +// in an overflow, they are not added to the output Region. +static Region transformTouchableRegionSafely(const ui::Transform& t, const Region& r, + const std::string& debugWindowName) { + // Round the translation using the same rounding strategy used by ui::Transform. + const auto tx = static_cast<int32_t>(t.tx() + 0.5); + const auto ty = static_cast<int32_t>(t.ty() + 0.5); + + ui::Transform transformWithoutOffset = t; + transformWithoutOffset.set(0.f, 0.f); + + const Region transformed = transformWithoutOffset.transform(r); + + // Apply the translation to each of the Rects in the region while discarding any that overflow. + Region ret; + for (const auto& rect : transformed) { + Rect newRect; + if (__builtin_add_overflow(rect.left, tx, &newRect.left) || + __builtin_add_overflow(rect.top, ty, &newRect.top) || + __builtin_add_overflow(rect.right, tx, &newRect.right) || + __builtin_add_overflow(rect.bottom, ty, &newRect.bottom)) { + ALOGE("Applying transform to touchable region of window '%s' resulted in an overflow.", + debugWindowName.c_str()); + continue; + } + ret.orSelf(newRect); } + return ret; +} - // Transform the layer bounds from layer coordinate space to display coordinate space. - Rect transformedLayerBounds = t.transform(layerBounds); - - // clamp inset to layer bounds - xSurfaceInset = (xSurfaceInset >= 0) - ? std::min(xSurfaceInset, transformedLayerBounds.getWidth() / 2) - : 0; - ySurfaceInset = (ySurfaceInset >= 0) - ? std::min(ySurfaceInset, transformedLayerBounds.getHeight() / 2) - : 0; - - // inset while protecting from overflow TODO(b/161235021): What is going wrong - // in the overflow scenario? - { - int32_t tmp; - if (!__builtin_add_overflow(transformedLayerBounds.left, xSurfaceInset, &tmp)) - transformedLayerBounds.left = tmp; - if (!__builtin_sub_overflow(transformedLayerBounds.right, xSurfaceInset, &tmp)) - transformedLayerBounds.right = tmp; - if (!__builtin_add_overflow(transformedLayerBounds.top, ySurfaceInset, &tmp)) - transformedLayerBounds.top = tmp; - if (!__builtin_sub_overflow(transformedLayerBounds.bottom, ySurfaceInset, &tmp)) - transformedLayerBounds.bottom = tmp; - } - - // Compute the correct transform to send to input. This will allow it to transform the - // input coordinates from display space into window space. Therefore, it needs to use the - // final layer frame to create the inverse transform. Since surface insets are added later, - // along with the overflow, the best way to ensure we get the correct transform is to use - // the final frame calculated. - // 1. Take the original transform set on the window and get the inverse transform. This is - // used to get the final bounds in display space (ignorning the transform). Apply the - // inverse transform on the layerBounds to get the untransformed frame (in layer space) - // 2. Take the top and left of the untransformed frame to get the real position on screen. - // Apply the layer transform on top/left so it includes any scale or rotation. These will - // be the new translation values for the transform. - // 3. Update the translation of the original transform to the new translation values. - // 4. Send the inverse transform to input so the coordinates can be transformed back into - // window space. - ui::Transform inverseTransform = t.inverse(); - Rect nonTransformedBounds = inverseTransform.transform(transformedLayerBounds); - vec2 translation = t.transform(nonTransformedBounds.left, nonTransformedBounds.top); - ui::Transform inputTransform(t); - inputTransform.set(translation.x, translation.y); - info.transform = inputTransform.inverse(); - - // We need to send the layer bounds cropped to the screenbounds since the layer can be cropped. - // The frame should be the area the user sees on screen since it's used for occlusion - // detection. - transformedLayerBounds.intersect(screenBounds, &transformedLayerBounds); - info.frameLeft = transformedLayerBounds.left; - info.frameTop = transformedLayerBounds.top; - info.frameRight = transformedLayerBounds.right; - info.frameBottom = transformedLayerBounds.bottom; - - // Position the touchable region relative to frame screen location and restrict it to frame - // bounds. - info.touchableRegion = inputTransform.transform(info.touchableRegion); +void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& screenToDisplay) { + Rect tmpBounds = getInputBounds(); + if (!tmpBounds.isValid()) { + info.touchableRegion.clear(); + // A layer could have invalid input bounds and still expect to receive touch input if it has + // replaceTouchableRegionWithCrop. For that case, the input transform needs to be calculated + // correctly to determine the coordinate space for input events. Use an empty rect so that + // the layer will receive input in its own layer space. + tmpBounds = Rect::EMPTY_RECT; + } + + // InputDispatcher works in the display device's coordinate space. Here, we calculate the + // frame and transform used for the layer, which determines the bounds and the coordinate space + // within which the layer will receive input. + // + // The coordinate space within which each of the bounds are specified is explicitly documented + // in the variable name. For example "inputBoundsInLayer" is specified in layer space. A + // Transform converts one coordinate space to another, which is apparent in its naming. For + // example, "layerToDisplay" transforms layer space to display space. + // + // Coordinate space definitions: + // - display: The display device's coordinate space. Correlates to pixels on the display. + // - screen: The post-rotation coordinate space for the display, a.k.a. logical display space. + // - layer: The coordinate space of this layer. + // - input: The coordinate space in which this layer will receive input events. This could be + // different than layer space if a surfaceInset is used, which changes the origin + // of the input space. + const FloatRect inputBoundsInLayer = tmpBounds.toFloatRect(); + + // Clamp surface inset to the input bounds. + const auto surfaceInset = static_cast<float>(info.surfaceInset); + const float xSurfaceInset = + std::max(0.f, std::min(surfaceInset, inputBoundsInLayer.getWidth() / 2.f)); + const float ySurfaceInset = + std::max(0.f, std::min(surfaceInset, inputBoundsInLayer.getHeight() / 2.f)); + + // Apply the insets to the input bounds. + const FloatRect insetBoundsInLayer(inputBoundsInLayer.left + xSurfaceInset, + inputBoundsInLayer.top + ySurfaceInset, + inputBoundsInLayer.right - xSurfaceInset, + inputBoundsInLayer.bottom - ySurfaceInset); + + // Crop the input bounds to ensure it is within the parent's bounds. + const FloatRect croppedInsetBoundsInLayer = mBounds.intersect(insetBoundsInLayer); + + const ui::Transform layerToScreen = getInputTransform(); + const ui::Transform layerToDisplay = screenToDisplay * layerToScreen; + + const Rect roundedFrameInDisplay{layerToDisplay.transform(croppedInsetBoundsInLayer)}; + info.frameLeft = roundedFrameInDisplay.left; + info.frameTop = roundedFrameInDisplay.top; + info.frameRight = roundedFrameInDisplay.right; + info.frameBottom = roundedFrameInDisplay.bottom; + + ui::Transform inputToLayer; + inputToLayer.set(insetBoundsInLayer.left, insetBoundsInLayer.top); + const ui::Transform inputToDisplay = layerToDisplay * inputToLayer; + + // InputDispatcher expects a display-to-input transform. + info.transform = inputToDisplay.inverse(); + + // The touchable region is specified in the input coordinate space. Change it to display space. + info.touchableRegion = + transformTouchableRegionSafely(inputToDisplay, info.touchableRegion, mName); } void Layer::fillTouchOcclusionMode(WindowInfo& info) { @@ -2322,14 +2319,14 @@ gui::DropInputMode Layer::getDropInputMode() const { } void Layer::handleDropInputMode(gui::WindowInfo& info) const { - if (mDrawingState.inputInfo.inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL)) { + if (mDrawingState.inputInfo.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) { return; } // Check if we need to drop input unconditionally gui::DropInputMode dropInputMode = getDropInputMode(); if (dropInputMode == gui::DropInputMode::ALL) { - info.inputFeatures |= WindowInfo::Feature::DROP_INPUT; + info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT; ALOGV("Dropping input for %s as requested by policy.", getDebugName()); return; } @@ -2342,7 +2339,7 @@ void Layer::handleDropInputMode(gui::WindowInfo& info) const { // Check if the parent has set an alpha on the layer sp<Layer> parent = mDrawingParent.promote(); if (parent && parent->getAlpha() != 1.0_hf) { - info.inputFeatures |= WindowInfo::Feature::DROP_INPUT; + info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT; ALOGV("Dropping input for %s as requested by policy because alpha=%f", getDebugName(), static_cast<float>(getAlpha())); } @@ -2350,7 +2347,7 @@ void Layer::handleDropInputMode(gui::WindowInfo& info) const { // Check if the parent has cropped the buffer Rect bufferSize = getCroppedBufferSize(getDrawingState()); if (!bufferSize.isValid()) { - info.inputFeatures |= WindowInfo::Feature::DROP_INPUT_IF_OBSCURED; + info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED; return; } @@ -2362,7 +2359,7 @@ void Layer::handleDropInputMode(gui::WindowInfo& info) const { bool croppedByParent = bufferInScreenSpace != Rect{mScreenBounds}; if (croppedByParent) { - info.inputFeatures |= WindowInfo::Feature::DROP_INPUT; + info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT; ALOGV("Dropping input for %s as requested by policy because buffer is cropped by parent", getDebugName()); } else { @@ -2370,51 +2367,24 @@ void Layer::handleDropInputMode(gui::WindowInfo& info) const { // input if the window is obscured. This check should be done in surfaceflinger but the // logic currently resides in inputflinger. So pass the if_obscured check to input to only // drop input events if the window is obscured. - info.inputFeatures |= WindowInfo::Feature::DROP_INPUT_IF_OBSCURED; + info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED; } } -WindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) { +WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure) { if (!hasInputInfo()) { mDrawingState.inputInfo.name = getName(); mDrawingState.inputInfo.ownerUid = mOwnerUid; mDrawingState.inputInfo.ownerPid = mOwnerPid; - mDrawingState.inputInfo.inputFeatures = WindowInfo::Feature::NO_INPUT_CHANNEL; - mDrawingState.inputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL; - mDrawingState.inputInfo.displayId = getLayerStack(); + mDrawingState.inputInfo.inputConfig |= WindowInfo::InputConfig::NO_INPUT_CHANNEL; + mDrawingState.inputInfo.displayId = getLayerStack().id; } WindowInfo info = mDrawingState.inputInfo; info.id = sequence; - info.displayId = getLayerStack(); - - // Transform that goes from "logical(rotated)" display to the non-rotated display. - ui::Transform toNonRotatedDisplay; - if (display) { - // The physical orientation is set when the orientation of the display panel is different - // than the default orientation of the device. We do not need to expose the physical - // orientation of the panel outside of SurfaceFlinger. - const ui::Rotation inversePhysicalOrientation = - ui::ROTATION_0 - display->getPhysicalOrientation(); - auto width = display->getWidth(); - auto height = display->getHeight(); - if (inversePhysicalOrientation == ui::ROTATION_90 || - inversePhysicalOrientation == ui::ROTATION_270) { - std::swap(width, height); - } - const auto rotationFlags = ui::Transform::toRotationFlags(inversePhysicalOrientation); - const ui::Transform undoPhysicalOrientation(rotationFlags, width, height); - toNonRotatedDisplay = undoPhysicalOrientation * display->getTransform(); - - // Send the inverse of the display orientation so that input can transform points back to - // the rotated display space. - const ui::Rotation inverseOrientation = ui::ROTATION_0 - display->getOrientation(); - info.displayOrientation = ui::Transform::toRotationFlags(inverseOrientation); + info.displayId = getLayerStack().id; - info.displayWidth = width; - info.displayHeight = height; - } - fillInputFrameInfo(info, toNonRotatedDisplay); + fillInputFrameInfo(info, displayTransform); // For compatibility reasons we let layers which can receive input // receive input before they have actually submitted a buffer. Because @@ -2424,35 +2394,40 @@ WindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) { // We are just using these layers for occlusion detection in // InputDispatcher, and obviously if they aren't visible they can't occlude // anything. - info.visible = hasInputInfo() ? canReceiveInput() : isVisible(); + const bool visible = hasInputInfo() ? canReceiveInput() : isVisible(); + info.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !visible); + info.alpha = getAlpha(); fillTouchOcclusionMode(info); handleDropInputMode(info); + // If the window will be blacked out on a display because the display does not have the secure + // flag and the layer has the secure flag set, then drop input. + if (!displayIsSecure && isSecure()) { + info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT; + } + auto cropLayer = mDrawingState.touchableRegionCrop.promote(); if (info.replaceTouchableRegionWithCrop) { - if (cropLayer == nullptr) { - info.touchableRegion = Region(toNonRotatedDisplay.transform(Rect{mScreenBounds})); - } else { - info.touchableRegion = - Region(toNonRotatedDisplay.transform(Rect{cropLayer->mScreenBounds})); - } + const Rect bounds(cropLayer ? cropLayer->mScreenBounds : mScreenBounds); + info.touchableRegion = Region(displayTransform.transform(bounds)); } else if (cropLayer != nullptr) { info.touchableRegion = info.touchableRegion.intersect( - toNonRotatedDisplay.transform(Rect{cropLayer->mScreenBounds})); + displayTransform.transform(Rect{cropLayer->mScreenBounds})); } // Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state // if it was set by WM for a known system overlay - info.trustedOverlay = info.trustedOverlay || isTrustedOverlay(); - + if (isTrustedOverlay()) { + info.inputConfig |= WindowInfo::InputConfig::TRUSTED_OVERLAY; + } // If the layer is a clone, we need to crop the input region to cloned root to prevent // touches from going outside the cloned area. if (isClone()) { - sp<Layer> clonedRoot = getClonedRoot(); - if (clonedRoot != nullptr) { - Rect rect = toNonRotatedDisplay.transform(Rect{clonedRoot->mScreenBounds}); + info.isClone = true; + if (const sp<Layer> clonedRoot = getClonedRoot()) { + const Rect rect = displayTransform.transform(Rect{clonedRoot->mScreenBounds}); info.touchableRegion = info.touchableRegion.intersect(rect); } } @@ -2471,7 +2446,8 @@ sp<Layer> Layer::getClonedRoot() { } bool Layer::hasInputInfo() const { - return mDrawingState.inputInfo.token != nullptr; + return mDrawingState.inputInfo.token != nullptr || + mDrawingState.inputInfo.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL); } bool Layer::canReceiveInput() const { @@ -2578,7 +2554,7 @@ void Layer::updateClonedInputInfo(const std::map<sp<Layer>, sp<Layer>>& clonedLa } // Cloned layers shouldn't handle watch outside since their z order is not determined by // WM or the client. - mDrawingState.inputInfo.flags &= ~WindowInfo::Flag::WATCH_OUTSIDE_TOUCH; + mDrawingState.inputInfo.setInputConfig(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH, false); } void Layer::updateClonedRelatives(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) { @@ -2629,6 +2605,8 @@ Layer::FrameRateCompatibility Layer::FrameRate::convertCompatibility(int8_t comp return FrameRateCompatibility::ExactOrMultiple; case ANATIVEWINDOW_FRAME_RATE_EXACT: return FrameRateCompatibility::Exact; + case ANATIVEWINDOW_FRAME_RATE_NO_VOTE: + return FrameRateCompatibility::NoVote; default: LOG_ALWAYS_FATAL("Invalid frame rate compatibility value %d", compatibility); return FrameRateCompatibility::Default; @@ -2647,14 +2625,14 @@ scheduler::Seamlessness Layer::FrameRate::convertChangeFrameRateStrategy(int8_t } } -bool Layer::getPrimaryDisplayOnly() const { +bool Layer::isInternalDisplayOverlay() const { const State& s(mDrawingState); if (s.flags & layer_state_t::eLayerSkipScreenshot) { return true; } sp<Layer> parent = mDrawingParent.promote(); - return parent == nullptr ? false : parent->getPrimaryDisplayOnly(); + return parent && parent->isInternalDisplayOverlay(); } void Layer::setClonedChild(const sp<Layer>& clonedChild) { @@ -2695,15 +2673,26 @@ void Layer::cloneDrawingState(const Layer* from) { mDrawingState.callbackHandles = {}; } +bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) { + if (handles.empty()) { + return false; + } + + for (const auto& handle : handles) { + mFlinger->getTransactionCallbackInvoker().registerUnpresentedCallbackHandle(handle); + } + + return true; +} + // --------------------------------------------------------------------------- std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) { - return stream << "{rate=" << rate.rate - << " type=" << Layer::frameRateCompatibilityString(rate.type) - << " seamlessness=" << toString(rate.seamlessness) << "}"; + return stream << "{rate=" << rate.rate << " type=" << ftl::enum_string(rate.type) + << " seamlessness=" << ftl::enum_string(rate.seamlessness) << '}'; } -}; // namespace android +} // namespace android #if defined(__gl_h_) #error "don't include gl/gl.h in this file" |