diff options
| author | 2019-02-14 20:22:12 +0000 | |
|---|---|---|
| committer | 2019-02-14 20:22:12 +0000 | |
| commit | f6d3044c4db6d928a19007bd8ab056c6ee52b7b0 (patch) | |
| tree | 9ffe31b2360833ead630664620bffa9e43be5793 | |
| parent | 7caa828e5d7dad4a07d4776498caed8529685d84 (diff) | |
| parent | 0b785d86a036383e6173d4680cf02554e7851d33 (diff) | |
Merge changes I20e4aa1a,I00370f05
* changes:
SF: Introduce LayerCompositionState
SF: Introduce OutputLayerCompositionState
44 files changed, 967 insertions, 634 deletions
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 89eee6b621..c077b6841f 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -24,8 +24,12 @@ #include <mutex> #include <compositionengine/CompositionEngine.h> +#include <compositionengine/Display.h> #include <compositionengine/Layer.h> #include <compositionengine/LayerCreationArgs.h> +#include <compositionengine/OutputLayer.h> +#include <compositionengine/impl/LayerCompositionState.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> #include <cutils/compiler.h> #include <cutils/native_handle.h> #include <cutils/properties.h> @@ -66,11 +70,10 @@ BufferLayer::BufferLayer(const LayerCreationArgs& args) BufferLayer::~BufferLayer() { mFlinger->deleteTextureAsync(mTextureName); - if (!getBE().mHwcLayers.empty()) { + if (destroyAllHwcLayersPlusChildren()) { ALOGE("Found stale hardware composer layers when destroying " "surface flinger layer %s", mName.string()); - destroyAllHwcLayersPlusChildren(); } mFlinger->mTimeStats->onDestroy(getSequence()); @@ -91,7 +94,7 @@ void BufferLayer::useEmptyDamage() { bool BufferLayer::isOpaque(const Layer::State& s) const { // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the // layer's opaque flag. - if ((getBE().compositionInfo.hwc.sidebandStream == nullptr) && (mActiveBuffer == nullptr)) { + if ((mSidebandStream == nullptr) && (mActiveBuffer == nullptr)) { return false; } @@ -102,7 +105,7 @@ bool BufferLayer::isOpaque(const Layer::State& s) const { bool BufferLayer::isVisible() const { return !(isHiddenByPolicy()) && getAlpha() > 0.0f && - (mActiveBuffer != nullptr || getBE().compositionInfo.hwc.sidebandStream != nullptr); + (mActiveBuffer != nullptr || mSidebandStream != nullptr); } bool BufferLayer::isFixedSize() const { @@ -171,7 +174,8 @@ bool BufferLayer::prepareClientLayer(const RenderArea& renderArea, const Region& layer.source.buffer.usePremultipliedAlpha = getPremultipledAlpha(); layer.source.buffer.isY410BT2020 = isHdrY410(); // TODO: we could be more subtle with isFixedSize() - const bool useFiltering = needsFiltering() || renderArea.needsFiltering() || isFixedSize(); + const bool useFiltering = needsFiltering(renderArea.getDisplayDevice()) || + renderArea.needsFiltering() || isFixedSize(); // Query the texture matrix given our current filtering mode. float textureMatrix[16]; @@ -237,26 +241,31 @@ bool BufferLayer::isHdrY410() const { // pixel format is HDR Y410 masquerading as RGBA_1010102 return (mCurrentDataSpace == ui::Dataspace::BT2020_ITU_PQ && getDrawingApi() == NATIVE_WINDOW_API_MEDIA && - getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102); + mActiveBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102); } -void BufferLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform, - const Rect& viewport, int32_t supportedPerFrameMetadata) { - RETURN_IF_NO_HWC_LAYER(displayId); +void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice, + const ui::Transform& transform, const Rect& viewport, + int32_t supportedPerFrameMetadata) { + RETURN_IF_NO_HWC_LAYER(displayDevice); // Apply this display's projection's viewport to the visible region // before giving it to the HWC HAL. Region visible = transform.transform(visibleRegion.intersect(viewport)); - auto& hwcInfo = getBE().mHwcLayers[displayId]; - auto& hwcLayer = hwcInfo.layer; + const auto outputLayer = findOutputLayerForDisplay(displayDevice); + LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc); + + auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer; auto error = hwcLayer->setVisibleRegion(visible); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), to_string(error).c_str(), static_cast<int32_t>(error)); visible.dump(LOG_TAG); } - getBE().compositionInfo.hwc.visibleRegion = visible; + outputLayer->editState().visibleRegion = visible; + + auto& layerCompositionState = getCompositionLayer()->editState().frontEnd; error = hwcLayer->setSurfaceDamage(surfaceDamageRegion); if (error != HWC2::Error::None) { @@ -264,29 +273,29 @@ void BufferLayer::setPerFrameData(DisplayId displayId, const ui::Transform& tran to_string(error).c_str(), static_cast<int32_t>(error)); surfaceDamageRegion.dump(LOG_TAG); } - getBE().compositionInfo.hwc.surfaceDamage = surfaceDamageRegion; + layerCompositionState.surfaceDamage = surfaceDamageRegion; // Sideband layers - if (getBE().compositionInfo.hwc.sidebandStream.get()) { - setCompositionType(displayId, HWC2::Composition::Sideband); + if (layerCompositionState.sidebandStream.get()) { + setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::SIDEBAND); ALOGV("[%s] Requesting Sideband composition", mName.string()); - error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle()); + error = hwcLayer->setSidebandStream(layerCompositionState.sidebandStream->handle()); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(), - getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(), + layerCompositionState.sidebandStream->handle(), to_string(error).c_str(), static_cast<int32_t>(error)); } - getBE().compositionInfo.compositionType = HWC2::Composition::Sideband; + layerCompositionState.compositionType = Hwc2::IComposerClient::Composition::SIDEBAND; return; } // Device or Cursor layers if (mPotentialCursor) { ALOGV("[%s] Requesting Cursor composition", mName.string()); - setCompositionType(displayId, HWC2::Composition::Cursor); + setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::CURSOR); } else { ALOGV("[%s] Requesting Device composition", mName.string()); - setCompositionType(displayId, HWC2::Composition::Device); + setCompositionType(displayDevice, Hwc2::IComposerClient::Composition::DEVICE); } ALOGV("setPerFrameData: dataspace = %d", mCurrentDataSpace); @@ -308,12 +317,11 @@ void BufferLayer::setPerFrameData(DisplayId displayId, const ui::Transform& tran ALOGE("[%s] Failed to setColorTransform: %s (%d)", mName.string(), to_string(error).c_str(), static_cast<int32_t>(error)); } - getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace; - getBE().compositionInfo.hwc.hdrMetadata = getDrawingHdrMetadata(); - getBE().compositionInfo.hwc.supportedPerFrameMetadata = supportedPerFrameMetadata; - getBE().compositionInfo.hwc.colorTransform = getColorTransform(); + layerCompositionState.dataspace = mCurrentDataSpace; + layerCompositionState.colorTransform = getColorTransform(); + layerCompositionState.hdrMetadata = metadata; - setHwcLayerBuffer(displayId); + setHwcLayerBuffer(displayDevice); } bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { @@ -605,9 +613,21 @@ bool BufferLayer::getOpacityForFormat(uint32_t format) { return true; } -bool BufferLayer::needsFiltering() const { - const auto displayFrame = getBE().compositionInfo.hwc.displayFrame; - const auto sourceCrop = getBE().compositionInfo.hwc.sourceCrop; +bool BufferLayer::needsFiltering(const sp<const DisplayDevice>& displayDevice) const { + // If we are not capturing based on the state of a known display device, we + // only return mNeedsFiltering + if (displayDevice == nullptr) { + return mNeedsFiltering; + } + + const auto outputLayer = findOutputLayerForDisplay(displayDevice); + if (outputLayer == nullptr) { + return mNeedsFiltering; + } + + const auto& compositionState = outputLayer->getState(); + const auto displayFrame = compositionState.displayFrame; + const auto sourceCrop = compositionState.sourceCrop; return mNeedsFiltering || sourceCrop.getHeight() != displayFrame.getHeight() || sourceCrop.getWidth() != displayFrame.getWidth(); } diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 0f8a350d6a..d358baeae0 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -80,8 +80,8 @@ public: bool isHdrY410() const override; - void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport, - int32_t supportedPerFrameMetadata) override; + void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform, + const Rect& viewport, int32_t supportedPerFrameMetadata) override; bool onPreComposition(nsecs_t refreshStartTime) override; bool onPostComposition(const std::optional<DisplayId>& displayId, @@ -148,7 +148,7 @@ private: virtual status_t updateActiveBuffer() = 0; virtual status_t updateFrameNumber(nsecs_t latchTime) = 0; - virtual void setHwcLayerBuffer(DisplayId displayId) = 0; + virtual void setHwcLayerBuffer(const sp<const DisplayDevice>& displayDevice) = 0; protected: // Loads the corresponding system property once per process @@ -177,7 +177,7 @@ protected: private: // Returns true if this layer requires filtering - bool needsFiltering() const; + bool needsFiltering(const sp<const DisplayDevice>& displayDevice) const; uint64_t getHeadFrameNumber() const; diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index 0313c326a5..cdcbcd94f4 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -14,13 +14,18 @@ * limitations under the License. */ +#include <compositionengine/Display.h> +#include <compositionengine/Layer.h> +#include <compositionengine/OutputLayer.h> +#include <compositionengine/impl/LayerCompositionState.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> +#include <system/window.h> + #include "BufferQueueLayer.h" #include "LayerRejecter.h" #include "TimeStats/TimeStats.h" -#include <system/window.h> - namespace android { BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {} @@ -195,8 +200,9 @@ bool BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) { if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) { // mSidebandStreamChanged was changed to false // replicated in LayerBE until FE/BE is ready to be synchronized - getBE().compositionInfo.hwc.sidebandStream = mConsumer->getSidebandStream(); - if (getBE().compositionInfo.hwc.sidebandStream != nullptr) { + auto& layerCompositionState = getCompositionLayer()->editState().frontEnd; + layerCompositionState.sidebandStream = mConsumer->getSidebandStream(); + if (layerCompositionState.sidebandStream != nullptr) { setTransactionFlags(eTransactionNeeded); mFlinger->setTransactionFlags(eTraversalNeeded); } @@ -325,8 +331,9 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t status_t BufferQueueLayer::updateActiveBuffer() { // update the active buffer mActiveBuffer = mConsumer->getCurrentBuffer(&mActiveBufferSlot, &mActiveBufferFence); - getBE().compositionInfo.mBuffer = mActiveBuffer; - getBE().compositionInfo.mBufferSlot = mActiveBufferSlot; + auto& layerCompositionState = getCompositionLayer()->editState().frontEnd; + layerCompositionState.buffer = mActiveBuffer; + layerCompositionState.bufferSlot = mActiveBufferSlot; if (mActiveBuffer == nullptr) { // this can only happen if the very first buffer was rejected. @@ -350,24 +357,28 @@ status_t BufferQueueLayer::updateFrameNumber(nsecs_t latchTime) { return NO_ERROR; } -void BufferQueueLayer::setHwcLayerBuffer(DisplayId displayId) { - auto& hwcInfo = getBE().mHwcLayers[displayId]; - auto& hwcLayer = hwcInfo.layer; +void BufferQueueLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) { + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer); + LOG_FATAL_IF(!outputLayer->getState.hwc); + auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer; uint32_t hwcSlot = 0; sp<GraphicBuffer> hwcBuffer; - hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer); + (*outputLayer->editState().hwc) + .hwcBufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer); auto acquireFence = mConsumer->getCurrentFence(); auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), - getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(), - static_cast<int32_t>(error)); + ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle, + to_string(error).c_str(), static_cast<int32_t>(error)); } - getBE().compositionInfo.mBufferSlot = mActiveBufferSlot; - getBE().compositionInfo.mBuffer = mActiveBuffer; - getBE().compositionInfo.hwc.fence = acquireFence; + + auto& layerCompositionState = getCompositionLayer()->editState().frontEnd; + layerCompositionState.bufferSlot = mActiveBufferSlot; + layerCompositionState.buffer = mActiveBuffer; + layerCompositionState.acquireFence = acquireFence; } // ----------------------------------------------------------------------- diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index d392a699b3..30107e24ab 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -97,7 +97,7 @@ private: status_t updateActiveBuffer() override; status_t updateFrameNumber(nsecs_t latchTime) override; - void setHwcLayerBuffer(DisplayId displayId) override; + void setHwcLayerBuffer(const sp<const DisplayDevice>& displayDevice) override; // ----------------------------------------------------------------------- // Interface implementation for BufferLayerConsumer::ContentsChangedListener diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 2d6da765dc..a3d5b89be2 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -19,15 +19,19 @@ #define LOG_TAG "BufferStateLayer" #define ATRACE_TAG ATRACE_TAG_GRAPHICS -#include "BufferStateLayer.h" -#include "ColorLayer.h" - -#include "TimeStats/TimeStats.h" +#include <limits> +#include <compositionengine/Display.h> +#include <compositionengine/Layer.h> +#include <compositionengine/OutputLayer.h> +#include <compositionengine/impl/LayerCompositionState.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> #include <private/gui/SyncFeatures.h> #include <renderengine/Image.h> -#include <limits> +#include "BufferStateLayer.h" +#include "ColorLayer.h" +#include "TimeStats/TimeStats.h" namespace android { @@ -438,9 +442,10 @@ bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) { if (mSidebandStreamChanged.exchange(false)) { const State& s(getDrawingState()); // mSidebandStreamChanged was true - // replicated in LayerBE until FE/BE is ready to be synchronized - getBE().compositionInfo.hwc.sidebandStream = s.sidebandStream; - if (getBE().compositionInfo.hwc.sidebandStream != nullptr) { + LOG_ALWAYS_FATAL_IF(!getCompositionLayer()); + mSidebandStream = s.sidebandStream; + getCompositionLayer()->editState().frontEnd.sidebandStream = mSidebandStream; + if (mSidebandStream != nullptr) { setTransactionFlags(eTransactionNeeded); mFlinger->setTransactionFlags(eTraversalNeeded); } @@ -594,8 +599,9 @@ status_t BufferStateLayer::updateActiveBuffer() { mActiveBuffer = s.buffer; mActiveBufferFence = s.acquireFence; - getBE().compositionInfo.mBuffer = mActiveBuffer; - getBE().compositionInfo.mBufferSlot = 0; + auto& layerCompositionState = getCompositionLayer()->editState().frontEnd; + layerCompositionState.buffer = mActiveBuffer; + layerCompositionState.bufferSlot = 0; return NO_ERROR; } @@ -611,9 +617,10 @@ status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) { return NO_ERROR; } -void BufferStateLayer::setHwcLayerBuffer(DisplayId displayId) { - auto& hwcInfo = getBE().mHwcLayers[displayId]; - auto& hwcLayer = hwcInfo.layer; +void BufferStateLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) { + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc); + auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer; const State& s(getDrawingState()); diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 3320c5b5d5..a97f0a47fc 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -131,7 +131,7 @@ private: status_t updateActiveBuffer() override; status_t updateFrameNumber(nsecs_t latchTime) override; - void setHwcLayerBuffer(DisplayId displayId) override; + void setHwcLayerBuffer(const sp<const DisplayDevice>& display) override; private: void onFirstRef() override; diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index d82ff0eab3..9ea0a466a5 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -23,8 +23,12 @@ #include <sys/types.h> #include <compositionengine/CompositionEngine.h> +#include <compositionengine/Display.h> #include <compositionengine/Layer.h> #include <compositionengine/LayerCreationArgs.h> +#include <compositionengine/OutputLayer.h> +#include <compositionengine/impl/LayerCompositionState.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> #include <renderengine/RenderEngine.h> #include <ui/GraphicBuffer.h> #include <utils/Errors.h> @@ -73,30 +77,36 @@ bool ColorLayer::setColor(const half3& color) { return true; } -void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform, - const Rect& viewport, int32_t /* supportedPerFrameMetadata */) { - RETURN_IF_NO_HWC_LAYER(displayId); +void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& display, + const ui::Transform& transform, const Rect& viewport, + int32_t /* supportedPerFrameMetadata */) { + RETURN_IF_NO_HWC_LAYER(display); Region visible = transform.transform(visibleRegion.intersect(viewport)); - auto& hwcInfo = getBE().mHwcLayers[displayId]; - auto& hwcLayer = hwcInfo.layer; + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc); + + auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer; + auto error = hwcLayer->setVisibleRegion(visible); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), to_string(error).c_str(), static_cast<int32_t>(error)); visible.dump(LOG_TAG); } - getBE().compositionInfo.hwc.visibleRegion = visible; + outputLayer->editState().visibleRegion = visible; - setCompositionType(displayId, HWC2::Composition::SolidColor); + setCompositionType(display, Hwc2::IComposerClient::Composition::SOLID_COLOR); error = hwcLayer->setDataspace(mCurrentDataSpace); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace, to_string(error).c_str(), static_cast<int32_t>(error)); } - getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace; + + auto& layerCompositionState = getCompositionLayer()->editState().frontEnd; + layerCompositionState.dataspace = mCurrentDataSpace; half4 color = getColor(); error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)), @@ -106,9 +116,9 @@ void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& trans ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), static_cast<int32_t>(error)); } - getBE().compositionInfo.hwc.color = { static_cast<uint8_t>(std::round(255.0f * color.r)), - static_cast<uint8_t>(std::round(255.0f * color.g)), - static_cast<uint8_t>(std::round(255.0f * color.b)), 255 }; + layerCompositionState.color = {static_cast<uint8_t>(std::round(255.0f * color.r)), + static_cast<uint8_t>(std::round(255.0f * color.g)), + static_cast<uint8_t>(std::round(255.0f * color.b)), 255}; // Clear out the transform, because it doesn't make sense absent a source buffer error = hwcLayer->setTransform(HWC2::Transform::None); @@ -116,14 +126,14 @@ void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& trans ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(), static_cast<int32_t>(error)); } - getBE().compositionInfo.hwc.transform = HWC2::Transform::None; + outputLayer->editState().bufferTransform = static_cast<Hwc2::Transform>(0); error = hwcLayer->setColorTransform(getColorTransform()); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to setColorTransform: %s (%d)", mName.string(), to_string(error).c_str(), static_cast<int32_t>(error)); } - getBE().compositionInfo.hwc.colorTransform = getColorTransform(); + layerCompositionState.colorTransform = getColorTransform(); error = hwcLayer->setSurfaceDamage(surfaceDamageRegion); if (error != HWC2::Error::None) { @@ -131,7 +141,7 @@ void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& trans to_string(error).c_str(), static_cast<int32_t>(error)); surfaceDamageRegion.dump(LOG_TAG); } - getBE().compositionInfo.hwc.surfaceDamage = surfaceDamageRegion; + layerCompositionState.surfaceDamage = surfaceDamageRegion; } std::shared_ptr<compositionengine::Layer> ColorLayer::getCompositionLayer() const { diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index ed4c2d8208..df0adac1dd 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -35,8 +35,8 @@ public: bool setColor(const half3& color) override; - void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport, - int32_t supportedPerFrameMetadata) override; + void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform, + const Rect& viewport, int32_t supportedPerFrameMetadata) override; bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; } diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp index ce6b06c0c7..f5376a59b9 100644 --- a/services/surfaceflinger/CompositionEngine/Android.bp +++ b/services/surfaceflinger/CompositionEngine/Android.bp @@ -5,6 +5,7 @@ cc_defaults { "-DLOG_TAG=\"CompositionEngine\"", ], shared_libs: [ + "android.frameworks.vr.composer@1.0", "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.composer@2.1", "android.hardware.graphics.composer@2.2", @@ -28,6 +29,9 @@ cc_defaults { "libtrace_proto", ], header_libs: [ + "android.hardware.graphics.composer@2.1-command-buffer", + "android.hardware.graphics.composer@2.2-command-buffer", + "android.hardware.graphics.composer@2.3-command-buffer", "libsurfaceflinger_headers", ], } @@ -43,9 +47,11 @@ cc_library { "src/DumpHelpers.cpp", "src/HwcBufferCache.cpp", "src/Layer.cpp", + "src/LayerCompositionState.cpp", "src/Output.cpp", "src/OutputCompositionState.cpp", "src/OutputLayer.cpp", + "src/OutputLayerCompositionState.cpp", "src/RenderSurface.cpp", ], local_include_dirs: ["include"], diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Layer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Layer.h index 29a7deafce..8cb92034f6 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Layer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Layer.h @@ -17,6 +17,7 @@ #pragma once #include <cstdint> +#include <string> #include <utils/StrongPointer.h> @@ -29,6 +30,10 @@ namespace compositionengine { class Display; class LayerFE; +namespace impl { +struct LayerCompositionState; +} // namespace impl + /** * A layer contains the output-independent composition state for a front-end * Layer @@ -40,6 +45,21 @@ public: // Gets the front-end interface for this layer. Can return nullptr if the // front-end layer no longer exists. virtual sp<LayerFE> getLayerFE() const = 0; + + using CompositionState = impl::LayerCompositionState; + + // Gets the raw composition state data for the layer + // TODO(lpique): Make this protected once it is only internally called. + virtual const CompositionState& getState() const = 0; + + // Allows mutable access to the raw composition state data for the layer. + // This is meant to be used by the various functions that are part of the + // composition process. + // TODO(lpique): Make this protected once it is only internally called. + virtual CompositionState& editState() = 0; + + // Debugging + virtual void dump(std::string& result) const = 0; }; } // namespace compositionengine diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h new file mode 100644 index 0000000000..2201bdd6d2 --- /dev/null +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h @@ -0,0 +1,92 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <cstdint> + +#include <gui/BufferQueue.h> +#include <gui/HdrMetadata.h> +#include <math/mat4.h> +#include <ui/FloatRect.h> +#include <ui/GraphicBuffer.h> +#include <ui/GraphicTypes.h> +#include <ui/Rect.h> +#include <ui/Region.h> +#include <ui/Transform.h> + +#include "DisplayHardware/ComposerHal.h" + +namespace android::compositionengine { + +/* + * Used by LayerFE::getCompositionState + */ +struct LayerFECompositionState { + /* + * Presentation + */ + + // The blend mode for this layer + Hwc2::IComposerClient::BlendMode blendMode{Hwc2::IComposerClient::BlendMode::INVALID}; + + // The alpha value for this layer + float alpha{1.f}; + + /* + * Extra metadata + */ + + // The type for this layer + int type{0}; + + // The appId for this layer + int appId{0}; + + /* + * Per-frame content + */ + + // The type of composition for this layer + Hwc2::IComposerClient::Composition compositionType{Hwc2::IComposerClient::Composition::INVALID}; + + // The buffer and related state + sp<GraphicBuffer> buffer; + int bufferSlot{BufferQueue::INVALID_BUFFER_SLOT}; + sp<Fence> acquireFence; + Region surfaceDamage; + + // The handle to use for a sideband stream for this layer + sp<NativeHandle> sidebandStream; + + // The color for this layer + Hwc2::IComposerClient::Color color; + + /* + * Per-frame presentation state + */ + + // The dataspace for this layer + ui::Dataspace dataspace{ui::Dataspace::UNKNOWN}; + + // The metadata for this layer + HdrMetadata hdrMetadata; + + // The color transform + mat4 colorTransform; +}; + +} // namespace android::compositionengine diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h index 4b8ef38059..48cb581ccd 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h @@ -16,14 +16,22 @@ #pragma once +#include <string> + #include <utils/StrongPointer.h> -namespace android::compositionengine { +namespace android { + +namespace compositionengine { class Output; class Layer; class LayerFE; +namespace impl { +struct OutputLayerCompositionState; +} // namespace impl + /** * An output layer contains the output-dependent composition state for a layer */ @@ -39,6 +47,22 @@ public: // Gets the front-end layer interface this output layer represents virtual LayerFE& getLayerFE() const = 0; + + using CompositionState = compositionengine::impl::OutputLayerCompositionState; + + // Gets the raw composition state data for the layer + // TODO(lpique): Make this protected once it is only internally called. + virtual const CompositionState& getState() const = 0; + + // Allows mutable access to the raw composition state data for the layer. + // This is meant to be used by the various functions that are part of the + // composition process. + // TODO(lpique): Make this protected once it is only internally called. + virtual CompositionState& editState() = 0; + + // Debugging + virtual void dump(std::string& result) const = 0; }; -} // namespace android::compositionengine +} // namespace compositionengine +} // namespace android diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h index ddeb7304a8..20093808cb 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h @@ -29,8 +29,6 @@ namespace android { class GraphicBuffer; -struct CompositionInfo; - namespace compositionengine { /** @@ -70,7 +68,7 @@ public: virtual status_t beginFrame(bool mustRecompose) = 0; // Prepares the frame for rendering - virtual status_t prepareFrame(std::vector<CompositionInfo>& compositionData) = 0; + virtual status_t prepareFrame() = 0; // Allocates a buffer as scratch space for GPU composition virtual sp<GraphicBuffer> dequeueBuffer() = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h index 631351b857..3e56b21b18 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h @@ -19,6 +19,7 @@ #include <memory> #include <compositionengine/Layer.h> +#include <compositionengine/impl/LayerCompositionState.h> #include <utils/RefBase.h> #include <utils/StrongPointer.h> @@ -40,9 +41,16 @@ public: sp<LayerFE> getLayerFE() const override; + const LayerCompositionState& getState() const override; + LayerCompositionState& editState() override; + + void dump(std::string& result) const override; + private: const compositionengine::CompositionEngine& mCompositionEngine; const wp<LayerFE> mLayerFE; + + LayerCompositionState mState; }; std::shared_ptr<compositionengine::Layer> createLayer(const compositionengine::CompositionEngine&, diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/LayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/LayerCompositionState.h new file mode 100644 index 0000000000..67bea4bc14 --- /dev/null +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/LayerCompositionState.h @@ -0,0 +1,47 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <cstdint> +#include <string> + +#include <compositionengine/LayerFECompositionState.h> +#include <renderengine/Mesh.h> + +namespace android { + +namespace compositionengine::impl { + +struct LayerCompositionState { + /* + * State intended to be set by LayerFE::getCompositionState + */ + + LayerFECompositionState frontEnd; + + /* + * RE state + */ + + renderengine::Mesh reMesh{renderengine::Mesh::TRIANGLE_FAN, 4, 2, 2}; + + // Debugging + void dump(std::string& result) const; +}; + +} // namespace compositionengine::impl +} // namespace android diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h index f3d02584b0..5798540792 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h @@ -17,8 +17,10 @@ #pragma once #include <memory> +#include <string> #include <compositionengine/OutputLayer.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> namespace android::compositionengine::impl { @@ -32,10 +34,17 @@ public: compositionengine::Layer& getLayer() const override; compositionengine::LayerFE& getLayerFE() const override; + const OutputLayerCompositionState& getState() const override; + OutputLayerCompositionState& editState() override; + + void dump(std::string& result) const override; + private: const compositionengine::Output& mOutput; std::shared_ptr<compositionengine::Layer> mLayer; sp<compositionengine::LayerFE> mLayerFE; + + OutputLayerCompositionState mState; }; std::unique_ptr<compositionengine::OutputLayer> createOutputLayer( diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h new file mode 100644 index 0000000000..b78e9e0076 --- /dev/null +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h @@ -0,0 +1,91 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <cstdint> +#include <optional> +#include <string> + +#include <compositionengine/impl/HwcBufferCache.h> +#include <renderengine/Mesh.h> +#include <ui/FloatRect.h> +#include <ui/Rect.h> +#include <ui/Region.h> + +#include "DisplayHardware/ComposerHal.h" + +namespace HWC2 { +class Layer; +} // namespace HWC2 + +namespace android { + +class HWComposer; + +namespace compositionengine::impl { + +struct OutputLayerCompositionState { + // The region of this layer which is visible on this output + Region visibleRegion; + + // If true, client composition will be used on this output + bool forceClientComposition{false}; + + // If true, when doing client composition, the target may need to be cleared + bool clearClientTarget{false}; + + // The display frame for this layer on this output + Rect displayFrame; + + // The source crop for this layer on this output + FloatRect sourceCrop; + + // The buffer transform to use for this layer o on this output. + Hwc2::Transform bufferTransform{static_cast<Hwc2::Transform>(0)}; + + // The Z order index of this layer on this output + uint32_t z; + + /* + * HWC state + */ + + struct Hwc { + explicit Hwc(std::shared_ptr<HWC2::Layer> hwcLayer) : hwcLayer(hwcLayer) {} + + // The HWC Layer backing this layer + std::shared_ptr<HWC2::Layer> hwcLayer; + + // The HWC composition type for this layer + Hwc2::IComposerClient::Composition hwcCompositionType{ + Hwc2::IComposerClient::Composition::INVALID}; + + // The buffer cache for this layer. This is used to lower the + // cost of sending reused buffers to the HWC. + HwcBufferCache hwcBufferCache; + }; + + // The HWC state is optional, and is only set up if there is any potential + // HWC acceleration possible. + std::optional<Hwc> hwc; + + // Debugging + void dump(std::string& result) const; +}; + +} // namespace compositionengine::impl +} // namespace android diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h index 2f0fceb387..58b13ed603 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h @@ -51,7 +51,7 @@ public: void setDisplaySize(const ui::Size&) override; void setProtected(bool useProtected) override; status_t beginFrame(bool mustRecompose) override; - status_t prepareFrame(std::vector<CompositionInfo>& compositionData) override; + status_t prepareFrame() override; sp<GraphicBuffer> dequeueBuffer() override; void queueBuffer(base::unique_fd&& readyFence) override; void onPresentDisplayCompleted() override; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Layer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Layer.h index a7cc08e117..cce3b97bbd 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Layer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Layer.h @@ -18,6 +18,7 @@ #include <compositionengine/Layer.h> #include <compositionengine/LayerFE.h> +#include <compositionengine/impl/LayerCompositionState.h> #include <gmock/gmock.h> namespace android::compositionengine::mock { @@ -28,6 +29,11 @@ public: virtual ~Layer(); MOCK_CONST_METHOD0(getLayerFE, sp<LayerFE>()); + + MOCK_CONST_METHOD0(getState, const CompositionState&()); + MOCK_METHOD0(editState, CompositionState&()); + + MOCK_CONST_METHOD1(dump, void(std::string&)); }; } // namespace android::compositionengine::mock diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h index f5e5026203..6bd61ee795 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h @@ -20,6 +20,7 @@ #include <compositionengine/LayerFE.h> #include <compositionengine/Output.h> #include <compositionengine/OutputLayer.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> #include <gmock/gmock.h> namespace android::compositionengine::mock { @@ -32,6 +33,11 @@ public: MOCK_CONST_METHOD0(getOutput, const compositionengine::Output&()); MOCK_CONST_METHOD0(getLayer, compositionengine::Layer&()); MOCK_CONST_METHOD0(getLayerFE, compositionengine::LayerFE&()); + + MOCK_CONST_METHOD0(getState, const impl::OutputLayerCompositionState&()); + MOCK_METHOD0(editState, impl::OutputLayerCompositionState&()); + + MOCK_CONST_METHOD1(dump, void(std::string&)); }; } // namespace android::compositionengine::mock diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h index e9ff330482..8442bef6fc 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h @@ -20,7 +20,6 @@ #include <gmock/gmock.h> #include <ui/GraphicBuffer.h> -#include "LayerBE.h" namespace android::compositionengine::mock { @@ -37,7 +36,7 @@ public: MOCK_METHOD1(setProtected, void(bool)); MOCK_METHOD1(setBufferDataspace, void(ui::Dataspace)); MOCK_METHOD1(beginFrame, status_t(bool mustRecompose)); - MOCK_METHOD1(prepareFrame, status_t(std::vector<CompositionInfo>& compositionData)); + MOCK_METHOD0(prepareFrame, status_t()); MOCK_METHOD0(dequeueBuffer, sp<GraphicBuffer>()); MOCK_METHOD1(queueBuffer, void(base::unique_fd&&)); MOCK_METHOD0(onPresentDisplayCompleted, void()); diff --git a/services/surfaceflinger/CompositionEngine/src/Layer.cpp b/services/surfaceflinger/CompositionEngine/src/Layer.cpp index aaa758ea6f..109e9f8438 100644 --- a/services/surfaceflinger/CompositionEngine/src/Layer.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Layer.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <android-base/stringprintf.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/LayerCreationArgs.h> #include <compositionengine/LayerFE.h> @@ -42,5 +43,18 @@ sp<LayerFE> Layer::getLayerFE() const { return mLayerFE.promote(); } +const LayerCompositionState& Layer::getState() const { + return mState; +} + +LayerCompositionState& Layer::editState() { + return mState; +} + +void Layer::dump(std::string& out) const { + android::base::StringAppendF(&out, " Layer %p\n", this); + mState.dump(out); +} + } // namespace impl } // namespace android::compositionengine diff --git a/services/surfaceflinger/CompositionEngine/src/LayerCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerCompositionState.cpp new file mode 100644 index 0000000000..517b641594 --- /dev/null +++ b/services/surfaceflinger/CompositionEngine/src/LayerCompositionState.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/stringprintf.h> +#include <compositionengine/impl/DumpHelpers.h> +#include <compositionengine/impl/LayerCompositionState.h> + +namespace android::compositionengine::impl { + +namespace { + +using android::compositionengine::impl::dumpVal; + +void dumpVal(std::string& out, const char* name, Hwc2::IComposerClient::Color value) { + using android::base::StringAppendF; + StringAppendF(&out, "%s=[%d %d %d] ", name, value.r, value.g, value.b); +} + +void dumpFrontEnd(std::string& out, const LayerFECompositionState& state) { + out.append(" "); + dumpVal(out, "blend", toString(state.blendMode), state.blendMode); + dumpVal(out, "alpha", state.alpha); + + out.append("\n "); + dumpVal(out, "type", state.type); + dumpVal(out, "appId", state.appId); + + dumpVal(out, "composition type", toString(state.compositionType), state.compositionType); + + out.append("\n buffer: "); + dumpVal(out, "buffer", state.buffer.get()); + dumpVal(out, "slot", state.bufferSlot); + + out.append("\n "); + dumpVal(out, "sideband stream", state.sidebandStream.get()); + + out.append("\n "); + dumpVal(out, "color", state.color); + + out.append("\n "); + dumpVal(out, "dataspace", toString(state.dataspace), state.dataspace); + dumpVal(out, "hdr metadata types", state.hdrMetadata.validTypes); + dumpVal(out, "colorTransform", state.colorTransform); + + out.append("\n"); +} + +} // namespace + +void LayerCompositionState::dump(std::string& out) const { + out.append(" frontend:\n"); + dumpFrontEnd(out, frontEnd); +} + +} // namespace android::compositionengine::impl diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index e103ebee73..f97add4f17 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -146,6 +146,14 @@ void Output::dumpBase(std::string& out) const { } else { out.append(" No render surface!\n"); } + + out.append("\n %d Layers", mOutputLayersOrderedByZ.size()); + for (const auto& outputLayer : mOutputLayersOrderedByZ) { + if (!outputLayer) { + continue; + } + outputLayer->dump(out); + } } compositionengine::DisplayColorProfile* Output::getDisplayColorProfile() const { diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp index e95f3a6d30..78c140316e 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <android-base/stringprintf.h> #include <compositionengine/Layer.h> #include <compositionengine/LayerFE.h> #include <compositionengine/Output.h> @@ -48,5 +49,20 @@ compositionengine::LayerFE& OutputLayer::getLayerFE() const { return *mLayerFE; } +const OutputLayerCompositionState& OutputLayer::getState() const { + return mState; +} + +OutputLayerCompositionState& OutputLayer::editState() { + return mState; +} + +void OutputLayer::dump(std::string& out) const { + using android::base::StringAppendF; + + StringAppendF(&out, " Output Layer %p\n", this); + mState.dump(out); +} + } // namespace impl } // namespace android::compositionengine diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp new file mode 100644 index 0000000000..10f27b86f9 --- /dev/null +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <compositionengine/impl/DumpHelpers.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> + +#include "DisplayHardware/HWC2.h" + +namespace android::compositionengine::impl { + +namespace { + +void dumpHwc(const OutputLayerCompositionState::Hwc& hwc, std::string& out) { + out.append("\n hwc: "); + + if (hwc.hwcLayer == nullptr) { + out.append("No layer "); + } else { + dumpHex(out, "layer", hwc.hwcLayer->getId()); + } + + dumpVal(out, "composition", toString(hwc.hwcCompositionType), hwc.hwcCompositionType); +} + +} // namespace + +void OutputLayerCompositionState::dump(std::string& out) const { + out.append(" "); + dumpVal(out, "visibleRegion", visibleRegion); + + out.append(" "); + dumpVal(out, "forceClientComposition", forceClientComposition); + dumpVal(out, "clearClientTarget", clearClientTarget); + dumpVal(out, "displayFrame", displayFrame); + dumpVal(out, "sourceCrop", sourceCrop); + dumpVal(out, "bufferTransform%", toString(bufferTransform), bufferTransform); + dumpVal(out, "z-index", z); + + if (hwc) { + dumpHwc(*hwc, out); + } + + out.append("\n"); +} + +} // namespace android::compositionengine::impl diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp index 3f841d241b..ebb1bc2e5b 100644 --- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp +++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp @@ -99,11 +99,11 @@ status_t RenderSurface::beginFrame(bool mustRecompose) { return mDisplaySurface->beginFrame(mustRecompose); } -status_t RenderSurface::prepareFrame(std::vector<CompositionInfo>& compositionData) { +status_t RenderSurface::prepareFrame() { auto& hwc = mCompositionEngine.getHwComposer(); const auto id = mDisplay.getId(); if (id) { - status_t error = hwc.prepare(*id, compositionData); + status_t error = hwc.prepare(*id, mDisplay); if (error != NO_ERROR) { return error; } diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h index ece412f5ec..885cdd4ec4 100644 --- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h @@ -16,10 +16,9 @@ #pragma once +#include <compositionengine/Output.h> #include <gmock/gmock.h> -#include "LayerBE.h" - #include "DisplayHardware/HWComposer.h" namespace android { @@ -41,7 +40,7 @@ public: std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*)); MOCK_METHOD1(createLayer, HWC2::Layer*(DisplayId)); MOCK_METHOD2(destroyLayer, void(DisplayId, HWC2::Layer*)); - MOCK_METHOD2(prepare, status_t(DisplayId, std::vector<CompositionInfo>&)); + MOCK_METHOD2(prepare, status_t(DisplayId, const compositionengine::Output&)); MOCK_METHOD5(setClientTarget, status_t(DisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&, ui::Dataspace)); diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp index c56d92a067..0a7c46254a 100644 --- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp @@ -22,6 +22,7 @@ #include <compositionengine/mock/CompositionEngine.h> #include <compositionengine/mock/Display.h> #include <compositionengine/mock/DisplaySurface.h> +#include <compositionengine/mock/OutputLayer.h> #include <gtest/gtest.h> #include <renderengine/mock/RenderEngine.h> #include <system/window.h> @@ -284,64 +285,66 @@ TEST_F(RenderSurfaceTest, beginFrameAppliesChange) { * RenderSurface::prepareFrame() */ -TEST_F(RenderSurfaceTest, prepareFrameTakesEarlyOutOnHwcError) { - std::vector<CompositionInfo> data; +TEST_F(RenderSurfaceTest, prepareFramePassesOutputLayersToHwc) { + EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay))) + .WillOnce(Return(INVALID_OPERATION)); + + EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame()); +} - EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))) +TEST_F(RenderSurfaceTest, prepareFrameTakesEarlyOutOnHwcError) { + EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay))) .WillOnce(Return(INVALID_OPERATION)); - EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame(data)); + EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame()); } TEST_F(RenderSurfaceTest, prepareFrameHandlesMixedComposition) { - std::vector<CompositionInfo> data; - EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay))) + .WillOnce(Return(NO_ERROR)); EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true)); EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true)); EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_MIXED)) .WillOnce(Return(INVALID_OPERATION)); - EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame(data)); + EXPECT_EQ(INVALID_OPERATION, mSurface.prepareFrame()); } TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyGlesComposition) { - std::vector<CompositionInfo> data; - - EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay))) + .WillOnce(Return(NO_ERROR)); EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true)); EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false)); EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_GLES)) .WillOnce(Return(NO_ERROR)); - EXPECT_EQ(NO_ERROR, mSurface.prepareFrame(data)); + EXPECT_EQ(NO_ERROR, mSurface.prepareFrame()); } TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyHwcComposition) { - std::vector<CompositionInfo> data; - - EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay))) + .WillOnce(Return(NO_ERROR)); EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false)); EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(true)); EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC)) .WillOnce(Return(NO_ERROR)); - EXPECT_EQ(NO_ERROR, mSurface.prepareFrame(data)); + EXPECT_EQ(NO_ERROR, mSurface.prepareFrame()); } TEST_F(RenderSurfaceTest, prepareFrameHandlesNoComposition) { - std::vector<CompositionInfo> data; - - EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(data))).WillOnce(Return(NO_ERROR)); + EXPECT_CALL(mHwComposer, prepare(*DEFAULT_DISPLAY_ID, Ref(mDisplay))) + .WillOnce(Return(NO_ERROR)); EXPECT_CALL(mHwComposer, hasClientComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false)); EXPECT_CALL(mHwComposer, hasDeviceComposition(DEFAULT_DISPLAY_ID)).WillOnce(Return(false)); EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC)) .WillOnce(Return(NO_ERROR)); - EXPECT_EQ(NO_ERROR, mSurface.prepareFrame(data)); + EXPECT_EQ(NO_ERROR, mSurface.prepareFrame()); } /* ------------------------------------------------------------------------ diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp index 941b4ad53b..22c40d79a0 100644 --- a/services/surfaceflinger/ContainerLayer.cpp +++ b/services/surfaceflinger/ContainerLayer.cpp @@ -39,6 +39,7 @@ bool ContainerLayer::canReceiveInput() const { return !isHiddenByPolicy(); } -void ContainerLayer::setPerFrameData(DisplayId, const ui::Transform&, const Rect&, int32_t) {} +void ContainerLayer::setPerFrameData(const sp<const DisplayDevice>&, const ui::Transform&, + const Rect&, int32_t) {} } // namespace android diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h index fec82d7a71..c69997dd3b 100644 --- a/services/surfaceflinger/ContainerLayer.h +++ b/services/surfaceflinger/ContainerLayer.h @@ -33,8 +33,8 @@ public: bool canReceiveInput() const override; - void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport, - int32_t supportedPerFrameMetadata) override; + void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform, + const Rect& viewport, int32_t supportedPerFrameMetadata) override; bool isCreatedFromMainThread() const override { return true; } diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 9674f0db3d..a827c47ba9 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -266,6 +266,7 @@ public: int getHeight() const override { return mDevice->getHeight(); } int getWidth() const override { return mDevice->getWidth(); } bool isSecure() const override { return mDevice->isSecure(); } + const sp<const DisplayDevice> getDisplayDevice() const override { return mDevice; } bool needsFiltering() const override { // check if the projection from the logical display to the physical diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 5b4d347aae..3b9e0e6c83 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -20,13 +20,14 @@ #define LOG_TAG "HWComposer" #define ATRACE_TAG ATRACE_TAG_GRAPHICS -#include <utils/Errors.h> -#include <utils/Trace.h> - +#include <compositionengine/Output.h> +#include <compositionengine/OutputLayer.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> +#include <log/log.h> #include <ui/DebugUtils.h> #include <ui/GraphicBuffer.h> - -#include <log/log.h> +#include <utils/Errors.h> +#include <utils/Trace.h> #include "HWComposer.h" #include "HWC2.h" @@ -398,7 +399,7 @@ status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot, return NO_ERROR; } -status_t HWComposer::prepare(DisplayId displayId, std::vector<CompositionInfo>& compositionData) { +status_t HWComposer::prepare(DisplayId displayId, const compositionengine::Output& output) { ATRACE_CALL(); RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); @@ -462,47 +463,42 @@ status_t HWComposer::prepare(DisplayId displayId, std::vector<CompositionInfo>& displayData.hasClientComposition = false; displayData.hasDeviceComposition = false; - for (auto& compositionInfo : compositionData) { - auto hwcLayer = compositionInfo.hwc.hwcLayer; - - if (changedTypes.count(&*hwcLayer) != 0) { - // We pass false so we only update our state and don't call back - // into the HWC device - validateChange(compositionInfo.compositionType, - changedTypes[&*hwcLayer]); - compositionInfo.compositionType = changedTypes[&*hwcLayer]; - compositionInfo.layer->mLayer->setCompositionType(displayId, - compositionInfo.compositionType, - false); + for (auto& outputLayer : output.getOutputLayersOrderedByZ()) { + auto& state = outputLayer->editState(); + LOG_FATAL_IF(!state.hwc.); + auto hwcLayer = (*state.hwc).hwcLayer; + + if (auto it = changedTypes.find(hwcLayer.get()); it != changedTypes.end()) { + auto newCompositionType = it->second; + validateChange(static_cast<HWC2::Composition>((*state.hwc).hwcCompositionType), + newCompositionType); + (*state.hwc).hwcCompositionType = + static_cast<Hwc2::IComposerClient::Composition>(newCompositionType); } - switch (compositionInfo.compositionType) { - case HWC2::Composition::Client: + switch ((*state.hwc).hwcCompositionType) { + case Hwc2::IComposerClient::Composition::CLIENT: displayData.hasClientComposition = true; break; - case HWC2::Composition::Device: - case HWC2::Composition::SolidColor: - case HWC2::Composition::Cursor: - case HWC2::Composition::Sideband: + case Hwc2::IComposerClient::Composition::DEVICE: + case Hwc2::IComposerClient::Composition::SOLID_COLOR: + case Hwc2::IComposerClient::Composition::CURSOR: + case Hwc2::IComposerClient::Composition::SIDEBAND: displayData.hasDeviceComposition = true; break; default: break; } - if (layerRequests.count(&*hwcLayer) != 0 && - layerRequests[&*hwcLayer] == - HWC2::LayerRequest::ClearClientTarget) { - compositionInfo.hwc.clearClientTarget = true; - compositionInfo.layer->mLayer->setClearClientTarget(displayId, true); - } else { - if (layerRequests.count(&*hwcLayer) != 0) { + state.clearClientTarget = false; + if (auto it = layerRequests.find(hwcLayer.get()); it != layerRequests.end()) { + auto request = it->second; + if (request == HWC2::LayerRequest::ClearClientTarget) { + state.clearClientTarget = true; + } else { LOG_DISPLAY_ERROR(displayId, - ("Unknown layer request " + to_string(layerRequests[&*hwcLayer])) - .c_str()); + ("Unknown layer request " + to_string(request)).c_str()); } - compositionInfo.hwc.clearClientTarget = false; - compositionInfo.layer->mLayer->setClearClientTarget(displayId, false); } } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index f42f860ab9..ca59a2645a 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -45,6 +45,10 @@ namespace Hwc2 { class Composer; } // namespace Hwc2 +namespace compositionengine { +class Output; +} // namespace compositionengine + class HWComposer { public: virtual ~HWComposer(); @@ -68,8 +72,7 @@ public: virtual void destroyLayer(DisplayId displayId, HWC2::Layer* layer) = 0; // Asks the HAL what it can do - virtual status_t prepare(DisplayId displayId, - std::vector<CompositionInfo>& compositionData) = 0; + virtual status_t prepare(DisplayId displayId, const compositionengine::Output&) = 0; virtual status_t setClientTarget(DisplayId displayId, uint32_t slot, const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target, @@ -205,7 +208,7 @@ public: void destroyLayer(DisplayId displayId, HWC2::Layer* layer) override; // Asks the HAL what it can do - status_t prepare(DisplayId displayId, std::vector<CompositionInfo>& compositionData) override; + status_t prepare(DisplayId displayId, const compositionengine::Output&) override; status_t setClientTarget(DisplayId displayId, uint32_t slot, const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target, ui::Dataspace dataspace) override; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 51e1f006fb..7b8ad7129a 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -24,44 +24,42 @@ #include <stdlib.h> #include <sys/types.h> #include <algorithm> +#include <mutex> #include <android-base/stringprintf.h> - +#include <compositionengine/Display.h> +#include <compositionengine/Layer.h> +#include <compositionengine/OutputLayer.h> +#include <compositionengine/impl/LayerCompositionState.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> #include <cutils/compiler.h> #include <cutils/native_handle.h> #include <cutils/properties.h> - +#include <gui/BufferItem.h> +#include <gui/LayerDebugInfo.h> +#include <gui/Surface.h> +#include <renderengine/RenderEngine.h> +#include <ui/DebugUtils.h> +#include <ui/GraphicBuffer.h> +#include <ui/PixelFormat.h> #include <utils/Errors.h> #include <utils/Log.h> #include <utils/NativeHandle.h> #include <utils/StopWatch.h> #include <utils/Trace.h> -#include <ui/DebugUtils.h> -#include <ui/GraphicBuffer.h> -#include <ui/PixelFormat.h> - -#include <gui/BufferItem.h> -#include <gui/LayerDebugInfo.h> -#include <gui/Surface.h> - #include "BufferLayer.h" #include "ColorLayer.h" #include "Colorizer.h" #include "DisplayDevice.h" +#include "DisplayHardware/HWComposer.h" #include "Layer.h" +#include "LayerProtoHelper.h" #include "LayerRejecter.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" - -#include "DisplayHardware/HWComposer.h" #include "TimeStats/TimeStats.h" -#include <renderengine/RenderEngine.h> - -#include <mutex> -#include "LayerProtoHelper.h" - #define DEBUG_RESIZE 0 namespace android { @@ -211,9 +209,16 @@ sp<IBinder> Layer::getHandle() { // h/w composer set-up // --------------------------------------------------------------------------- -bool Layer::createHwcLayer(HWComposer* hwc, DisplayId displayId) { - LOG_ALWAYS_FATAL_IF(hasHwcLayer(displayId), "Already have a layer for display %s", - to_string(displayId).c_str()); +bool Layer::createHwcLayer(HWComposer* hwc, const sp<DisplayDevice>& displayDevice) { + LOG_ALWAYS_FATAL_IF(!displayDevice->getId()); + auto displayId = *displayDevice->getId(); + auto outputLayer = findOutputLayerForDisplay(displayDevice); + LOG_ALWAYS_FATAL_IF(!outputLayer); + + LOG_ALWAYS_FATAL_IF(outputLayer->getState().hwc.has_value(), + "Already have a layer for display %s", + displayDevice->getDisplayName().c_str()); + auto layer = std::shared_ptr<HWC2::Layer>( hwc->createLayer(displayId), [hwc, displayId](HWC2::Layer* layer) { @@ -221,42 +226,56 @@ bool Layer::createHwcLayer(HWComposer* hwc, DisplayId displayId) { if (!layer) { return false; } - LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers[displayId]; - hwcInfo.hwc = hwc; - hwcInfo.layer = layer; - layer->setLayerDestroyedListener( - [this, displayId](HWC2::Layer* /*layer*/) { getBE().mHwcLayers.erase(displayId); }); + auto& state = outputLayer->editState(); + state.hwc.emplace(layer); return true; } -bool Layer::destroyHwcLayer(DisplayId displayId) { - if (!hasHwcLayer(displayId)) { +bool Layer::destroyHwcLayer(const sp<DisplayDevice>& displayDevice) { + auto outputLayer = findOutputLayerForDisplay(displayDevice); + if (outputLayer == nullptr) { return false; } - auto& hwcInfo = getBE().mHwcLayers[displayId]; - LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer"); - LOG_ALWAYS_FATAL_IF(hwcInfo.hwc == nullptr, "Missing HWComposer"); - hwcInfo.layer = nullptr; - - return true; + auto& state = outputLayer->editState(); + bool result = state.hwc.has_value(); + state.hwc.reset(); + return result; } -void Layer::destroyHwcLayersForAllDisplays() { - size_t numLayers = getBE().mHwcLayers.size(); - for (size_t i = 0; i < numLayers; ++i) { - LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.empty(), "destroyAllHwcLayers failed"); - destroyHwcLayer(getBE().mHwcLayers.begin()->first); +bool Layer::destroyHwcLayersForAllDisplays() { + bool destroyedAnyLayers = false; + + for (const auto& [token, displayDevice] : mFlinger->mDisplays) { + if (destroyHwcLayer(displayDevice)) { + destroyedAnyLayers = true; + } } + + return destroyedAnyLayers; } -void Layer::destroyAllHwcLayersPlusChildren() { - destroyHwcLayersForAllDisplays(); - LOG_ALWAYS_FATAL_IF(!getBE().mHwcLayers.empty(), - "All hardware composer layers should have been destroyed"); +bool Layer::destroyAllHwcLayersPlusChildren() { + bool result = destroyHwcLayersForAllDisplays(); for (const sp<Layer>& child : mDrawingChildren) { - child->destroyAllHwcLayersPlusChildren(); + result |= child->destroyAllHwcLayersPlusChildren(); + } + + return result; +} + +bool Layer::hasHwcLayer(const sp<const DisplayDevice>& displayDevice) { + auto outputLayer = findOutputLayerForDisplay(displayDevice); + LOG_FATAL_IF(!outputLayer); + return outputLayer->getState().hwc && (*outputLayer->getState().hwc).hwcLayer != nullptr; +} + +HWC2::Layer* Layer::getHwcLayer(const sp<const DisplayDevice>& displayDevice) { + auto outputLayer = findOutputLayerForDisplay(displayDevice); + if (!outputLayer || !outputLayer->getState().hwc) { + return nullptr; } + return (*outputLayer->getState().hwc).hwcLayer.get(); } Rect Layer::getContentCrop() const { @@ -266,9 +285,9 @@ Rect Layer::getContentCrop() const { if (!mCurrentCrop.isEmpty()) { // if the buffer crop is defined, we use that crop = mCurrentCrop; - } else if (getBE().compositionInfo.mBuffer != nullptr) { + } else if (mActiveBuffer != nullptr) { // otherwise we use the whole buffer - crop = getBE().compositionInfo.mBuffer->getBounds(); + crop = mActiveBuffer->getBounds(); } else { // if we don't have a buffer yet, we use an empty/invalid crop crop.makeInvalid(); @@ -322,18 +341,18 @@ ui::Transform Layer::getTransformWithScale() const { // for in the transform. We need to mirror this scaling to child surfaces // or we will break the contract where WM can treat child surfaces as // pixels in the parent surface. - if (!isFixedSize() || !getBE().compositionInfo.mBuffer) { + if (!isFixedSize() || !mActiveBuffer) { return mEffectiveTransform; } int bufferWidth; int bufferHeight; if ((mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) == 0) { - bufferWidth = getBE().compositionInfo.mBuffer->getWidth(); - bufferHeight = getBE().compositionInfo.mBuffer->getHeight(); + bufferWidth = mActiveBuffer->getWidth(); + bufferHeight = mActiveBuffer->getHeight(); } else { - bufferHeight = getBE().compositionInfo.mBuffer->getWidth(); - bufferWidth = getBE().compositionInfo.mBuffer->getHeight(); + bufferHeight = mActiveBuffer->getWidth(); + bufferWidth = mActiveBuffer->getHeight(); } float sx = getActiveWidth(getDrawingState()) / static_cast<float>(bufferWidth); float sy = getActiveHeight(getDrawingState()) / static_cast<float>(bufferHeight); @@ -421,7 +440,8 @@ void Layer::setupRoundedCornersCropCoordinates(Rect win, win.top -= roundedCornersCrop.top; win.bottom -= roundedCornersCrop.top; - renderengine::Mesh::VertexArray<vec2> cropCoords(getBE().mMesh.getCropCoordArray<vec2>()); + renderengine::Mesh::VertexArray<vec2> cropCoords( + getCompositionLayer()->editState().reMesh.getCropCoordArray<vec2>()); cropCoords[0] = vec2(win.left, win.top); cropCoords[1] = vec2(win.left, win.top + win.getHeight()); cropCoords[2] = vec2(win.right, win.top + win.getHeight()); @@ -494,20 +514,28 @@ FloatRect Layer::computeCrop(const sp<const DisplayDevice>& display) const { } void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { - const auto displayId = display->getId(); - LOG_ALWAYS_FATAL_IF(!displayId); - RETURN_IF_NO_HWC_LAYER(*displayId); - auto& hwcInfo = getBE().mHwcLayers[*displayId]; + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer); + LOG_FATAL_IF(!outputLayer->getState().hwc); + auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer; + + if (!hasHwcLayer(display)) { + ALOGE("[%s] failed to setGeometry: no HWC layer found (%s)", mName.string(), + display->getDebugName().c_str()); + return; + } + + LOG_FATAL_IF(!getCompositionLayer()); + auto& commonCompositionState = getCompositionLayer()->editState().frontEnd; + auto& compositionState = outputLayer->editState(); // enable this layer - hwcInfo.forceClientComposition = false; + compositionState.forceClientComposition = false; if (isSecure() && !display->isSecure()) { - hwcInfo.forceClientComposition = true; + compositionState.forceClientComposition = true; } - auto& hwcLayer = hwcInfo.layer; - // this gives us only the "orientation" component of the transform const State& s(getDrawingState()); const Rect bufferSize = getBufferSize(s); @@ -522,7 +550,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { " %s (%d)", mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(), static_cast<int32_t>(error)); - getBE().compositionInfo.hwc.blendMode = blendMode; + commonCompositionState.blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode); // apply the layer's transform, followed by the display's global transform // here we're guaranteed that the layer's transform preserves rects @@ -567,9 +595,8 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { transformedFrame.left, transformedFrame.top, transformedFrame.right, transformedFrame.bottom, to_string(error).c_str(), static_cast<int32_t>(error)); } else { - hwcInfo.displayFrame = transformedFrame; + compositionState.displayFrame = transformedFrame; } - getBE().compositionInfo.hwc.displayFrame = transformedFrame; FloatRect sourceCrop = computeCrop(display); error = hwcLayer->setSourceCrop(sourceCrop); @@ -579,9 +606,8 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { mName.string(), sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom, to_string(error).c_str(), static_cast<int32_t>(error)); } else { - hwcInfo.sourceCrop = sourceCrop; + compositionState.sourceCrop = sourceCrop; } - getBE().compositionInfo.hwc.sourceCrop = sourceCrop; float alpha = static_cast<float>(getAlpha()); error = hwcLayer->setPlaneAlpha(alpha); @@ -589,12 +615,12 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { "[%s] Failed to set plane alpha %.3f: " "%s (%d)", mName.string(), alpha, to_string(error).c_str(), static_cast<int32_t>(error)); - getBE().compositionInfo.hwc.alpha = alpha; + commonCompositionState.alpha = alpha; error = hwcLayer->setZOrder(z); ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z, to_string(error).c_str(), static_cast<int32_t>(error)); - getBE().compositionInfo.hwc.z = z; + compositionState.z = z; int type = s.metadata.getInt32(METADATA_WINDOW_TYPE, 0); int appId = s.metadata.getInt32(METADATA_OWNER_UID, 0); @@ -613,8 +639,8 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(), static_cast<int32_t>(error)); - getBE().compositionInfo.hwc.type = type; - getBE().compositionInfo.hwc.appId = appId; + commonCompositionState.type = type; + commonCompositionState.appId = appId; /* * Transformations are applied in this order: @@ -651,35 +677,39 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { const uint32_t orientation = transform.getOrientation(); if (orientation & ui::Transform::ROT_INVALID) { // we can only handle simple transformation - hwcInfo.forceClientComposition = true; - getBE().mHwcLayers[*displayId].compositionType = HWC2::Composition::Client; + compositionState.forceClientComposition = true; + (*compositionState.hwc).hwcCompositionType = Hwc2::IComposerClient::Composition::CLIENT; } else { auto transform = static_cast<HWC2::Transform>(orientation); - hwcInfo.transform = transform; auto error = hwcLayer->setTransform(transform); ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: " "%s (%d)", mName.string(), to_string(transform).c_str(), to_string(error).c_str(), static_cast<int32_t>(error)); - getBE().compositionInfo.hwc.transform = transform; + compositionState.bufferTransform = static_cast<Hwc2::Transform>(transform); } } -void Layer::forceClientComposition(DisplayId displayId) { - RETURN_IF_NO_HWC_LAYER(displayId); - getBE().mHwcLayers[displayId].forceClientComposition = true; +void Layer::forceClientComposition(const sp<DisplayDevice>& display) { + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer); + outputLayer->editState().forceClientComposition = true; } -bool Layer::getForceClientComposition(DisplayId displayId) { - RETURN_IF_NO_HWC_LAYER(displayId, false); - return getBE().mHwcLayers[displayId].forceClientComposition; +bool Layer::getForceClientComposition(const sp<DisplayDevice>& display) { + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer); + return outputLayer->getState().forceClientComposition; } void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) { - const auto displayId = display->getId(); - LOG_ALWAYS_FATAL_IF(!displayId); - if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) { + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer); + + if (!outputLayer->getState().hwc || + (*outputLayer->getState().hwc).hwcCompositionType != + Hwc2::IComposerClient::Composition::CURSOR) { return; } @@ -697,8 +727,7 @@ void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) { auto position = displayTransform.transform(frame); auto error = - getBE().mHwcLayers[*displayId].layer->setCursorPosition(position.left, position.top); - + (*outputLayer->getState().hwc).hwcLayer->setCursorPosition(position.left, position.top); ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position " "to (%d, %d): %s (%d)", @@ -760,65 +789,50 @@ bool Layer::prepareClientLayer(const RenderArea& /*renderArea*/, const Region& / void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue, float alpha) const { auto& engine(mFlinger->getRenderEngine()); - computeGeometry(renderArea, getBE().mMesh, false); + computeGeometry(renderArea, getCompositionLayer()->editState().reMesh, false); engine.setupFillWithColor(red, green, blue, alpha); - engine.drawMesh(getBE().mMesh); + engine.drawMesh(getCompositionLayer()->getState().reMesh); } void Layer::clearWithOpenGL(const RenderArea& renderArea) const { clearWithOpenGL(renderArea, 0, 0, 0, 0); } -void Layer::setCompositionType(DisplayId displayId, HWC2::Composition type, bool callIntoHwc) { - if (getBE().mHwcLayers.count(displayId) == 0) { - ALOGE("setCompositionType called without a valid HWC layer"); - return; - } - auto& hwcInfo = getBE().mHwcLayers[displayId]; - auto& hwcLayer = hwcInfo.layer; - ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", (hwcLayer)->getId(), to_string(type).c_str(), - static_cast<int>(callIntoHwc)); - if (hwcInfo.compositionType != type) { +void Layer::setCompositionType(const sp<const DisplayDevice>& display, + Hwc2::IComposerClient::Composition type) { + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer); + LOG_FATAL_IF(!outputLayer->getState().hwc); + auto& compositionState = outputLayer->editState(); + + ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", ((*compositionState.hwc).hwcLayer)->getId(), + toString(type).c_str(), 1); + if ((*compositionState.hwc).hwcCompositionType != type) { ALOGV(" actually setting"); - hwcInfo.compositionType = type; - if (callIntoHwc) { - auto error = (hwcLayer)->setCompositionType(type); - ALOGE_IF(error != HWC2::Error::None, - "[%s] Failed to set " - "composition type %s: %s (%d)", - mName.string(), to_string(type).c_str(), to_string(error).c_str(), - static_cast<int32_t>(error)); - } - } -} + (*compositionState.hwc).hwcCompositionType = type; -HWC2::Composition Layer::getCompositionType(const std::optional<DisplayId>& displayId) const { - if (!displayId) { - // If we're querying the composition type for a display that does not - // have a HWC counterpart, then it will always be Client - return HWC2::Composition::Client; - } - if (getBE().mHwcLayers.count(*displayId) == 0) { - ALOGE("getCompositionType called with an invalid HWC layer"); - return HWC2::Composition::Invalid; + auto error = (*compositionState.hwc) + .hwcLayer->setCompositionType(static_cast<HWC2::Composition>(type)); + ALOGE_IF(error != HWC2::Error::None, + "[%s] Failed to set " + "composition type %s: %s (%d)", + mName.string(), toString(type).c_str(), to_string(error).c_str(), + static_cast<int32_t>(error)); } - return getBE().mHwcLayers.at(*displayId).compositionType; } -void Layer::setClearClientTarget(DisplayId displayId, bool clear) { - if (getBE().mHwcLayers.count(displayId) == 0) { - ALOGE("setClearClientTarget called without a valid HWC layer"); - return; - } - getBE().mHwcLayers[displayId].clearClientTarget = clear; +Hwc2::IComposerClient::Composition Layer::getCompositionType( + const sp<const DisplayDevice>& display) const { + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer); + return outputLayer->getState().hwc ? (*outputLayer->getState().hwc).hwcCompositionType + : Hwc2::IComposerClient::Composition::CLIENT; } -bool Layer::getClearClientTarget(DisplayId displayId) const { - if (getBE().mHwcLayers.count(displayId) == 0) { - ALOGE("getClearClientTarget called without a valid HWC layer"); - return false; - } - return getBE().mHwcLayers.at(displayId).clearClientTarget; +bool Layer::getClearClientTarget(const sp<const DisplayDevice>& display) const { + const auto outputLayer = findOutputLayerForDisplay(display); + LOG_FATAL_IF(!outputLayer); + return outputLayer->getState().clearClientTarget; } bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) { @@ -1037,9 +1051,9 @@ uint32_t Layer::doTransactionResize(uint32_t flags, State* stateToCommit) { const bool resizePending = ((stateToCommit->requested_legacy.w != stateToCommit->active_legacy.w) || (stateToCommit->requested_legacy.h != stateToCommit->active_legacy.h)) && - (getBE().compositionInfo.mBuffer != nullptr); + (mActiveBuffer != nullptr); if (!isFixedSize()) { - if (resizePending && getBE().compositionInfo.hwc.sidebandStream == nullptr) { + if (resizePending && mSidebandStream == nullptr) { flags |= eDontUpdateGeometryState; } } @@ -1535,8 +1549,9 @@ void Layer::miniDumpHeader(std::string& result) { result.append("-----------------------------\n"); } -void Layer::miniDump(std::string& result, DisplayId displayId) const { - if (!hasHwcLayer(displayId)) { +void Layer::miniDump(std::string& result, const sp<DisplayDevice>& displayDevice) const { + auto outputLayer = findOutputLayerForDisplay(displayDevice); + if (!outputLayer) { return; } @@ -1554,26 +1569,24 @@ void Layer::miniDump(std::string& result, DisplayId displayId) const { StringAppendF(&result, " %s\n", name.c_str()); const State& layerState(getDrawingState()); - const LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers.at(displayId); + const auto& compositionState = outputLayer->getState(); + if (layerState.zOrderRelativeOf != nullptr || mDrawingParent != nullptr) { StringAppendF(&result, " rel %6d | ", layerState.z); } else { StringAppendF(&result, " %10d | ", layerState.z); } - StringAppendF(&result, "%10s | ", to_string(getCompositionType(displayId)).c_str()); - StringAppendF(&result, "%10s | ", to_string(hwcInfo.transform).c_str()); - const Rect& frame = hwcInfo.displayFrame; + StringAppendF(&result, "%10s | ", toString(getCompositionType(displayDevice)).c_str()); + StringAppendF(&result, "%10s | ", + toString(getCompositionLayer() ? compositionState.bufferTransform + : static_cast<Hwc2::Transform>(0)) + .c_str()); + const Rect& frame = compositionState.displayFrame; StringAppendF(&result, "%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom); - const FloatRect& crop = hwcInfo.sourceCrop; + const FloatRect& crop = compositionState.sourceCrop; StringAppendF(&result, "%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right, crop.bottom); - result.append("- - - - - - - - - - - - - - - -\n"); - - std::string compositionInfoStr; - getBE().compositionInfo.dump(compositionInfoStr, "compositionInfo"); - result.append(compositionInfoStr); - result.append("- - - - - - - - - - - - - - - -"); result.append("- - - - - - - - - - - - - - - -"); result.append("- - - - - - - - - - - - - - -\n"); @@ -2132,8 +2145,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence); } - // XXX getBE().compositionInfo.mBuffer is not protected - auto buffer = getBE().compositionInfo.mBuffer; + auto buffer = mActiveBuffer; if (buffer != nullptr) { LayerProtoHelper::writeToProto(buffer, layerInfo->mutable_active_buffer()); LayerProtoHelper::writeToProto(ui::Transform(mCurrentTransform), @@ -2164,25 +2176,29 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) LayerProtoHelper::writeToProto(mBounds, layerInfo->mutable_bounds()); } -void Layer::writeToProto(LayerProto* layerInfo, DisplayId displayId) { - if (!hasHwcLayer(displayId)) { +void Layer::writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice) { + auto outputLayer = findOutputLayerForDisplay(displayDevice); + if (!outputLayer) { return; } writeToProto(layerInfo, LayerVector::StateSet::Drawing); - const auto& hwcInfo = getBE().mHwcLayers.at(displayId); + const auto& compositionState = outputLayer->getState(); - const Rect& frame = hwcInfo.displayFrame; + const Rect& frame = compositionState.displayFrame; LayerProtoHelper::writeToProto(frame, layerInfo->mutable_hwc_frame()); - const FloatRect& crop = hwcInfo.sourceCrop; + const FloatRect& crop = compositionState.sourceCrop; LayerProtoHelper::writeToProto(crop, layerInfo->mutable_hwc_crop()); - const int32_t transform = static_cast<int32_t>(hwcInfo.transform); + const int32_t transform = + getCompositionLayer() ? static_cast<int32_t>(compositionState.bufferTransform) : 0; layerInfo->set_hwc_transform(transform); - const int32_t compositionType = static_cast<int32_t>(hwcInfo.compositionType); + const int32_t compositionType = + static_cast<int32_t>(compositionState.hwc ? (*compositionState.hwc).hwcCompositionType + : Hwc2::IComposerClient::Composition::CLIENT); layerInfo->set_hwc_composition_type(compositionType); if (std::strcmp(getTypeId(), "BufferLayer") == 0 && @@ -2249,6 +2265,11 @@ bool Layer::canReceiveInput() const { return isVisible(); } +compositionengine::OutputLayer* Layer::findOutputLayerForDisplay( + const sp<const DisplayDevice>& display) const { + return display->getCompositionDisplay()->getOutputLayerForLayer(getCompositionLayer().get()); +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 9241e71b35..8ae057f804 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -51,6 +51,7 @@ #include "SurfaceFlinger.h" #include "TransactionCompletedThread.h" +#include "DisplayHardware/ComposerHal.h" #include "DisplayHardware/HWComposer.h" #include "RenderArea.h" @@ -70,6 +71,7 @@ class LayerBE; namespace compositionengine { class Layer; +class OutputLayer; } namespace impl { @@ -419,7 +421,7 @@ public: void writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing); - void writeToProto(LayerProto* layerInfo, DisplayId displayId); + void writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice); virtual Geometry getActiveGeometry(const Layer::State& s) const { return s.active_legacy; } virtual uint32_t getActiveWidth(const Layer::State& s) const { return s.active_legacy.w; } @@ -443,17 +445,19 @@ public: virtual bool isHdrY410() const { return false; } void setGeometry(const sp<const DisplayDevice>& display, uint32_t z); - void forceClientComposition(DisplayId displayId); - bool getForceClientComposition(DisplayId displayId); - virtual void setPerFrameData(DisplayId displayId, const ui::Transform& transform, - const Rect& viewport, int32_t supportedPerFrameMetadata) = 0; + void forceClientComposition(const sp<DisplayDevice>& display); + bool getForceClientComposition(const sp<DisplayDevice>& display); + virtual void setPerFrameData(const sp<const DisplayDevice>& display, + const ui::Transform& transform, const Rect& viewport, + int32_t supportedPerFrameMetadata) = 0; // callIntoHwc exists so we can update our local state and call // acceptDisplayChanges without unnecessarily updating the device's state - void setCompositionType(DisplayId displayId, HWC2::Composition type, bool callIntoHwc = true); - HWC2::Composition getCompositionType(const std::optional<DisplayId>& displayId) const; - void setClearClientTarget(DisplayId displayId, bool clear); - bool getClearClientTarget(DisplayId displayId) const; + void setCompositionType(const sp<const DisplayDevice>& display, + Hwc2::IComposerClient::Composition type); + Hwc2::IComposerClient::Composition getCompositionType( + const sp<const DisplayDevice>& display) const; + bool getClearClientTarget(const sp<const DisplayDevice>& display) const; void updateCursorPosition(const sp<const DisplayDevice>& display); /* @@ -567,27 +571,13 @@ public: // ----------------------------------------------------------------------- - bool createHwcLayer(HWComposer* hwc, DisplayId displayId); - bool destroyHwcLayer(DisplayId displayId); - void destroyHwcLayersForAllDisplays(); - void destroyAllHwcLayersPlusChildren(); + bool createHwcLayer(HWComposer* hwc, const sp<DisplayDevice>& display); + bool destroyHwcLayer(const sp<DisplayDevice>& display); + bool destroyHwcLayersForAllDisplays(); + bool destroyAllHwcLayersPlusChildren(); - bool hasHwcLayer(DisplayId displayId) const { return getBE().mHwcLayers.count(displayId) > 0; } - - HWC2::Layer* getHwcLayer(DisplayId displayId) { - if (!hasHwcLayer(displayId)) { - return nullptr; - } - return getBE().mHwcLayers[displayId].layer.get(); - } - - bool setHwcLayer(DisplayId displayId) { - if (!hasHwcLayer(displayId)) { - return false; - } - getBE().compositionInfo.hwc.hwcLayer = getBE().mHwcLayers[displayId].layer; - return true; - } + bool hasHwcLayer(const sp<const DisplayDevice>& displayDevice); + HWC2::Layer* getHwcLayer(const sp<const DisplayDevice>& displayDevice); // ----------------------------------------------------------------------- void clearWithOpenGL(const RenderArea& renderArea) const; @@ -600,7 +590,7 @@ public: /* always call base class first */ static void miniDumpHeader(std::string& result); - void miniDump(std::string& result, DisplayId displayId) const; + void miniDump(std::string& result, const sp<DisplayDevice>& display) const; void dumpFrameStats(std::string& result) const; void dumpFrameEvents(std::string& result); void clearFrameStats(); @@ -676,6 +666,9 @@ public: return parentBounds; } + compositionengine::OutputLayer* findOutputLayerForDisplay( + const sp<const DisplayDevice>& display) const; + protected: // constant sp<SurfaceFlinger> mFlinger; @@ -832,6 +825,7 @@ protected: FenceTimeline mReleaseTimeline; // main thread + sp<NativeHandle> mSidebandStream; // Active buffer fields sp<GraphicBuffer> mActiveBuffer; sp<Fence> mActiveBufferFence; @@ -920,11 +914,11 @@ private: } // namespace android -#define RETURN_IF_NO_HWC_LAYER(displayId, ...) \ +#define RETURN_IF_NO_HWC_LAYER(displayDevice, ...) \ do { \ - if (!hasHwcLayer(displayId)) { \ + if (!hasHwcLayer(displayDevice)) { \ ALOGE("[%s] %s failed: no HWC layer found for display %s", mName.string(), \ - __FUNCTION__, to_string(displayId).c_str()); \ + __FUNCTION__, displayDevice->getDebugName().c_str()); \ return __VA_ARGS__; \ } \ } while (false) diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp index e39babe117..9f634408c7 100644 --- a/services/surfaceflinger/LayerBE.cpp +++ b/services/surfaceflinger/LayerBE.cpp @@ -21,45 +21,14 @@ #include "Layer.h" -#include <android-base/stringprintf.h> -#include <renderengine/RenderEngine.h> - -#include <string> - -namespace { - -const char* getCompositionName(HWC2::Composition compositionType) { - switch (compositionType) { - case HWC2::Composition::Invalid: - return "Invalid"; - case HWC2::Composition::Client: - return "Client"; - case HWC2::Composition::Device: - return "Device"; - case HWC2::Composition::SolidColor: - return "Solid Color"; - case HWC2::Composition::Cursor: - return "Cursor"; - case HWC2::Composition::Sideband: - return "Sideband"; - } - return "Invalid"; -} - -} // namespace anonymous - namespace android { -LayerBE::LayerBE(Layer* layer, std::string layerName) - : mLayer(layer), - mMesh(renderengine::Mesh::TRIANGLE_FAN, 4, 2, 2) { +LayerBE::LayerBE(Layer* layer, std::string layerName) : mLayer(layer) { compositionInfo.layer = std::make_shared<LayerBE>(*this); compositionInfo.layerName = layerName; } -LayerBE::LayerBE(const LayerBE& layer) - : mLayer(layer.mLayer), - mMesh(renderengine::Mesh::TRIANGLE_FAN, 4, 2, 2) { +LayerBE::LayerBE(const LayerBE& layer) : mLayer(layer.mLayer) { compositionInfo.layer = layer.compositionInfo.layer; compositionInfo.layerName = layer.mLayer->getName().string(); } @@ -68,101 +37,4 @@ void LayerBE::onLayerDisplayed(const sp<Fence>& releaseFence) { mLayer->onLayerDisplayed(releaseFence); } -void LayerBE::clear(renderengine::RenderEngine& engine) { - engine.setupFillWithColor(0, 0, 0, 0); - engine.drawMesh(mMesh); -} - -void CompositionInfo::dump(const char* tag) const -{ - std::string logString; - dump(logString, tag); - ALOGV("%s", logString.c_str()); -} - -void CompositionInfo::dumpHwc(std::string& result, const char* tag) const { - if (tag == nullptr) { - result += base::StringPrintf("HWC parameters\n"); - } else { - result += base::StringPrintf("[%s]HWC parameters\n", tag); - } - - result += base::StringPrintf("\thwcLayer=%p\n", static_cast<HWC2::Layer*>(&*hwc.hwcLayer)); - result += base::StringPrintf("\tfence=%p\n", hwc.fence.get()); - result += base::StringPrintf("\tblendMode=%d\n", hwc.blendMode); - result += base::StringPrintf("\ttransform=%d\n", hwc.transform); - result += base::StringPrintf("\tz=%d\n", hwc.z); - result += base::StringPrintf("\ttype=%d\n", hwc.type); - result += base::StringPrintf("\tappId=%d\n", hwc.appId); - result += base::StringPrintf("\tdisplayFrame=%4d %4d %4d %4d\n", hwc.displayFrame.left, - hwc.displayFrame.top, hwc.displayFrame.right, - hwc.displayFrame.bottom); - result += base::StringPrintf("\talpha=%.3f", hwc.alpha); - result += base::StringPrintf("\tsourceCrop=%6.1f %6.1f %6.1f %6.1f\n", hwc.sourceCrop.left, - hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom); - - hwc.visibleRegion.dump(result, "visibleRegion"); - hwc.surfaceDamage.dump(result, "surfaceDamage"); - - result += base::StringPrintf("\tcolor transform matrix:\n" - "\t\t[%f, %f, %f, %f,\n" - "\t\t %f, %f, %f, %f,\n" - "\t\t %f, %f, %f, %f,\n" - "\t\t %f, %f, %f, %f]\n", - hwc.colorTransform[0][0], hwc.colorTransform[1][0], - hwc.colorTransform[2][0], hwc.colorTransform[3][0], - hwc.colorTransform[0][1], hwc.colorTransform[1][1], - hwc.colorTransform[2][1], hwc.colorTransform[3][1], - hwc.colorTransform[0][2], hwc.colorTransform[1][2], - hwc.colorTransform[2][2], hwc.colorTransform[3][2], - hwc.colorTransform[0][3], hwc.colorTransform[1][3], - hwc.colorTransform[2][3], hwc.colorTransform[3][3]); -} - -void CompositionInfo::dumpRe(std::string& result, const char* tag) const { - if (tag == nullptr) { - result += base::StringPrintf("RenderEngine parameters:\n"); - } else { - result += base::StringPrintf("[%s]RenderEngine parameters:\n", tag); - } - - result += base::StringPrintf("\tblackoutLayer=%d\n", re.blackoutLayer); - result += base::StringPrintf("\tclearArea=%d\n", re.clearArea); - result += base::StringPrintf("\tpreMultipliedAlpha=%d\n", re.preMultipliedAlpha); - result += base::StringPrintf("\topaque=%d\n", re.opaque); - result += base::StringPrintf("\tdisableTexture=%d\n", re.disableTexture); - result += base::StringPrintf("\tuseIdentityTransform=%d\n", re.useIdentityTransform); -} - -void CompositionInfo::dump(std::string& result, const char* tag) const -{ - if (tag == nullptr) { - result += base::StringPrintf("CompositionInfo\n"); - } else { - result += base::StringPrintf("[%s]CompositionInfo\n", tag); - } - result += base::StringPrintf("\tLayerName: %s\n", layerName.c_str()); - result += base::StringPrintf("\tCompositionType: %s\n", - getCompositionName(compositionType)); - result += base::StringPrintf("\tmBuffer = %p\n", mBuffer.get()); - result += base::StringPrintf("\tmBufferSlot=%d\n", mBufferSlot); - result += base::StringPrintf("\tdisplayFrame=%4d %4d %4d %4d\n", hwc.displayFrame.left, - hwc.displayFrame.top, hwc.displayFrame.right, - hwc.displayFrame.bottom); - result += base::StringPrintf("\talpha=%f\n", hwc.alpha); - result += base::StringPrintf("\tsourceCrop=%6.1f %6.1f %6.1f %6.1f\n", hwc.sourceCrop.left, - hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom); - - switch (compositionType) { - case HWC2::Composition::Device: - dumpHwc(result, tag); - break; - case HWC2::Composition::Client: - dumpRe(result, tag); - break; - default: - break; - } -} - }; // namespace android diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h index 6270efa742..51f7857356 100644 --- a/services/surfaceflinger/LayerBE.h +++ b/services/surfaceflinger/LayerBE.h @@ -17,18 +17,12 @@ #pragma once #include <stdint.h> -#include <sys/types.h> +#include <string.h> -#include <compositionengine/impl/HwcBufferCache.h> - -#include <renderengine/Mesh.h> -#include <renderengine/RenderEngine.h> -#include <renderengine/Texture.h> -#include <ui/Region.h> +#include <ui/Fence.h> +#include <utils/StrongPointer.h> #include "DisplayHardware/DisplayIdentification.h" -#include "DisplayHardware/HWComposer.h" -#include "SurfaceFlinger.h" namespace android { @@ -36,48 +30,10 @@ class LayerBE; struct CompositionInfo { std::string layerName; - HWC2::Composition compositionType; - bool firstClear = false; - sp<GraphicBuffer> mBuffer = nullptr; - int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT; std::shared_ptr<LayerBE> layer; struct { - std::shared_ptr<HWC2::Layer> hwcLayer; DisplayId displayId; - sp<Fence> fence; - HWC2::BlendMode blendMode = HWC2::BlendMode::Invalid; - Rect displayFrame; - float alpha; - FloatRect sourceCrop; - HWC2::Transform transform = HWC2::Transform::None; - int z; - int type; - int appId; - Region visibleRegion; - Region surfaceDamage; - sp<NativeHandle> sidebandStream; - ui::Dataspace dataspace; - hwc_color_t color; - bool clearClientTarget = false; - bool supportedPerFrameMetadata = false; - HdrMetadata hdrMetadata; - mat4 colorTransform; } hwc; - struct { - bool blackoutLayer = false; - bool clearArea = false; - bool preMultipliedAlpha = false; - bool opaque = false; - bool disableTexture = false; - half4 color; - bool useIdentityTransform = false; - bool Y410BT2020 = false; - } re; - - void dump(const char* tag) const; - void dump(std::string& result, const char* tag = nullptr) const; - void dumpHwc(std::string& result, const char* tag = nullptr) const; - void dumpRe(std::string& result, const char* tag = nullptr) const; }; class LayerBE { @@ -96,41 +52,10 @@ public: explicit LayerBE(const LayerBE& layer); void onLayerDisplayed(const sp<Fence>& releaseFence); - void clear(renderengine::RenderEngine& renderEngine); - renderengine::Mesh& getMesh() { return mMesh; } Layer*const mLayer; -private: - // The mesh used to draw the layer in GLES composition mode - renderengine::Mesh mMesh; - - // HWC items, accessed from the main thread - struct HWCInfo { - HWCInfo() - : hwc(nullptr), - layer(nullptr), - forceClientComposition(false), - compositionType(HWC2::Composition::Invalid), - clearClientTarget(false), - transform(HWC2::Transform::None) {} - - HWComposer* hwc; - std::shared_ptr<HWC2::Layer> layer; - bool forceClientComposition; - HWC2::Composition compositionType; - bool clearClientTarget; - Rect displayFrame; - FloatRect sourceCrop; - compositionengine::impl::HwcBufferCache bufferCache; - HWC2::Transform transform; - }; - - // A layer can be attached to multiple displays when operating in mirror mode - // (a.k.a: when several displays are attached with equal layerStack). In this - // case we need to keep track. In non-mirror mode, a layer will have only one - // HWCInfo. - std::unordered_map<DisplayId, HWCInfo> mHwcLayers; +private: CompositionInfo compositionInfo; }; diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h index 9bad6dee04..edc6442da7 100644 --- a/services/surfaceflinger/RenderArea.h +++ b/services/surfaceflinger/RenderArea.h @@ -7,6 +7,8 @@ namespace android { +class DisplayDevice; + // RenderArea describes a rectangular area that layers can be rendered to. // // There is a logical render area and a physical render area. When a layer is @@ -76,6 +78,8 @@ public: // covered by any rendered layer should be filled with this color. CaptureFill getCaptureFill() const { return mCaptureFill; }; + virtual const sp<const DisplayDevice> getDisplayDevice() const = 0; + private: const uint32_t mReqWidth; const uint32_t mReqHeight; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index dc3409b10b..3abd6a7ce5 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -43,7 +43,9 @@ #include <compositionengine/Layer.h> #include <compositionengine/OutputLayer.h> #include <compositionengine/RenderSurface.h> +#include <compositionengine/impl/LayerCompositionState.h> #include <compositionengine/impl/OutputCompositionState.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> #include <dvr/vr_flinger.h> #include <gui/BufferQueue.h> #include <gui/GuiConfig.h> @@ -1826,11 +1828,6 @@ void SurfaceFlinger::handleMessageRefresh() { mVsyncModulator.onRefreshed(mHadClientComposition); getBE().mEndOfFrameCompositionInfo = std::move(getBE().mCompositionInfo); - for (const auto& [token, display] : mDisplays) { - for (auto& compositionInfo : getBE().mEndOfFrameCompositionInfo[token]) { - compositionInfo.hwc.hwcLayer = nullptr; - } - } mLayersWithQueuedFrames.clear(); } @@ -1871,16 +1868,16 @@ void SurfaceFlinger::calculateWorkingSet() { for (size_t i = 0; i < currentLayers.size(); i++) { const auto& layer = currentLayers[i]; - if (!layer->hasHwcLayer(*displayId)) { - if (!layer->createHwcLayer(&getHwComposer(), *displayId)) { - layer->forceClientComposition(*displayId); + if (!layer->hasHwcLayer(displayDevice)) { + if (!layer->createHwcLayer(&getHwComposer(), displayDevice)) { + layer->forceClientComposition(displayDevice); continue; } } layer->setGeometry(displayDevice, i); if (mDebugDisableHWC || mDebugRegion) { - layer->forceClientComposition(*displayId); + layer->forceClientComposition(displayDevice); } } } @@ -1900,34 +1897,35 @@ void SurfaceFlinger::calculateWorkingSet() { } for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { if (layer->isHdrY410()) { - layer->forceClientComposition(*displayId); + layer->forceClientComposition(displayDevice); } else if ((layer->getDataSpace() == Dataspace::BT2020_PQ || layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) && !profile->hasHDR10Support()) { - layer->forceClientComposition(*displayId); + layer->forceClientComposition(displayDevice); } else if ((layer->getDataSpace() == Dataspace::BT2020_HLG || layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) && !profile->hasHLGSupport()) { - layer->forceClientComposition(*displayId); + layer->forceClientComposition(displayDevice); } // TODO(b/111562338) remove when composer 2.3 is shipped. if (layer->hasColorTransform()) { - layer->forceClientComposition(*displayId); + layer->forceClientComposition(displayDevice); } if (layer->getRoundedCornerState().radius > 0.0f) { - layer->forceClientComposition(*displayId); + layer->forceClientComposition(displayDevice); } - if (layer->getForceClientComposition(*displayId)) { + if (layer->getForceClientComposition(displayDevice)) { ALOGV("[%s] Requesting Client composition", layer->getName().string()); - layer->setCompositionType(*displayId, HWC2::Composition::Client); + layer->setCompositionType(displayDevice, + Hwc2::IComposerClient::Composition::CLIENT); continue; } const auto& displayState = display->getState(); - layer->setPerFrameData(*displayId, displayState.transform, displayState.viewport, + layer->setPerFrameData(displayDevice, displayState.transform, displayState.viewport, displayDevice->getSupportedPerFrameMetadata()); } @@ -1942,20 +1940,15 @@ void SurfaceFlinger::calculateWorkingSet() { mDrawingState.colorMatrixChanged = false; - for (const auto& [token, display] : mDisplays) { - for (auto& layer : display->getVisibleLayersSortedByZ()) { + for (const auto& [token, displayDevice] : mDisplays) { + auto display = displayDevice->getCompositionDisplay(); + for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { const auto displayId = display->getId(); - layer->getBE().compositionInfo.compositionType = layer->getCompositionType(displayId); - - if (displayId) { - if (!layer->setHwcLayer(*displayId)) { - ALOGV("Need to create HWCLayer for %s", layer->getName().string()); - } - layer->getBE().compositionInfo.hwc.displayId = *displayId; - } - + auto& layerState = layer->getCompositionLayer()->editState().frontEnd; + layerState.compositionType = static_cast<Hwc2::IComposerClient::Composition>( + layer->getCompositionType(displayDevice)); + layer->getBE().compositionInfo.hwc.displayId = *displayId; getBE().mCompositionInfo[token].push_back(layer->getBE().compositionInfo); - layer->getBE().compositionInfo.hwc.hwcLayer = nullptr; } } } @@ -2003,7 +1996,7 @@ void SurfaceFlinger::logLayerStats() { if (CC_UNLIKELY(mLayerStats.isEnabled())) { for (const auto& [token, display] : mDisplays) { if (display->isPrimary()) { - mLayerStats.logLayerStats(dumpVisibleLayersProtoInfo(*display)); + mLayerStats.logLayerStats(dumpVisibleLayersProtoInfo(display)); return; } } @@ -2400,13 +2393,13 @@ void SurfaceFlinger::rebuildLayerStacks() { } else { // Clear out the HWC layer if this layer was // previously visible, but no longer is - hwcLayerDestroyed = displayId && layer->destroyHwcLayer(*displayId); + hwcLayerDestroyed = displayId && layer->destroyHwcLayer(displayDevice); } } else { // WM changes display->layerStack upon sleep/awake. // Here we make sure we delete the HWC layers even if // WM changed their layer stack. - hwcLayerDestroyed = displayId && layer->destroyHwcLayer(*displayId); + hwcLayerDestroyed = displayId && layer->destroyHwcLayer(displayDevice); } // If a layer is not going to get a release fence because @@ -2576,8 +2569,7 @@ void SurfaceFlinger::prepareFrame(const sp<DisplayDevice>& displayDevice) { return; } - status_t result = display->getRenderSurface()->prepareFrame( - getBE().mCompositionInfo[displayDevice->getDisplayToken()]); + status_t result = display->getRenderSurface()->prepareFrame(); ALOGE_IF(result != NO_ERROR, "prepareFrame failed for %s: %d (%s)", displayDevice->getDebugName().c_str(), result, strerror(-result)); } @@ -2635,9 +2627,10 @@ void SurfaceFlinger::postFramebuffer(const sp<DisplayDevice>& displayDevice) { // The layer buffer from the previous frame (if any) is released // by HWC only when the release fence from this frame (if any) is // signaled. Always get the release fence from HWC first. - if (displayId && layer->hasHwcLayer(*displayId)) { - releaseFence = getHwComposer().getLayerReleaseFence(*displayId, - layer->getHwcLayer(*displayId)); + if (displayId && layer->hasHwcLayer(displayDevice)) { + releaseFence = + getHwComposer().getLayerReleaseFence(*displayId, + layer->getHwcLayer(displayDevice)); } // If the layer was client composited in the previous frame, we @@ -2645,7 +2638,8 @@ void SurfaceFlinger::postFramebuffer(const sp<DisplayDevice>& displayDevice) { // Since we do not track that, always merge with the current // client target acquire fence when it is available, even though // this is suboptimal. - if (layer->getCompositionType(displayId) == HWC2::Composition::Client) { + if (layer->getCompositionType(displayDevice) == + Hwc2::IComposerClient::Composition::CLIENT) { releaseFence = Fence::merge("LayerRelease", releaseFence, display->getRenderSurface()->getClientTargetAcquireFence()); @@ -3562,16 +3556,16 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice, const Region viewportRegion(displayState.viewport); const Region clip(viewportRegion.intersect(layer->visibleRegion)); ALOGV("Layer: %s", layer->getName().string()); - ALOGV(" Composition type: %s", to_string(layer->getCompositionType(displayId)).c_str()); + ALOGV(" Composition type: %s", toString(layer->getCompositionType(displayDevice)).c_str()); if (!clip.isEmpty()) { - switch (layer->getCompositionType(displayId)) { - case HWC2::Composition::Cursor: - case HWC2::Composition::Device: - case HWC2::Composition::Sideband: - case HWC2::Composition::SolidColor: { + switch (layer->getCompositionType(displayDevice)) { + case Hwc2::IComposerClient::Composition::CURSOR: + case Hwc2::IComposerClient::Composition::DEVICE: + case Hwc2::IComposerClient::Composition::SIDEBAND: + case Hwc2::IComposerClient::Composition::SOLID_COLOR: { LOG_ALWAYS_FATAL_IF(!displayId); const Layer::State& state(layer->getDrawingState()); - if (layer->getClearClientTarget(*displayId) && !firstLayer && + if (layer->getClearClientTarget(displayDevice) && !firstLayer && layer->isOpaque(state) && (layer->getAlpha() == 1.0f) && layer->getRoundedCornerState().radius == 0.0f && hasClientComposition) { // never clear the very first layer since we're @@ -3591,7 +3585,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice, } break; } - case HWC2::Composition::Client: { + case Hwc2::IComposerClient::Composition::CLIENT: { renderengine::LayerSettings layerSettings; bool prepared = layer->prepareClientLayer(renderArea, clip, clearRegion, layerSettings); @@ -4580,7 +4574,6 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, })}, {"--dump-layer-stats"s, dumper([this](std::string& s) { mLayerStats.dump(s); })}, {"--enable-layer-stats"s, dumper([this](std::string&) { mLayerStats.enable(); })}, - {"--frame-composition"s, dumper(&SurfaceFlinger::dumpFrameCompositionInfo)}, {"--frame-events"s, dumper(&SurfaceFlinger::dumpFrameEventsLocked)}, {"--latency"s, argsDumper(&SurfaceFlinger::dumpStatsLocked)}, {"--latency-clear"s, argsDumper(&SurfaceFlinger::clearStatsLocked)}, @@ -4834,23 +4827,6 @@ void SurfaceFlinger::dumpWideColorInfo(std::string& result) const { result.append("\n"); } -void SurfaceFlinger::dumpFrameCompositionInfo(std::string& result) const { - for (const auto& [token, display] : mDisplays) { - const auto it = getBE().mEndOfFrameCompositionInfo.find(token); - if (it == getBE().mEndOfFrameCompositionInfo.end()) { - continue; - } - - const auto& compositionInfoList = it->second; - StringAppendF(&result, "%s\n", display->getDebugName().c_str()); - StringAppendF(&result, "numComponents: %zu\n", compositionInfoList.size()); - for (const auto& compositionInfo : compositionInfoList) { - compositionInfo.dump(result, nullptr); - result.append("\n"); - } - } -} - LayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet) const { LayersProto layersProto; const bool useDrawing = stateSet == LayerVector::StateSet::Drawing; @@ -4863,26 +4839,27 @@ LayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet) const return layersProto; } -LayersProto SurfaceFlinger::dumpVisibleLayersProtoInfo(const DisplayDevice& displayDevice) const { +LayersProto SurfaceFlinger::dumpVisibleLayersProtoInfo( + const sp<DisplayDevice>& displayDevice) const { LayersProto layersProto; SizeProto* resolution = layersProto.mutable_resolution(); - resolution->set_w(displayDevice.getWidth()); - resolution->set_h(displayDevice.getHeight()); + resolution->set_w(displayDevice->getWidth()); + resolution->set_h(displayDevice->getHeight()); - auto display = displayDevice.getCompositionDisplay(); + auto display = displayDevice->getCompositionDisplay(); const auto& displayState = display->getState(); layersProto.set_color_mode(decodeColorMode(displayState.colorMode)); layersProto.set_color_transform(decodeColorTransform(displayState.colorTransform)); layersProto.set_global_transform(displayState.orientation); - const auto displayId = displayDevice.getId(); + const auto displayId = displayDevice->getId(); LOG_ALWAYS_FATAL_IF(!displayId); mDrawingState.traverseInZOrder([&](Layer* layer) { - if (!layer->visibleRegion.isEmpty() && layer->getBE().mHwcLayers.count(*displayId)) { + if (!layer->visibleRegion.isEmpty() && !display->getOutputLayersOrderedByZ().empty()) { LayerProto* layerProto = layersProto.add_layers(); - layer->writeToProto(layerProto, *displayId); + layer->writeToProto(layerProto, displayDevice); } }); @@ -4951,10 +4928,6 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co result.append("\n"); } - result.append("\nFrame-Composition information:\n"); - dumpFrameCompositionInfo(result); - result.append("\n"); - /* * Dump Display state */ @@ -5018,7 +4991,9 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co StringAppendF(&result, "Display %s HWC layers:\n", to_string(*displayId).c_str()); Layer::miniDumpHeader(result); - mCurrentState.traverseInZOrder([&](Layer* layer) { layer->miniDump(result, *displayId); }); + const sp<DisplayDevice> displayDevice = display; + mCurrentState.traverseInZOrder( + [&](Layer* layer) { layer->miniDump(result, displayDevice); }); result.append("\n"); } @@ -5570,6 +5545,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, } bool isSecure() const override { return false; } bool needsFiltering() const override { return mNeedsFiltering; } + const sp<const DisplayDevice> getDisplayDevice() const override { return nullptr; } Rect getSourceCrop() const override { if (mCrop.isEmpty()) { return getBounds(); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 02898b21f0..728e8d3f83 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -895,9 +895,8 @@ private: void dumpBufferingStats(std::string& result) const; void dumpDisplayIdentificationData(std::string& result) const; void dumpWideColorInfo(std::string& result) const; - void dumpFrameCompositionInfo(std::string& result) const; LayersProto dumpProtoInfo(LayerVector::StateSet stateSet) const; - LayersProto dumpVisibleLayersProtoInfo(const DisplayDevice& display) const; + LayersProto dumpVisibleLayersProtoInfo(const sp<DisplayDevice>& display) const; bool isLayerTripleBufferingDisabled() const { return this->mLayerTripleBufferingDisabled; diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp index 68cf61e0dd..a2c0611b1e 100644 --- a/services/surfaceflinger/tests/fakehwc/Android.bp +++ b/services/surfaceflinger/tests/fakehwc/Android.bp @@ -31,7 +31,6 @@ cc_test { "libutils", ], static_libs: [ - "libcompositionengine", "libgmock", "librenderengine", "libtrace_proto", diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 3fb87087d4..3addd61e55 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -17,6 +17,7 @@ #undef LOG_TAG #define LOG_TAG "CompositionTest" +#include <compositionengine/Display.h> #include <compositionengine/mock/DisplaySurface.h> #include <gmock/gmock.h> #include <gtest/gtest.h> @@ -753,12 +754,16 @@ struct BaseLayerVariant { } static void injectLayer(CompositionTest* test, sp<Layer> layer) { + std::vector<std::unique_ptr<compositionengine::OutputLayer>> outputLayers; + outputLayers.emplace_back( + test->mDisplay->getCompositionDisplay() + ->getOrCreateOutputLayer(layer->getCompositionLayer(), layer)); + test->mDisplay->getCompositionDisplay()->setOutputLayersOrderedByZ(std::move(outputLayers)); + EXPECT_CALL(*test->mComposer, createLayer(HWC_DISPLAY, _)) .WillOnce(DoAll(SetArgPointee<1>(HWC_LAYER), Return(Error::NONE))); - const auto displayId = test->mDisplay->getId(); - ASSERT_TRUE(displayId); - layer->createHwcLayer(&test->mFlinger.getHwComposer(), *displayId); + layer->createHwcLayer(&test->mFlinger.getHwComposer(), test->mDisplay); Mock::VerifyAndClear(test->mComposer); @@ -771,10 +776,12 @@ struct BaseLayerVariant { static void cleanupInjectedLayers(CompositionTest* test) { EXPECT_CALL(*test->mComposer, destroyLayer(HWC_DISPLAY, HWC_LAYER)) .WillOnce(Return(Error::NONE)); - const auto displayId = test->mDisplay->getId(); - ASSERT_TRUE(displayId); + + test->mDisplay->getCompositionDisplay()->setOutputLayersOrderedByZ( + std::vector<std::unique_ptr<compositionengine::OutputLayer>>()); + for (auto layer : test->mFlinger.mutableDrawingState().layersSortedByZ) { - layer->destroyHwcLayer(*displayId); + layer->destroyHwcLayer(test->mDisplay); } test->mFlinger.mutableDrawingState().layersSortedByZ.clear(); } @@ -963,8 +970,8 @@ struct RECompositionResultVariant : public CompositionResultBaseVariant { }; struct ForcedClientCompositionResultVariant : public RECompositionResultVariant { - static void setupLayerState(CompositionTest*, sp<Layer> layer) { - layer->forceClientComposition(DEFAULT_DISPLAY_ID); + static void setupLayerState(CompositionTest* test, sp<Layer> layer) { + layer->forceClientComposition(test->mDisplay); } template <typename Case> diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 495237b3f2..959126ef08 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -16,7 +16,12 @@ #pragma once +#include <compositionengine/Display.h> +#include <compositionengine/Layer.h> +#include <compositionengine/OutputLayer.h> #include <compositionengine/impl/CompositionEngine.h> +#include <compositionengine/impl/LayerCompositionState.h> +#include <compositionengine/impl/OutputLayerCompositionState.h> #include "BufferQueueLayer.h" #include "BufferStateLayer.h" @@ -203,9 +208,18 @@ public: void setLayerSidebandStream(sp<Layer> layer, sp<NativeHandle> sidebandStream) { layer->mDrawingState.sidebandStream = sidebandStream; - layer->getBE().compositionInfo.hwc.sidebandStream = sidebandStream; + layer->mSidebandStream = sidebandStream; + layer->getCompositionLayer()->editState().frontEnd.sidebandStream = sidebandStream; } + void setLayerCompositionType(sp<Layer> layer, HWC2::Composition type) { + auto outputLayer = layer->findOutputLayerForDisplay(mFlinger->getDefaultDisplayDevice()); + LOG_ALWAYS_FATAL_IF(!outputLayer); + auto& state = outputLayer->editState(); + LOG_ALWAYS_FATAL_IF(!outputLayer->getState().hwc); + (*state.hwc).hwcCompositionType = static_cast<Hwc2::IComposerClient::Composition>(type); + }; + void setLayerPotentialCursor(sp<Layer> layer, bool potentialCursor) { layer->mPotentialCursor = potentialCursor; } |