summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-06-18 07:18:14 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-06-18 07:18:14 +0000
commit421036dd914d2ec2b6630b338d0a663b127696d8 (patch)
tree55a0948aaa76e5d270540f7b39d5927f6ba2c80b
parent913dd036191f1e2222cf977c47595eeb7af54ad6 (diff)
parenta17b14eb92f6c21a9cea97ed0ca30df74da9fc29 (diff)
downloadnative-421036dd914d2ec2b6630b338d0a663b127696d8.tar.gz
release-request-f4ecf242-5d1c-45e0-8c7c-ede48d1a9e82-for-git_oc-release-4111650 snap-temp-L02200000075283731
Change-Id: Iee5ced44440d132836c4fd1df09ec6f7f9d36ed3
-rw-r--r--include/gui/SurfaceControl.h2
-rw-r--r--libs/gui/SurfaceControl.cpp19
-rw-r--r--services/surfaceflinger/Client.cpp19
-rw-r--r--services/surfaceflinger/Client.h3
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.h5
-rw-r--r--services/surfaceflinger/Layer.cpp48
-rw-r--r--services/surfaceflinger/Layer.h5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp20
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger_hwc1.cpp20
10 files changed, 83 insertions, 60 deletions
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index 712a323337..8bb705cf77 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -135,6 +135,7 @@ public:
const sp<SurfaceControl>& control, Parcel* parcel);
sp<Surface> getSurface() const;
+ sp<Surface> createSurface() const;
sp<IBinder> getHandle() const;
status_t clearLayerFrameStats() const;
@@ -155,6 +156,7 @@ private:
~SurfaceControl();
+ sp<Surface> generateSurfaceLocked() const;
status_t validate() const;
void destroy();
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index bf8a815fe6..58bd273de6 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -237,17 +237,30 @@ status_t SurfaceControl::writeSurfaceToParcel(
return parcel->writeStrongBinder(IInterface::asBinder(bp));
}
+sp<Surface> SurfaceControl::generateSurfaceLocked() const
+{
+ // This surface is always consumed by SurfaceFlinger, so the
+ // producerControlledByApp value doesn't matter; using false.
+ mSurfaceData = new Surface(mGraphicBufferProducer, false);
+
+ return mSurfaceData;
+}
+
sp<Surface> SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
- // This surface is always consumed by SurfaceFlinger, so the
- // producerControlledByApp value doesn't matter; using false.
- mSurfaceData = new Surface(mGraphicBufferProducer, false);
+ return generateSurfaceLocked();
}
return mSurfaceData;
}
+sp<Surface> SurfaceControl::createSurface() const
+{
+ Mutex::Autolock _l(mLock);
+ return generateSurfaceLocked();
+}
+
sp<IBinder> SurfaceControl::getHandle() const
{
Mutex::Autolock lock(mLock);
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index e9a251305f..8ba6cb9ba7 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -57,9 +57,19 @@ Client::~Client()
}
void Client::setParentLayer(const sp<Layer>& parentLayer) {
+ Mutex::Autolock _l(mLock);
mParentLayer = parentLayer;
}
+sp<Layer> Client::getParentLayer(bool* outParentDied) const {
+ Mutex::Autolock _l(mLock);
+ sp<Layer> parent = mParentLayer.promote();
+ if (outParentDied != nullptr) {
+ *outParentDied = (mParentLayer != nullptr && parent == nullptr);
+ }
+ return parent;
+}
+
status_t Client::initCheck() const {
return NO_ERROR;
}
@@ -108,7 +118,7 @@ status_t Client::onTransact(
// We grant an exception in the case that the Client has a "parent layer", as its
// effects will be scoped to that layer.
if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0)
- && (mParentLayer.promote() == nullptr)) {
+ && (getParentLayer() == nullptr)) {
// we're called from a different process, do the real check
if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
{
@@ -135,11 +145,12 @@ status_t Client::createSurface(
return NAME_NOT_FOUND;
}
}
- if (parent == nullptr && mParentLayer != nullptr) {
- parent = mParentLayer.promote();
+ if (parent == nullptr) {
+ bool parentDied;
+ parent = getParentLayer(&parentDied);
// If we had a parent, but it died, we've lost all
// our capabilities.
- if (parent == nullptr) {
+ if (parentDied) {
return NAME_NOT_FOUND;
}
}
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index b5f98b8a6f..2aab28f37d 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -71,12 +71,13 @@ private:
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+ sp<Layer> getParentLayer(bool* outParentDied = nullptr) const;
+
// constant
sp<SurfaceFlinger> mFlinger;
// protected by mLock
DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;
-
wp<Layer> mParentLayer;
// thread-safe
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 97582a7a99..7f26e56a63 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -35,6 +35,7 @@
#include <unordered_map>
#include <unordered_set>
#include <vector>
+#include <map>
namespace android {
class Fence;
@@ -283,7 +284,9 @@ private:
bool mIsConnected;
DisplayType mType;
std::unordered_map<hwc2_layer_t, std::weak_ptr<Layer>> mLayers;
- std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
+ // The ordering in this map matters, for getConfigs(), when it is
+ // converted to a vector
+ std::map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
};
// Convenience C++ class to access hwc2_device_t Layer functions directly.
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2ff14aa395..022b41634d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -403,7 +403,7 @@ Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const {
win.intersect(s.finalCrop, &win);
}
- const sp<Layer>& p = getParent();
+ const sp<Layer>& p = mDrawingParent.promote();
// Now we need to calculate the parent bounds, so we can clip ourselves to those.
// When calculating the parent bounds for purposes of clipping,
// we don't need to constrain the parent to its transparent region.
@@ -440,7 +440,7 @@ Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
}
Rect bounds = win;
- const auto& p = getParent();
+ const auto& p = mDrawingParent.promote();
if (p != nullptr) {
// Look in computeScreenBounds recursive call for explanation of
// why we pass false here.
@@ -498,7 +498,7 @@ FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
// Screen space to make reduction to parent crop clearer.
Rect activeCrop = computeInitialCrop(hw);
- const auto& p = getParent();
+ const auto& p = mDrawingParent.promote();
if (p != nullptr) {
auto parentCrop = p->computeInitialCrop(hw);
activeCrop.intersect(parentCrop, &activeCrop);
@@ -710,7 +710,7 @@ void Layer::setGeometry(
int type = s.type;
int appId = s.appId;
- sp<Layer> parent = mParent.promote();
+ sp<Layer> parent = mDrawingParent.promote();
if (parent.get()) {
auto& parentState = parent->getDrawingState();
type = parentState.type;
@@ -1109,8 +1109,9 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
* of a camera where the buffer remains in native orientation,
* we want the pixels to always be upright.
*/
- if (getParent() != nullptr) {
- const auto parentTransform = getParent()->getTransform();
+ sp<Layer> p = mDrawingParent.promote();
+ if (p != nullptr) {
+ const auto parentTransform = p->getTransform();
tr = tr * inverseOrientation(parentTransform.getOrientation());
}
@@ -1928,7 +1929,7 @@ bool Layer::setDataSpace(android_dataspace dataSpace) {
}
uint32_t Layer::getLayerStack() const {
- auto p = getParent();
+ auto p = mDrawingParent.promote();
if (p == nullptr) {
return getDrawingState().layerStack;
}
@@ -2071,7 +2072,7 @@ void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
bool Layer::isHiddenByPolicy() const {
const Layer::State& s(mDrawingState);
- const auto& parent = getParent();
+ const auto& parent = mDrawingParent.promote();
if (parent != nullptr && parent->isHiddenByPolicy()) {
return true;
}
@@ -2555,25 +2556,7 @@ bool Layer::reparentChildren(const sp<IBinder>& newParentHandle) {
}
for (const sp<Layer>& child : mCurrentChildren) {
- // We don't call addChild as we need to delay updating the child's parent pointer until
- // a transaction occurs. Remember a refresh could occur in between now and the next
- // transaction, in which case the Layer's parent pointer would be updated, but changes
- // made to the parent in the same transaction would not have applied.
- // This means that the following kind of scenario wont work:
- //
- // 1. Existing and visible child and parent surface exist
- // 2. Create new surface hidden
- // 3. Open transaction
- // 4. Show the new surface, and reparent the old surface's children to it.
- // 5. Close transaction.
- //
- // If we were to update the parent pointer immediately, then the child surface
- // could disappear for one frame as it pointed at the new parent which
- // hasn't yet become visible as the transaction hasn't yet occurred.
- //
- // Instead we defer the reparenting to commitChildList which happens as part
- // of the global transaction.
- newParent->mCurrentChildren.add(child);
+ newParent->addChild(child);
sp<Client> client(child->mClientRef.promote());
if (client != nullptr) {
@@ -2601,7 +2584,7 @@ bool Layer::detachChildren() {
}
void Layer::setParent(const sp<Layer>& layer) {
- mParent = layer;
+ mCurrentParent = layer;
}
void Layer::clearSyncPoints() {
@@ -2691,7 +2674,7 @@ void Layer::traverseInReverseZOrder(LayerVector::StateSet stateSet,
Transform Layer::getTransform() const {
Transform t;
- const auto& p = getParent();
+ const auto& p = mDrawingParent.promote();
if (p != nullptr) {
t = p->getTransform();
@@ -2724,14 +2707,14 @@ Transform Layer::getTransform() const {
#ifdef USE_HWC2
float Layer::getAlpha() const {
- const auto& p = getParent();
+ const auto& p = mDrawingParent.promote();
float parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0;
return parentAlpha * getDrawingState().alpha;
}
#else
uint8_t Layer::getAlpha() const {
- const auto& p = getParent();
+ const auto& p = mDrawingParent.promote();
float parentAlpha = (p != nullptr) ? (p->getAlpha() / 255.0f) : 1.0;
float drawingAlpha = getDrawingState().alpha / 255.0f;
@@ -2743,11 +2726,10 @@ uint8_t Layer::getAlpha() const {
void Layer::commitChildList() {
for (size_t i = 0; i < mCurrentChildren.size(); i++) {
const auto& child = mCurrentChildren[i];
- child->setParent(this);
-
child->commitChildList();
}
mDrawingChildren = mCurrentChildren;
+ mDrawingParent = mCurrentParent;
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5335fff9ff..24fc10dd2b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -524,7 +524,7 @@ public:
// 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 mParent.promote(); }
+ sp<Layer> getParent() const { return mCurrentParent.promote(); }
bool hasParent() const { return getParent() != nullptr; }
Rect computeScreenBounds(bool reduceTransparentRegion = true) const;
@@ -801,7 +801,8 @@ private:
// Child list used for rendering.
LayerVector mDrawingChildren;
- wp<Layer> mParent;
+ wp<Layer> mCurrentParent;
+ wp<Layer> mDrawingParent;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a49e8f4aa8..6174185969 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2679,14 +2679,18 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer, bool topLevelOnly) {
Mutex::Autolock _l(mStateLock);
const auto& p = layer->getParent();
- const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
- mCurrentState.layersSortedByZ.remove(layer);
-
+ ssize_t index;
if (p != nullptr) {
+ if (topLevelOnly) {
+ return NO_ERROR;
+ }
+
+ index = p->removeChild(layer);
+
sp<Layer> ancestor = p;
while (ancestor->getParent() != nullptr) {
ancestor = ancestor->getParent();
@@ -2695,6 +2699,8 @@ status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
ALOGE("removeLayer called with a layer whose parent has been removed");
return NAME_NOT_FOUND;
}
+ } else {
+ index = mCurrentState.layersSortedByZ.remove(layer);
}
// As a matter of normal operation, the LayerCleaner will produce a second
@@ -3125,11 +3131,9 @@ status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
if (l == nullptr) {
// The layer has already been removed, carry on
return NO_ERROR;
- } if (l->getParent() != nullptr) {
- // If we have a parent, then we can continue to live as long as it does.
- return NO_ERROR;
}
- return removeLayer(l);
+ // If we have a parent, then we can continue to live as long as it does.
+ return removeLayer(l, true);
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c89e26f798..9239538932 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -396,7 +396,7 @@ private:
status_t onLayerDestroyed(const wp<Layer>& layer);
// remove a layer from SurfaceFlinger immediately
- status_t removeLayer(const sp<Layer>& layer);
+ status_t removeLayer(const sp<Layer>& layer, bool topLevelOnly = false);
// add a layer to SurfaceFlinger
status_t addClientLayer(const sp<Client>& client,
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index e19e021239..3d421d2154 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -2339,12 +2339,20 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer, bool topLevelOnly) {
Mutex::Autolock _l(mStateLock);
const auto& p = layer->getParent();
- const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
- mCurrentState.layersSortedByZ.remove(layer);
+ ssize_t index;
+ if (p != nullptr) {
+ if (topLevelOnly) {
+ return NO_ERROR;
+ }
+
+ index = p->removeChild(layer);
+ } else {
+ index = mCurrentState.layersSortedByZ.remove(layer);
+ }
// As a matter of normal operation, the LayerCleaner will produce a second
// attempt to remove the surface. The Layer will be kept alive in mDrawingState
@@ -2769,11 +2777,9 @@ status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
if (l == nullptr) {
// The layer has already been removed, carry on
return NO_ERROR;
- } if (l->getParent() != nullptr) {
- // If we have a parent, then we can continue to live as long as it does.
- return NO_ERROR;
}
- return removeLayer(l);
+ // If we have a parent, then we can continue to live as long as it does.
+ return removeLayer(l, true);
}
// ---------------------------------------------------------------------------