summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-05 10:06:28 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-05 10:06:28 +0000
commitc2d8c62c743da5ba1bb6b8a40cf066ff0b607eb6 (patch)
treee28f068cec492220f8785870df792caf6deb4c08
parent50ede759561d167033ae84ad2f45c08131f9a756 (diff)
parent843be86c432287f499845d6032e5568ff0313924 (diff)
Snap for 8406016 from 843be86c432287f499845d6032e5568ff0313924 to s-keystone-qcom-release
Change-Id: I3c6f1004a320cf08e039ecda0cd448890cd2a3f1
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp11
-rw-r--r--services/surfaceflinger/Layer.h1
-rw-r--r--services/surfaceflinger/LayerRenderArea.cpp24
-rw-r--r--services/surfaceflinger/LayerRenderArea.h3
-rw-r--r--services/surfaceflinger/RenderArea.h5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp47
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h9
-rw-r--r--services/surfaceflinger/tests/unittests/CompositionTest.cpp2
-rw-r--r--services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h4
9 files changed, 66 insertions, 40 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 07de93f49b..f0405fb232 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -559,6 +559,13 @@ status_t HWComposer::getDeviceCompositionChanges(
sp<Fence> HWComposer::getPresentFence(HalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
+
+ auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
+
+ if (!hwcDisplay->isConnected()) {
+ return Fence::NO_FENCE;
+ }
+
return mDisplayData.at(displayId).lastPresentFence;
}
@@ -583,6 +590,10 @@ status_t HWComposer::presentAndGetReleaseFences(
auto& displayData = mDisplayData[displayId];
auto& hwcDisplay = displayData.hwcDisplay;
+ if (!hwcDisplay->isConnected()) {
+ return NO_ERROR;
+ }
+
if (displayData.validateWasSkipped) {
displayData.validateWasSkipped = false;
// explicitly flush all pending commands
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 512dd6e5d3..a95f9085d7 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -1,4 +1,3 @@
-
/*
* Copyright (C) 2007 The Android Open Source Project
*
diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp
index 11fe6d0755..bced928101 100644
--- a/services/surfaceflinger/LayerRenderArea.cpp
+++ b/services/surfaceflinger/LayerRenderArea.cpp
@@ -26,18 +26,12 @@
namespace android {
namespace {
-struct ReparentForDrawing {
- const sp<Layer>& oldParent;
-
- ReparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent,
- const Rect& drawingBounds)
- : oldParent(oldParent) {
+void reparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent,
+ const Rect& drawingBounds) {
// Compute and cache the bounds for the new parent layer.
newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(),
- 0.f /* shadowRadius */);
+ 0.f /* shadowRadius */);
oldParent->setChildrenDrawingParent(newParent);
- }
- ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); }
};
} // namespace
@@ -116,11 +110,19 @@ void LayerRenderArea::render(std::function<void()> drawLayers) {
uint32_t h = static_cast<uint32_t>(getHeight());
// In the "childrenOnly" case we reparent the children to a screenshot
// layer which has no properties set and which does not draw.
+ // We hold the statelock as the reparent-for-drawing operation modifies the
+ // hierarchy and there could be readers on Binder threads, like dump.
sp<ContainerLayer> screenshotParentLayer = mFlinger.getFactory().createContainerLayer(
{&mFlinger, nullptr, "Screenshot Parent"s, w, h, 0, LayerMetadata()});
-
- ReparentForDrawing reparent(mLayer, screenshotParentLayer, sourceCrop);
+ {
+ Mutex::Autolock _l(mFlinger.mStateLock);
+ reparentForDrawing(mLayer, screenshotParentLayer, sourceCrop);
+ }
drawLayers();
+ {
+ Mutex::Autolock _l(mFlinger.mStateLock);
+ mLayer->setChildrenDrawingParent(mLayer);
+ }
}
}
diff --git a/services/surfaceflinger/LayerRenderArea.h b/services/surfaceflinger/LayerRenderArea.h
index 6a906944a7..41273e01c1 100644
--- a/services/surfaceflinger/LayerRenderArea.h
+++ b/services/surfaceflinger/LayerRenderArea.h
@@ -46,6 +46,7 @@ public:
Rect getSourceCrop() const override;
void render(std::function<void()> drawLayers) override;
+ virtual sp<Layer> getParentLayer() const { return mLayer; }
private:
const sp<Layer> mLayer;
@@ -58,4 +59,4 @@ private:
const bool mChildrenOnly;
};
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index c9f7f46953..387364c03a 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -4,6 +4,7 @@
#include <ui/Transform.h>
#include <functional>
+#include "Layer.h"
namespace android {
@@ -85,6 +86,10 @@ public:
// Returns the source display viewport.
const Rect& getLayerStackSpaceRect() const { return mLayerStackSpaceRect; }
+ // If this is a LayerRenderArea, return the root layer of the
+ // capture operation.
+ virtual sp<Layer> getParentLayer() const { return nullptr; }
+
protected:
const bool mAllowSecureLayers;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 223e71dba5..04b49325d2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4901,14 +4901,19 @@ status_t SurfaceFlinger::setTransactionState(
state.traverseStatesWithBuffers([&](const layer_state_t& state) {
sp<Layer> layer = fromHandle(state.surface).promote();
if (layer != nullptr) {
- const uint32_t layerStackId = layer->getLayerStack();
SmomoIntf *smoMo = nullptr;
- for (auto &instance: mSmomoInstances) {
- if (instance.layerStackId == layerStackId) {
- smoMo = instance.smoMo;
- break;
+ if (mSmomoInstances.size() > 1) {
+ const uint32_t layerStackId = layer->getLayerStack();
+ for (auto &instance: mSmomoInstances) {
+ if (instance.layerStackId == layerStackId) {
+ smoMo = instance.smoMo;
+ break;
+ }
}
}
+ else if (mSmomoInstances.size() == 1) {
+ smoMo = mSmomoInstances[0].smoMo;
+ }
if (smoMo) {
smomo::SmomoBufferStats bufferStats;
@@ -7931,17 +7936,6 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
// and failed if display is not in native mode. This provide a way to force using native
// colors when capture.
dataspace = args.dataspace;
- if (dataspace == ui::Dataspace::UNKNOWN) {
- auto display = findDisplay(WithLayerStack(parent->getLayerStack()));
- if (!display) {
- // If the layer is not on a display, use the dataspace for the default display.
- display = getDefaultDisplayDeviceLocked();
- }
-
- const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode;
- dataspace = pickDataspaceFromColorMode(colorMode);
- }
-
} // mStateLock
// really small crop or frameScale
@@ -8078,7 +8072,7 @@ status_t SurfaceFlinger::captureScreenCommon(
status_t result = NO_ERROR;
renderArea->render([&] {
- result = renderScreenImplLocked(*renderArea, traverseLayers, buffer,
+ result = renderScreenImpl(*renderArea, traverseLayers, buffer,
canCaptureBlackoutContent, regionSampling, grayscale,
captureResults);
});
@@ -8090,7 +8084,7 @@ status_t SurfaceFlinger::captureScreenCommon(
return NO_ERROR;
}
-status_t SurfaceFlinger::renderScreenImplLocked(
+status_t SurfaceFlinger::renderScreenImpl(
const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
const std::shared_ptr<renderengine::ExternalTexture>& buffer,
bool canCaptureBlackoutContent, bool regionSampling, bool grayscale,
@@ -8113,7 +8107,20 @@ status_t SurfaceFlinger::renderScreenImplLocked(
}
captureResults.buffer = buffer->getBuffer();
- captureResults.capturedDataspace = renderArea.getReqDataSpace();
+ auto dataspace = renderArea.getReqDataSpace();
+ auto parent = renderArea.getParentLayer();
+ if ((dataspace == ui::Dataspace::UNKNOWN) && (parent != nullptr)) {
+ Mutex::Autolock lock(mStateLock);
+ auto display = findDisplay(WithLayerStack(parent->getLayerStack()));
+ if (!display) {
+ // If the layer is not on a display, use the dataspace for the default display.
+ display = getDefaultDisplayDeviceLocked();
+ }
+
+ const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode;
+ dataspace = pickDataspaceFromColorMode(colorMode);
+ }
+ captureResults.capturedDataspace = dataspace;
const auto reqWidth = renderArea.getReqWidth();
const auto reqHeight = renderArea.getReqHeight();
@@ -8131,7 +8138,7 @@ status_t SurfaceFlinger::renderScreenImplLocked(
clientCompositionDisplay.clip = sourceCrop;
clientCompositionDisplay.orientation = rotation;
- clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace();
+ clientCompositionDisplay.outputDataspace = dataspace;
clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance;
const float colorSaturation = grayscale ? 0 : 1;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index dad158d89b..16305aa135 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -443,6 +443,7 @@ private:
friend class RefreshRateOverlay;
friend class RegionSamplingThread;
friend class SurfaceTracing;
+ friend class LayerRenderArea;
// For unit tests
friend class TestableSurfaceFlinger;
@@ -1023,10 +1024,10 @@ private:
const std::shared_ptr<renderengine::ExternalTexture>&,
bool regionSampling, bool grayscale,
const sp<IScreenCaptureListener>&);
- status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction,
- const std::shared_ptr<renderengine::ExternalTexture>&,
- bool canCaptureBlackoutContent, bool regionSampling,
- bool grayscale, ScreenCaptureResults&);
+ status_t renderScreenImpl(const RenderArea&, TraverseLayersFunction,
+ const std::shared_ptr<renderengine::ExternalTexture>&,
+ bool canCaptureBlackoutContent, bool regionSampling,
+ bool grayscale, ScreenCaptureResults&) EXCLUDES(mStateLock);
bool canAllocateHwcDisplayIdForVDS(uint64_t usage);
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 52a36a2719..fdf445fd93 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -248,7 +248,7 @@ void CompositionTest::captureScreenComposition() {
*mRenderEngine, true);
status_t result =
- mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer,
+ mFlinger.renderScreenImpl(*renderArea, traverseLayers, mCaptureScreenBuffer,
forSystem, regionSampling);
EXPECT_EQ(NO_ERROR, result);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 8656c16198..3e676560c5 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -347,12 +347,12 @@ public:
return mFlinger->onMessageReceived(what, /*vsyncId=*/0, systemTime());
}
- auto renderScreenImplLocked(const RenderArea& renderArea,
+ auto renderScreenImpl(const RenderArea& renderArea,
SurfaceFlinger::TraverseLayersFunction traverseLayers,
const std::shared_ptr<renderengine::ExternalTexture>& buffer,
bool forSystem, bool regionSampling) {
ScreenCaptureResults captureResults;
- return mFlinger->renderScreenImplLocked(renderArea, traverseLayers, buffer, forSystem,
+ return mFlinger->renderScreenImpl(renderArea, traverseLayers, buffer, forSystem,
regionSampling, false /* grayscale */,
captureResults);
}