Layer: Use raw pointers for Current/Drawing parent
We should only be reading/writing this from the main thread
and likewise we only delete layers on the main thread and
so using raw pointers and managing the lifetime from the
Layer destructor will be safe. This significantly decreases
overhead in various code that traverses via parent (getAlpha,
isVisible, etc...).
Test: Existing tests pass. simpleperf
Bug: 186200583
Change-Id: I45745f7c865177ddfe9105d1440a9fa8f3470823
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 8de43e0..82c91e7 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -223,7 +223,7 @@
* of a camera where the buffer remains in native orientation,
* we want the pixels to always be upright.
*/
- sp<Layer> p = mDrawingParent.promote();
+ auto p = mDrawingParent;
if (p != nullptr) {
const auto parentTransform = p->getTransform();
tr = tr * inverseOrientation(parentTransform.getOrientation());
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 4eeaba1..ba193c3 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -989,7 +989,7 @@
* how to go from screen space back to window space.
*/
ui::Transform BufferStateLayer::getInputTransform() const {
- sp<Layer> parent = mDrawingParent.promote();
+ auto parent = mDrawingParent;
if (parent == nullptr) {
return ui::Transform();
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 4f4a897..5707c67 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -179,9 +179,23 @@
if (mDrawingState.sidebandStream != nullptr) {
mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
}
+
if (mHadClonedChild) {
mFlinger->mNumClones--;
}
+
+ for (auto const& child : mCurrentChildren) {
+ if (child->mCurrentParent == this) child->mCurrentParent = nullptr;
+ if (child->mDrawingParent == this) {
+ child->mDrawingParent = nullptr;
+ }
+ }
+ for (auto const& child : mDrawingChildren) {
+ if (child->mCurrentParent == this) child->mCurrentParent = nullptr;
+ if (child->mDrawingParent == this) {
+ child->mDrawingParent = nullptr;
+ }
+ }
}
LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, std::string name,
@@ -237,7 +251,7 @@
}
sp<Layer> Layer::getRootLayer() {
- sp<Layer> parent = getParent();
+ auto parent = getParent();
if (parent == nullptr) {
return this;
}
@@ -662,7 +676,7 @@
return true;
}
- const auto p = mDrawingParent.promote();
+ const auto p = mDrawingParent;
return (p != nullptr) ? p->isSecure() : false;
}
@@ -845,7 +859,7 @@
if (getDrawingState().isTrustedOverlay) {
return true;
}
- const auto& p = mDrawingParent.promote();
+ const auto p = mDrawingParent;
return (p != nullptr) && p->isTrustedOverlay();
}
@@ -1025,7 +1039,7 @@
return mDrawingState.frameRateSelectionPriority;
}
// If not, search whether its parents have it set.
- sp<Layer> parent = getParent();
+ auto parent = getParent();
if (parent != nullptr) {
return parent->getFrameRateSelectionPriority();
}
@@ -1038,10 +1052,11 @@
};
ui::LayerStack Layer::getLayerStack() const {
- if (const auto parent = mDrawingParent.promote()) {
- return parent->getLayerStack();
+ auto p = mDrawingParent;
+ if (p == nullptr) {
+ return getDrawingState().layerStack;
}
- return getDrawingState().layerStack;
+ return mDrawingParent->getLayerStack();
}
bool Layer::setShadowRadius(float shadowRadius) {
@@ -1086,7 +1101,7 @@
return mDrawingState.stretchEffect;
}
- sp<Layer> parent = getParent();
+ auto parent = mDrawingParent;
if (parent != nullptr) {
auto effect = parent->getStretchEffect();
if (effect.hasEffect()) {
@@ -1301,7 +1316,7 @@
bool Layer::isHiddenByPolicy() const {
const State& s(mDrawingState);
- const auto& parent = mDrawingParent.promote();
+ auto parent = mDrawingParent;
if (parent != nullptr && parent->isHiddenByPolicy()) {
return true;
}
@@ -1348,7 +1363,7 @@
LayerDebugInfo info;
const State& ds = getDrawingState();
info.mName = getName();
- sp<Layer> parent = mDrawingParent.promote();
+ auto parent = mDrawingParent;
info.mParentName = parent ? parent->getName() : "none"s;
info.mType = getType();
info.mTransparentRegion = ds.activeTransparentRegion_legacy;
@@ -1580,7 +1595,7 @@
void Layer::setChildrenDrawingParent(const sp<Layer>& newParent) {
for (const sp<Layer>& child : mDrawingChildren) {
- child->mDrawingParent = newParent;
+ child->mDrawingParent = newParent.get();
child->computeBounds(newParent->mBounds, newParent->mEffectiveTransform,
newParent->mEffectiveShadowRadius);
}
@@ -1600,7 +1615,7 @@
}
}
- sp<Layer> parent = getParent();
+ auto parent = getParent();
if (parent != nullptr) {
parent->removeChild(this);
}
@@ -1635,7 +1650,7 @@
mat4 Layer::getColorTransform() const {
mat4 colorTransform = mat4(getDrawingState().colorTransform);
- if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
+ if (auto parent = mDrawingParent; parent != nullptr) {
colorTransform = parent->getColorTransform() * colorTransform;
}
return colorTransform;
@@ -1643,7 +1658,7 @@
bool Layer::hasColorTransform() const {
bool hasColorTransform = getDrawingState().hasColorTransform;
- if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
+ if (auto parent = mDrawingParent; parent != nullptr) {
hasColorTransform = hasColorTransform || parent->hasColorTransform();
}
return hasColorTransform;
@@ -1657,7 +1672,7 @@
}
void Layer::setParent(const sp<Layer>& layer) {
- mCurrentParent = layer;
+ mCurrentParent = layer.get();
}
int32_t Layer::getZ(LayerVector::StateSet) const {
@@ -1861,7 +1876,7 @@
}
half Layer::getAlpha() const {
- const auto& p = mDrawingParent.promote();
+ auto p = mDrawingParent;
half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf;
return parentAlpha * getDrawingState().color.a;
@@ -1872,7 +1887,7 @@
if (fixedTransformHint != ui::Transform::ROT_INVALID) {
return fixedTransformHint;
}
- const auto& p = mCurrentParent.promote();
+ auto p = mCurrentParent;
if (!p) return fixedTransformHint;
return p->getFixedTransformHint();
}
@@ -1883,7 +1898,7 @@
}
int32_t Layer::getBackgroundBlurRadius() const {
- const auto& p = mDrawingParent.promote();
+ auto p = mDrawingParent;
half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf;
return parentAlpha * getDrawingState().backgroundBlurRadius;
@@ -1901,9 +1916,8 @@
Layer::RoundedCornerState Layer::getRoundedCornerState() const {
// Get parent settings
RoundedCornerState parentSettings;
- const auto& parent = mDrawingParent.promote();
- if (parent != nullptr) {
- parentSettings = parent->getRoundedCornerState();
+ if (mDrawingParent != nullptr) {
+ parentSettings = mDrawingParent->getRoundedCornerState();
if (parentSettings.radius > 0) {
ui::Transform t = getActiveTransform(getDrawingState());
t = t.inverse();
@@ -2119,7 +2133,7 @@
LayerProtoHelper::writeToProtoDeprecated(requestedTransform,
layerInfo->mutable_requested_transform());
- auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote();
+ auto parent = useDrawing ? mDrawingParent : mCurrentParent;
if (parent != nullptr) {
layerInfo->set_parent(parent->sequence);
} else {
@@ -2266,9 +2280,9 @@
}
void Layer::fillTouchOcclusionMode(WindowInfo& info) {
- sp<Layer> p = this;
+ Layer* p = this;
while (p != nullptr && !p->hasInputInfo()) {
- p = p->mDrawingParent.promote();
+ p = p->mDrawingParent;
}
if (p != nullptr) {
info.touchOcclusionMode = p->mDrawingState.inputInfo.touchOcclusionMode;
@@ -2280,9 +2294,8 @@
if (mode == gui::DropInputMode::ALL) {
return mode;
}
- sp<Layer> parent = mDrawingParent.promote();
- if (parent) {
- gui::DropInputMode parentMode = parent->getDropInputMode();
+ if (mDrawingParent) {
+ gui::DropInputMode parentMode = mDrawingParent->getDropInputMode();
if (parentMode != gui::DropInputMode::NONE) {
return parentMode;
}
@@ -2309,8 +2322,7 @@
}
// Check if the parent has set an alpha on the layer
- sp<Layer> parent = mDrawingParent.promote();
- if (parent && parent->getAlpha() != 1.0_hf) {
+ if (mDrawingParent && mDrawingParent->getAlpha() != 1.0_hf) {
info.inputFeatures |= WindowInfo::Feature::DROP_INPUT;
ALOGV("Dropping input for %s as requested by policy because alpha=%f", getDebugName(),
static_cast<float>(getAlpha()));
@@ -2408,10 +2420,10 @@
if (mClonedChild != nullptr) {
return this;
}
- if (mDrawingParent == nullptr || mDrawingParent.promote() == nullptr) {
+ if (mDrawingParent == nullptr) {
return nullptr;
}
- return mDrawingParent.promote()->getClonedRoot();
+ return mDrawingParent->getClonedRoot();
}
bool Layer::hasInputInfo() const {
@@ -2598,8 +2610,7 @@
return true;
}
- sp<Layer> parent = mDrawingParent.promote();
- return parent && parent->isInternalDisplayOverlay();
+ return mDrawingParent && mDrawingParent->isInternalDisplayOverlay();
}
void Layer::setClonedChild(const sp<Layer>& clonedChild) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 8209c51..07b2eb5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -795,12 +795,12 @@
// Returns index if removed, or negative value otherwise
// for symmetry with Vector::remove
ssize_t removeChild(const sp<Layer>& layer);
- sp<Layer> getParent() const { return mCurrentParent.promote(); }
// Should be called with the surfaceflinger statelock held
bool isAtRoot() const { return mIsAtRoot; }
void setIsAtRoot(bool isAtRoot) { mIsAtRoot = isAtRoot; }
+ Layer* getParent() const { return mCurrentParent; }
bool hasParent() const { return getParent() != nullptr; }
Rect getScreenBounds(bool reduceTransparentRegion = true) const;
bool setChildLayer(const sp<Layer>& childLayer, int32_t z);
@@ -1007,8 +1007,8 @@
LayerVector mCurrentChildren{LayerVector::StateSet::Current};
LayerVector mDrawingChildren{LayerVector::StateSet::Drawing};
- wp<Layer> mCurrentParent;
- wp<Layer> mDrawingParent;
+ Layer* mCurrentParent = nullptr;
+ Layer* mDrawingParent = nullptr;
// Window types from WindowManager.LayoutParams
const gui::WindowInfo::Type mWindowType;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 81f20ed..acb81dc 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3412,6 +3412,7 @@
states.add(composerState);
lbc->updateTransformHint(mActiveDisplayTransformHint);
+
if (outTransformHint) {
*outTransformHint = mActiveDisplayTransformHint;
}
@@ -3956,7 +3957,7 @@
}
if (what & layer_state_t::eLayerChanged) {
// NOTE: index needs to be calculated before we update the state
- const auto& p = layer->getParent();
+ auto p = layer->getParent();
if (p == nullptr) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
if (layer->setLayer(s.z) && idx >= 0) {
@@ -3974,7 +3975,7 @@
}
if (what & layer_state_t::eRelativeLayerChanged) {
// NOTE: index needs to be calculated before we update the state
- const auto& p = layer->getParent();
+ auto p = layer->getParent();
const auto& relativeHandle = s.relativeLayerSurfaceControl ?
s.relativeLayerSurfaceControl->getHandle() : nullptr;
if (p == nullptr) {
@@ -6125,7 +6126,7 @@
return;
}
- sp<Layer> p = layer;
+ auto p = layer;
while (p != nullptr) {
if (excludeLayers.count(p) != 0) {
return;
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 7072439..db3b572 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -289,7 +289,7 @@
}
static void setLayerDrawingParent(const sp<Layer>& layer, const sp<Layer>& drawingParent) {
- layer->mDrawingParent = drawingParent;
+ layer->mDrawingParent = drawingParent.get();
}
/* ------------------------------------------------------------------------