diff options
49 files changed, 1064 insertions, 889 deletions
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index be260e856d..91cd90d0ab 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -68,6 +68,8 @@ libbinder_device_interface_sources = [ cc_library { name: "libbinder", + version_script: "libbinder.map", + // for vndbinder vendor_available: true, vndk: { diff --git a/libs/binder/libbinder.map b/libs/binder/libbinder.map new file mode 100644 index 0000000000..9ca14bcec2 --- /dev/null +++ b/libs/binder/libbinder.map @@ -0,0 +1,5 @@ +# b/190148312: Populate with correct list of ABI symbols +LIBBINDER { + global: + *; +}; diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index ada689ac42..75f2385174 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -213,6 +213,7 @@ int ANativeWindow_query(const ANativeWindow* window, ANativeWindowQuery what, in case ANATIVEWINDOW_QUERY_DEFAULT_WIDTH: case ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT: case ANATIVEWINDOW_QUERY_TRANSFORM_HINT: + case ANATIVEWINDOW_QUERY_BUFFER_AGE: // these are part of the VNDK API break; case ANATIVEWINDOW_QUERY_MIN_SWAP_INTERVAL: diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp index f57666077e..de36a7aea6 100644 --- a/opengl/libs/EGL/egl_platform_entries.cpp +++ b/opengl/libs/EGL/egl_platform_entries.cpp @@ -1453,7 +1453,9 @@ EGLBoolean eglSurfaceAttribImpl(EGLDisplay dpy, EGLSurface surface, EGLint attri if (attribute == EGL_TIMESTAMPS_ANDROID) { if (!s->getNativeWindow()) { - return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE); + // According to the spec, "if surface is not a window surface this has no + // effect." + return EGL_TRUE; } int err = native_window_enable_frame_timestamps(s->getNativeWindow(), value != 0); return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE); diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h index 633668e1c2..14eddb1861 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h @@ -21,13 +21,10 @@ #include <string> #include <ui/DisplayId.h> -#include <ui/PixelFormat.h> #include <ui/Size.h> #include <ui/StaticDisplayInfo.h> -#include "DisplayHardware/DisplayIdentification.h" #include "DisplayHardware/PowerAdvisor.h" -#include "DisplayIdGenerator.h" namespace android::compositionengine { @@ -37,24 +34,14 @@ class CompositionEngine; * A parameter object for creating Display instances */ struct DisplayCreationArgs { - struct Physical { - DisplayId id; - ui::DisplayConnectionType type; - }; + DisplayId id; - // Required for physical displays. Gives the HWC display id for the existing - // display along with the connection type. - std::optional<Physical> physical; + // Unset for virtual displays + std::optional<ui::DisplayConnectionType> connectionType; // Size of the display in pixels ui::Size pixels = ui::Size::INVALID; - // Pixel format of the display - ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN); - - // True if virtual displays should be created with the HWC API if possible - bool useHwcVirtualDisplays = false; - // True if this display should be considered secure bool isSecure = false; @@ -67,9 +54,6 @@ struct DisplayCreationArgs { // Debugging. Human readable name for the display. std::string name; - - // Generator for IDs of virtual displays, which are backed by the GPU. - DisplayIdGenerator<GpuVirtualDisplayId>* gpuVirtualDisplayIdGenerator; }; /** @@ -80,29 +64,18 @@ class DisplayCreationArgsBuilder { public: DisplayCreationArgs build() { return std::move(mArgs); } - DisplayCreationArgsBuilder& setPhysical(DisplayCreationArgs::Physical physical) { - mArgs.physical = physical; + DisplayCreationArgsBuilder& setId(DisplayId id) { + mArgs.id = id; return *this; } - DisplayCreationArgsBuilder& setPixels(ui::Size pixels) { - mArgs.pixels = pixels; + DisplayCreationArgsBuilder& setConnectionType(ui::DisplayConnectionType connectionType) { + mArgs.connectionType = connectionType; return *this; } - DisplayCreationArgsBuilder& setPixelFormat(ui::PixelFormat pixelFormat) { - mArgs.pixelFormat = pixelFormat; - return *this; - } - - DisplayCreationArgsBuilder& setUseHwcVirtualDisplays(bool useHwcVirtualDisplays) { - mArgs.useHwcVirtualDisplays = useHwcVirtualDisplays; - return *this; - } - - DisplayCreationArgsBuilder& setGpuVirtualDisplayIdGenerator( - DisplayIdGenerator<GpuVirtualDisplayId>& generator) { - mArgs.gpuVirtualDisplayIdGenerator = &generator; + DisplayCreationArgsBuilder& setPixels(ui::Size pixels) { + mArgs.pixels = pixels; return *this; } diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h index 791e7db75c..e51019ae99 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h @@ -78,6 +78,30 @@ public: virtual void prepareCompositionState(StateSubset) = 0; struct ClientCompositionTargetSettings { + enum class BlurSetting { + Disabled, + BackgroundBlurOnly, + BlurRegionsOnly, + Enabled, + }; + + friend std::string toString(BlurSetting blurSetting) { + switch (blurSetting) { + case BlurSetting::Enabled: + return "Enabled"; + case BlurSetting::BlurRegionsOnly: + return "BlurRegionsOnly"; + case BlurSetting::BackgroundBlurOnly: + return "BackgroundBlurOnly"; + case BlurSetting::Disabled: + return "Disabled"; + } + } + + friend std::ostream& operator<<(std::ostream& os, const BlurSetting& setting) { + return os << toString(setting); + } + // The clip region, or visible region that is being rendered to const Region& clip; @@ -110,8 +134,8 @@ public: // This may be requested by the HWC const bool clearContent; - // If set to true, change the layer settings to not use any blurs. - const bool disableBlurs; + // Configure layer settings for using blurs + BlurSetting blurSetting; }; // A superset of LayerSettings required by RenderEngine to compose a layer @@ -186,6 +210,7 @@ static inline void PrintTo(const LayerFE::ClientCompositionTargetSettings& setti PrintTo(settings.dataspace, os); *os << "\n .realContentIsVisible = " << settings.realContentIsVisible; *os << "\n .clearContent = " << settings.clearContent; + *os << "\n .blurSetting = " << settings.blurSetting; *os << "\n}"; } diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h index a8d372c562..4110346aa3 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h @@ -24,21 +24,17 @@ struct ANativeWindow; -namespace android { - -namespace compositionengine { - -class Display; +namespace android::compositionengine { /** * A parameter object for creating RenderSurface instances */ struct RenderSurfaceCreationArgs { // The initial width of the surface - int32_t displayWidth; + int32_t displayWidth = -1; // The initial height of the surface - int32_t displayHeight; + int32_t displayHeight = -1; // The ANativeWindow for the buffer queue for this surface sp<ANativeWindow> nativeWindow; @@ -46,22 +42,16 @@ struct RenderSurfaceCreationArgs { // The DisplaySurface for this surface sp<DisplaySurface> displaySurface; - size_t maxTextureCacheSize; + // The maximum size of the renderengine::ExternalTexture cache + size_t maxTextureCacheSize = 0; + +private: + friend class RenderSurfaceCreationArgsBuilder; + + // Not defaulted to disable aggregate initialization. + RenderSurfaceCreationArgs() {} }; -/** - * A helper for setting up a RenderSurfaceCreationArgs value in-line. - * Prefer this builder over raw structure initialization. - * - * Instead of: - * - * RenderSurfaceCreationArgs{1000, 1000, nativeWindow, displaySurface} - * - * Prefer: - * - * RenderSurfaceCreationArgsBuilder().setDisplayWidth(1000).setDisplayHeight(1000) - * .setNativeWindow(nativeWindow).setDisplaySurface(displaySurface).Build(); - */ class RenderSurfaceCreationArgsBuilder { public: RenderSurfaceCreationArgs build() { return std::move(mArgs); } @@ -75,11 +65,11 @@ public: return *this; } RenderSurfaceCreationArgsBuilder& setNativeWindow(sp<ANativeWindow> nativeWindow) { - mArgs.nativeWindow = nativeWindow; + mArgs.nativeWindow = std::move(nativeWindow); return *this; } RenderSurfaceCreationArgsBuilder& setDisplaySurface(sp<DisplaySurface> displaySurface) { - mArgs.displaySurface = displaySurface; + mArgs.displaySurface = std::move(displaySurface); return *this; } @@ -92,5 +82,4 @@ private: RenderSurfaceCreationArgs mArgs; }; -} // namespace compositionengine -} // namespace android +} // namespace android::compositionengine diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h index 54e91ae6be..bb540ea7ee 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h @@ -80,19 +80,13 @@ public: // Internal virtual void setConfiguration(const compositionengine::DisplayCreationArgs&); - virtual std::optional<DisplayId> maybeAllocateDisplayIdForVirtualDisplay(ui::Size, - ui::PixelFormat) const; std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const; - // Testing - void setDisplayIdForTesting(DisplayId displayId); - private: bool mIsVirtual = false; bool mIsDisconnected = false; DisplayId mId; Hwc2::PowerAdvisor* mPowerAdvisor = nullptr; - DisplayIdGenerator<GpuVirtualDisplayId>* mGpuVirtualDisplayIdGenerator; }; // This template factory function standardizes the implementation details of the diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h index 3f670a1b32..7564c54218 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h @@ -103,6 +103,13 @@ struct OutputLayerCompositionState { // be visible through it. Unowned - the OutputLayer's lifetime will // outlast this.) compositionengine::OutputLayer* peekThroughLayer = nullptr; + // True when this layer's blur has been cached with a previous layer, so that this layer + // does not need to request blurring. + // TODO(b/188816867): support blur regions too, which are less likely to be common if a + // device supports cross-window blurs. Blur region support should be doable, but we would + // need to make sure that layer caching works well with the blur region transform passed + // into RenderEngine + bool disableBackgroundBlur = false; } overrideInfo; /* diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h index fdcd6abe65..801dc74144 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h @@ -39,6 +39,7 @@ public: const LayerState* getState() const { return mState; } const std::string& getName() const { return mState->getName(); } + int32_t getBackgroundBlurRadius() const { return mState->getBackgroundBlurRadius(); } Rect getDisplayFrame() const { return mState->getDisplayFrame(); } const Region& getVisibleRegion() const { return mState->getVisibleRegion(); } const sp<GraphicBuffer>& getBuffer() const { @@ -91,6 +92,7 @@ public: mTexture = nullptr; mOutputDataspace = ui::Dataspace::UNKNOWN; mDrawFence = nullptr; + mBlurLayer = nullptr; mLayers.insert(mLayers.end(), other.mLayers.cbegin(), other.mLayers.cend()); Region boundingRegion; @@ -123,9 +125,15 @@ public: // nothing (besides the hole punch layer) will be drawn behind it. void addHolePunchLayerIfFeasible(const CachedSet&, bool isFirstLayer); + void addBackgroundBlurLayer(const CachedSet&); + // Retrieve the layer that will be drawn behind this one. compositionengine::OutputLayer* getHolePunchLayer() const; + compositionengine::OutputLayer* getBlurLayer() const; + + bool hasHdrLayers() const; + private: CachedSet() = default; @@ -135,6 +143,7 @@ private: // Unowned. const LayerState* mHolePunchLayer = nullptr; + const LayerState* mBlurLayer = nullptr; Rect mBounds = Rect::EMPTY_RECT; Region mVisibleRegion; size_t mAge = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h index 213c55e0ce..ca1d69d579 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h @@ -51,6 +51,11 @@ public: void dump(std::string& result) const; void dumpLayers(std::string& result) const; + const std::optional<CachedSet>& getNewCachedSetForTesting() const { return mNewCachedSet; } + +protected: + std::optional<CachedSet> mNewCachedSet; + private: size_t calculateDisplayCost(const std::vector<const LayerState*>& layers) const; @@ -72,6 +77,7 @@ private: std::vector<CachedSet>::const_iterator mStart; std::vector<size_t> mLengths; const CachedSet* mHolePunchCandidate = nullptr; + const CachedSet* mBlurringLayer = nullptr; public: // Initializes a Builder a CachedSet to start from. @@ -90,6 +96,10 @@ private: mHolePunchCandidate = holePunchCandidate; } + void setBlurringLayer(const CachedSet* blurringLayer) { + mBlurringLayer = blurringLayer; + } + // Builds a Run instance, if a valid Run may be built. std::optional<Run> validateAndBuild() { if (mLengths.size() <= 1) { @@ -99,7 +109,7 @@ private: return Run(mStart, std::reduce(mLengths.cbegin(), mLengths.cend(), 0u, [](size_t left, size_t right) { return left + right; }), - mHolePunchCandidate); + mHolePunchCandidate, mBlurringLayer); } void reset() { *this = {}; } @@ -112,14 +122,19 @@ private: size_t getLayerLength() const { return mLength; } // Gets the hole punch candidate for this Run. const CachedSet* getHolePunchCandidate() const { return mHolePunchCandidate; } + const CachedSet* getBlurringLayer() const { return mBlurringLayer; } private: Run(std::vector<CachedSet>::const_iterator start, size_t length, - const CachedSet* holePunchCandidate) - : mStart(start), mLength(length), mHolePunchCandidate(holePunchCandidate) {} + const CachedSet* holePunchCandidate, const CachedSet* blurringLayer) + : mStart(start), + mLength(length), + mHolePunchCandidate(holePunchCandidate), + mBlurringLayer(blurringLayer) {} const std::vector<CachedSet>::const_iterator mStart; const size_t mLength; const CachedSet* const mHolePunchCandidate; + const CachedSet* const mBlurringLayer; friend class Builder; }; @@ -138,7 +153,6 @@ private: std::chrono::steady_clock::time_point mLastGeometryUpdate; std::vector<CachedSet> mLayers; - std::optional<CachedSet> mNewCachedSet; // Statistics size_t mUnflattenedDisplayCost = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h index fef0dfb700..13b878192b 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h @@ -231,6 +231,7 @@ public: bool hasBlurBehind() const { return mBackgroundBlurRadius.get() > 0 || !mBlurRegions.get().empty(); } + int32_t getBackgroundBlurRadius() const { return mBackgroundBlurRadius.get(); } hardware::graphics::composer::hal::Composition getCompositionType() const { return mCompositionType.get(); } @@ -239,6 +240,15 @@ public: void resetFramesSinceBufferUpdate() { mFramesSinceBufferUpdate = 0; } int64_t getFramesSinceBufferUpdate() const { return mFramesSinceBufferUpdate; } + ui::Dataspace getDataspace() const { return mOutputDataspace.get(); } + + bool isHdr() const { + const ui::Dataspace transfer = + static_cast<ui::Dataspace>(getDataspace() & ui::Dataspace::TRANSFER_MASK); + return (transfer == ui::Dataspace::TRANSFER_ST2084 || + transfer == ui::Dataspace::TRANSFER_HLG); + } + void dump(std::string& result) const; std::optional<std::string> compare(const LayerState& other) const; diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp index 953eb76b63..ae1336ec9d 100644 --- a/services/surfaceflinger/CompositionEngine/src/Display.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp @@ -50,36 +50,14 @@ std::shared_ptr<Display> createDisplay( Display::~Display() = default; void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) { - mIsVirtual = !args.physical; + mId = args.id; + mIsVirtual = !args.connectionType; mPowerAdvisor = args.powerAdvisor; editState().isSecure = args.isSecure; editState().displaySpace.bounds = Rect(args.pixels); setLayerStackFilter(args.layerStackId, - args.physical && - args.physical->type == ui::DisplayConnectionType::Internal); + args.connectionType == ui::DisplayConnectionType::Internal); setName(args.name); - mGpuVirtualDisplayIdGenerator = args.gpuVirtualDisplayIdGenerator; - - if (args.physical) { - mId = args.physical->id; - } else { - std::optional<DisplayId> id; - if (args.useHwcVirtualDisplays) { - id = maybeAllocateDisplayIdForVirtualDisplay(args.pixels, args.pixelFormat); - } - if (!id) { - id = mGpuVirtualDisplayIdGenerator->nextId(); - } - LOG_ALWAYS_FATAL_IF(!id, "Failed to generate display ID"); - mId = *id; - } -} - -std::optional<DisplayId> Display::maybeAllocateDisplayIdForVirtualDisplay( - ui::Size pixels, ui::PixelFormat pixelFormat) const { - auto& hwc = getCompositionEngine().getHwComposer(); - return hwc.allocateVirtualDisplay(static_cast<uint32_t>(pixels.width), - static_cast<uint32_t>(pixels.height), &pixelFormat); } bool Display::isValid() const { @@ -102,23 +80,16 @@ std::optional<DisplayId> Display::getDisplayId() const { return mId; } -void Display::setDisplayIdForTesting(DisplayId displayId) { - mId = displayId; -} - void Display::disconnect() { if (mIsDisconnected) { return; } mIsDisconnected = true; - if (const auto id = GpuVirtualDisplayId::tryCast(mId)) { - mGpuVirtualDisplayIdGenerator->markUnused(*id); - return; + + if (const auto id = HalDisplayId::tryCast(mId)) { + getCompositionEngine().getHwComposer().disconnectDisplay(*id); } - const auto halDisplayId = HalDisplayId::tryCast(mId); - LOG_FATAL_IF(!halDisplayId); - getCompositionEngine().getHwComposer().disconnectDisplay(*halDisplayId); } void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) { @@ -344,8 +315,8 @@ void Display::applyClientTargetRequests(const ClientTargetProperty& clientTarget if (clientTargetProperty.dataspace == ui::Dataspace::UNKNOWN) { return; } - auto outputState = editState(); - outputState.dataspace = clientTargetProperty.dataspace; + + editState().dataspace = clientTargetProperty.dataspace; getRenderSurface()->setBufferDataspace(clientTargetProperty.dataspace); getRenderSurface()->setBufferPixelFormat(clientTargetProperty.pixelFormat); } diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index 088a400877..e9a8b912f2 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -1188,19 +1188,6 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( !layerState.visibleRegion.subtract(layerState.shadowRegion).isEmpty(); if (clientComposition || clearClientComposition) { - compositionengine::LayerFE::ClientCompositionTargetSettings - targetSettings{.clip = clip, - .needsFiltering = - layer->needsFiltering() || outputState.needsFiltering, - .isSecure = outputState.isSecure, - .supportsProtectedContent = supportsProtectedContent, - .clearRegion = clientComposition ? clearRegion : stubRegion, - .viewport = outputState.layerStackSpace.content, - .dataspace = outputDataspace, - .realContentIsVisible = realContentIsVisible, - .clearContent = !clientComposition, - .disableBlurs = disableBlurs}; - std::vector<LayerFE::LayerSettings> results; if (layer->getState().overrideInfo.buffer != nullptr) { if (layer->getState().overrideInfo.buffer->getBuffer() != previousOverrideBuffer) { @@ -1212,6 +1199,25 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( layer->getLayerFE().getDebugName()); } } else { + LayerFE::ClientCompositionTargetSettings::BlurSetting blurSetting = disableBlurs + ? LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled + : (layer->getState().overrideInfo.disableBackgroundBlur + ? LayerFE::ClientCompositionTargetSettings::BlurSetting:: + BlurRegionsOnly + : LayerFE::ClientCompositionTargetSettings::BlurSetting:: + Enabled); + compositionengine::LayerFE::ClientCompositionTargetSettings + targetSettings{.clip = clip, + .needsFiltering = layer->needsFiltering() || + outputState.needsFiltering, + .isSecure = outputState.isSecure, + .supportsProtectedContent = supportsProtectedContent, + .clearRegion = clientComposition ? clearRegion : stubRegion, + .viewport = outputState.layerStackSpace.content, + .dataspace = outputDataspace, + .realContentIsVisible = realContentIsVisible, + .clearContent = !clientComposition, + .blurSetting = blurSetting}; results = layerFE.prepareClientCompositionList(targetSettings); if (realContentIsVisible && !results.empty()) { layer->editState().clientCompositionTimestamp = systemTime(); diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp index b4c314c8d4..cfa740e251 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp @@ -78,6 +78,8 @@ void OutputLayerCompositionState::dump(std::string& out) const { std::string visibleRegionString; overrideInfo.visibleRegion.dump(visibleRegionString, ""); dumpVal(out, "override visible region", visibleRegionString); + dumpVal(out, "override peekThroughLayer", overrideInfo.peekThroughLayer); + dumpVal(out, "override disableBackgroundBlur", overrideInfo.disableBackgroundBlur); if (hwc) { dumpHwc(*hwc, out); diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp index b61daeb7cd..9a294c766e 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp @@ -25,6 +25,7 @@ #include <math/HashCombine.h> #include <renderengine/DisplaySettings.h> #include <renderengine/RenderEngine.h> +#include <utils/Trace.h> #include <utils/Trace.h> @@ -184,7 +185,7 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, .dataspace = outputDataspace, .realContentIsVisible = true, .clearContent = false, - .disableBlurs = false, + .blurSetting = LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; std::vector<renderengine::LayerSettings> layerSettings; @@ -201,6 +202,24 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, std::transform(layerSettings.cbegin(), layerSettings.cend(), std::back_inserter(layerSettingsPointers), [](const renderengine::LayerSettings& settings) { return &settings; }); + + renderengine::LayerSettings blurLayerSettings; + if (mBlurLayer) { + auto blurSettings = targetSettings; + blurSettings.blurSetting = + LayerFE::ClientCompositionTargetSettings::BlurSetting::BackgroundBlurOnly; + auto clientCompositionList = + mBlurLayer->getOutputLayer()->getLayerFE().prepareClientCompositionList( + blurSettings); + blurLayerSettings = clientCompositionList.back(); + // This mimics Layer::prepareClearClientComposition + blurLayerSettings.skipContentDraw = true; + blurLayerSettings.name = std::string("blur layer"); + // Clear out the shadow settings + blurLayerSettings.shadow = {}; + layerSettingsPointers.push_back(&blurLayerSettings); + } + renderengine::LayerSettings holePunchSettings; if (mHolePunchLayer) { auto clientCompositionList = @@ -209,7 +228,6 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, // Assume that the final layer contains the buffer that we want to // replace with a hole punch. holePunchSettings = clientCompositionList.back(); - LOG_ALWAYS_FATAL_IF(!holePunchSettings.source.buffer.buffer, "Expected to have a buffer!"); // This mimics Layer::prepareClearClientComposition holePunchSettings.source.buffer.buffer = nullptr; holePunchSettings.source.solidColor = half3(0.0f, 0.0f, 0.0f); @@ -315,10 +333,23 @@ void CachedSet::addHolePunchLayerIfFeasible(const CachedSet& holePunchLayer, boo } } +void CachedSet::addBackgroundBlurLayer(const CachedSet& blurLayer) { + mBlurLayer = blurLayer.getFirstLayer().getState(); +} + compositionengine::OutputLayer* CachedSet::getHolePunchLayer() const { return mHolePunchLayer ? mHolePunchLayer->getOutputLayer() : nullptr; } +compositionengine::OutputLayer* CachedSet::getBlurLayer() const { + return mBlurLayer ? mBlurLayer->getOutputLayer() : nullptr; +} + +bool CachedSet::hasHdrLayers() const { + return std::any_of(mLayers.cbegin(), mLayers.cend(), + [](const Layer& layer) { return layer.getState()->isHdr(); }); +} + void CachedSet::dump(std::string& result) const { const auto now = std::chrono::steady_clock::now(); diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp index 2def99d649..fb24fa4160 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp @@ -245,6 +245,12 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers auto currentLayerIter = mLayers.begin(); auto incomingLayerIter = layers.begin(); + + // If not null, this represents the layer that is blurring the layer before + // currentLayerIter. The blurring was stored in the override buffer, so the + // layer that requests the blur no longer needs to do any blurring. + compositionengine::OutputLayer* priorBlurLayer = nullptr; + while (incomingLayerIter != layers.end()) { if (mNewCachedSet && mNewCachedSet->getFirstLayer().getState()->getId() == (*incomingLayerIter)->getId()) { @@ -259,6 +265,8 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers auto* peekThroughLayer = mNewCachedSet->getHolePunchLayer(); const size_t layerCount = currentLayerIter->getLayerCount(); for (size_t i = 0; i < layerCount; ++i) { + bool disableBlur = priorBlurLayer && + priorBlurLayer == (*incomingLayerIter)->getOutputLayer(); OutputLayer::CompositionState& state = (*incomingLayerIter)->getOutputLayer()->editState(); state.overrideInfo = { @@ -270,6 +278,7 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers .damageRegion = Region::INVALID_REGION, .visibleRegion = mNewCachedSet->getVisibleRegion(), .peekThroughLayer = peekThroughLayer, + .disableBackgroundBlur = disableBlur, }; ++incomingLayerIter; } @@ -281,6 +290,7 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers skipCount -= layerCount; } + priorBlurLayer = mNewCachedSet->getBlurLayer(); merged.emplace_back(std::move(*mNewCachedSet)); mNewCachedSet = std::nullopt; continue; @@ -295,6 +305,8 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers const size_t layerCount = currentLayerIter->getLayerCount(); auto* peekThroughLayer = currentLayerIter->getHolePunchLayer(); for (size_t i = 0; i < layerCount; ++i) { + bool disableBlur = + priorBlurLayer && priorBlurLayer == (*incomingLayerIter)->getOutputLayer(); OutputLayer::CompositionState& state = (*incomingLayerIter)->getOutputLayer()->editState(); state.overrideInfo = { @@ -306,6 +318,7 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers .damageRegion = Region(), .visibleRegion = currentLayerIter->getVisibleRegion(), .peekThroughLayer = peekThroughLayer, + .disableBackgroundBlur = disableBlur, }; ++incomingLayerIter; } @@ -313,15 +326,26 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers // Break the current layer into its constituent layers ++mInvalidatedCachedSetAges[currentLayerIter->getAge()]; for (CachedSet& layer : currentLayerIter->decompose()) { + bool disableBlur = + priorBlurLayer && priorBlurLayer == (*incomingLayerIter)->getOutputLayer(); + OutputLayer::CompositionState& state = + (*incomingLayerIter)->getOutputLayer()->editState(); + state.overrideInfo.disableBackgroundBlur = disableBlur; layer.updateAge(now); merged.emplace_back(layer); ++incomingLayerIter; } } else { + bool disableBlur = + priorBlurLayer && priorBlurLayer == (*incomingLayerIter)->getOutputLayer(); + OutputLayer::CompositionState& state = + (*incomingLayerIter)->getOutputLayer()->editState(); + state.overrideInfo.disableBackgroundBlur = disableBlur; currentLayerIter->updateAge(now); merged.emplace_back(*currentLayerIter); ++incomingLayerIter; } + priorBlurLayer = currentLayerIter->getBlurLayer(); ++currentLayerIter; } @@ -344,7 +368,8 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { for (auto currentSet = mLayers.cbegin(); currentSet != mLayers.cend(); ++currentSet) { const bool layerIsInactive = now - currentSet->getLastUpdate() > kActiveLayerTimeout; const bool layerHasBlur = currentSet->hasBlurBehind(); - if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur)) { + if (layerIsInactive && (firstLayer || runHasFirstLayer || !layerHasBlur) && + !currentSet->hasHdrLayers()) { if (isPartOfRun) { builder.append(currentSet->getLayerCount()); } else { @@ -361,6 +386,15 @@ std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const { } } else if (isPartOfRun) { builder.setHolePunchCandidate(&(*currentSet)); + + // If we're here then this blur layer recently had an active buffer updating, meaning + // that there is exactly one layer. Blur radius currently is part of layer stack + // geometry, so we're also guaranteed that the background blur radius hasn't changed for + // at least as long as this new inactive cached set. + if (runHasFirstLayer && layerHasBlur && + currentSet->getFirstLayer().getBackgroundBlurRadius() > 0) { + builder.setBlurringLayer(&(*currentSet)); + } if (auto run = builder.validateAndBuild(); run) { runs.push_back(*run); } @@ -422,6 +456,10 @@ void Flattener::buildCachedSets(time_point now) { mNewCachedSet->append(*currentSet); } + if (bestRun->getBlurringLayer()) { + mNewCachedSet->addBackgroundBlurLayer(*bestRun->getBlurringLayer()); + } + if (mEnableHolePunch && bestRun->getHolePunchCandidate() && bestRun->getHolePunchCandidate()->requiresHolePunch()) { // Add the pip layer to mNewCachedSet, but in a special way - it should diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp index e12cb57feb..db9437b9a8 100644 --- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp @@ -14,10 +14,6 @@ * limitations under the License. */ -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wextra" - #include <cmath> #include <compositionengine/DisplayColorProfileCreationArgs.h> @@ -60,12 +56,12 @@ using testing::Sequence; using testing::SetArgPointee; using testing::StrictMock; -constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId{42}; -// TODO(b/160679868) Use VirtualDisplayId -constexpr PhysicalDisplayId VIRTUAL_DISPLAY_ID = PhysicalDisplayId{43}; -constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920; -constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080; -constexpr int32_t DEFAULT_LAYER_STACK = 123; +constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(123u); +constexpr HalVirtualDisplayId HAL_VIRTUAL_DISPLAY_ID{456u}; +constexpr GpuVirtualDisplayId GPU_VIRTUAL_DISPLAY_ID{789u}; + +const ui::Size DEFAULT_RESOLUTION{1920, 1080}; +constexpr uint32_t DEFAULT_LAYER_STACK = 42; struct Layer { Layer() { @@ -94,8 +90,6 @@ struct DisplayTestCommon : public testing::Test { public: using impl::Display::injectOutputLayerForTest; virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0; - - using impl::Display::maybeAllocateDisplayIdForVirtualDisplay; }; // Uses a special implementation with key internal member functions set up @@ -169,21 +163,19 @@ struct DisplayTestCommon : public testing::Test { DisplayCreationArgs getDisplayCreationArgsForPhysicalHWCDisplay() { return DisplayCreationArgsBuilder() - .setPhysical({DEFAULT_DISPLAY_ID, ui::DisplayConnectionType::Internal}) - .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) - .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888)) + .setId(DEFAULT_DISPLAY_ID) + .setConnectionType(ui::DisplayConnectionType::Internal) + .setPixels(DEFAULT_RESOLUTION) .setIsSecure(true) .setLayerStackId(DEFAULT_LAYER_STACK) .setPowerAdvisor(&mPowerAdvisor) .build(); } - DisplayCreationArgs getDisplayCreationArgsForNonHWCVirtualDisplay() { + DisplayCreationArgs getDisplayCreationArgsForGpuVirtualDisplay() { return DisplayCreationArgsBuilder() - .setUseHwcVirtualDisplays(false) - .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator) - .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) - .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888)) + .setId(GPU_VIRTUAL_DISPLAY_ID) + .setPixels(DEFAULT_RESOLUTION) .setIsSecure(false) .setLayerStackId(DEFAULT_LAYER_STACK) .setPowerAdvisor(&mPowerAdvisor) @@ -195,7 +187,6 @@ struct DisplayTestCommon : public testing::Test { StrictMock<renderengine::mock::RenderEngine> mRenderEngine; StrictMock<mock::CompositionEngine> mCompositionEngine; sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>(); - RandomDisplayIdGenerator<GpuVirtualDisplayId> mGpuDisplayIdGenerator; }; struct PartialMockDisplayTestCommon : public DisplayTestCommon { @@ -247,9 +238,9 @@ TEST_F(DisplayCreationTest, createPhysicalInternalDisplay) { EXPECT_EQ(DEFAULT_DISPLAY_ID, display->getId()); } -TEST_F(DisplayCreationTest, createNonHwcVirtualDisplay) { - auto display = impl::createDisplay(mCompositionEngine, - getDisplayCreationArgsForNonHWCVirtualDisplay()); +TEST_F(DisplayCreationTest, createGpuVirtualDisplay) { + auto display = + impl::createDisplay(mCompositionEngine, getDisplayCreationArgsForGpuVirtualDisplay()); EXPECT_FALSE(display->isSecure()); EXPECT_TRUE(display->isVirtual()); EXPECT_TRUE(GpuVirtualDisplayId::tryCast(display->getId())); @@ -262,17 +253,15 @@ TEST_F(DisplayCreationTest, createNonHwcVirtualDisplay) { using DisplaySetConfigurationTest = PartialMockDisplayTestCommon; TEST_F(DisplaySetConfigurationTest, configuresInternalSecurePhysicalDisplay) { - mDisplay->setConfiguration( - DisplayCreationArgsBuilder() - .setUseHwcVirtualDisplays(true) - .setPhysical({DEFAULT_DISPLAY_ID, ui::DisplayConnectionType::Internal}) - .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) - .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888)) - .setIsSecure(true) - .setLayerStackId(DEFAULT_LAYER_STACK) - .setPowerAdvisor(&mPowerAdvisor) - .setName(getDisplayNameFromCurrentTest()) - .build()); + mDisplay->setConfiguration(DisplayCreationArgsBuilder() + .setId(DEFAULT_DISPLAY_ID) + .setConnectionType(ui::DisplayConnectionType::Internal) + .setPixels(DEFAULT_RESOLUTION) + .setIsSecure(true) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .setName(getDisplayNameFromCurrentTest()) + .build()); EXPECT_EQ(DEFAULT_DISPLAY_ID, mDisplay->getId()); EXPECT_TRUE(mDisplay->isSecure()); @@ -283,17 +272,15 @@ TEST_F(DisplaySetConfigurationTest, configuresInternalSecurePhysicalDisplay) { } TEST_F(DisplaySetConfigurationTest, configuresExternalInsecurePhysicalDisplay) { - mDisplay->setConfiguration( - DisplayCreationArgsBuilder() - .setUseHwcVirtualDisplays(true) - .setPhysical({DEFAULT_DISPLAY_ID, ui::DisplayConnectionType::External}) - .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) - .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888)) - .setIsSecure(false) - .setLayerStackId(DEFAULT_LAYER_STACK) - .setPowerAdvisor(&mPowerAdvisor) - .setName(getDisplayNameFromCurrentTest()) - .build()); + mDisplay->setConfiguration(DisplayCreationArgsBuilder() + .setId(DEFAULT_DISPLAY_ID) + .setConnectionType(ui::DisplayConnectionType::External) + .setPixels(DEFAULT_RESOLUTION) + .setIsSecure(false) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .setName(getDisplayNameFromCurrentTest()) + .build()); EXPECT_EQ(DEFAULT_DISPLAY_ID, mDisplay->getId()); EXPECT_FALSE(mDisplay->isSecure()); @@ -303,52 +290,17 @@ TEST_F(DisplaySetConfigurationTest, configuresExternalInsecurePhysicalDisplay) { EXPECT_FALSE(mDisplay->isValid()); } -TEST_F(DisplaySetConfigurationTest, configuresHwcBackedVirtualDisplay) { - EXPECT_CALL(mHwComposer, - allocateVirtualDisplay(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH, - Pointee(Eq(static_cast<ui::PixelFormat>( - PIXEL_FORMAT_RGBA_8888))))) - .WillOnce(Return(VIRTUAL_DISPLAY_ID)); - - mDisplay->setConfiguration( - DisplayCreationArgsBuilder() - .setUseHwcVirtualDisplays(true) - .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) - .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888)) - .setIsSecure(false) - .setLayerStackId(DEFAULT_LAYER_STACK) - .setPowerAdvisor(&mPowerAdvisor) - .setName(getDisplayNameFromCurrentTest()) - .build()); - - EXPECT_EQ(VIRTUAL_DISPLAY_ID, mDisplay->getId()); - EXPECT_FALSE(mDisplay->isSecure()); - EXPECT_TRUE(mDisplay->isVirtual()); - EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId); - EXPECT_FALSE(mDisplay->getState().layerStackInternal); - EXPECT_FALSE(mDisplay->isValid()); -} - -TEST_F(DisplaySetConfigurationTest, configuresNonHwcBackedVirtualDisplayIfHwcAllocationFails) { - EXPECT_CALL(mHwComposer, - allocateVirtualDisplay(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH, - Pointee(Eq(static_cast<ui::PixelFormat>( - PIXEL_FORMAT_RGBA_8888))))) - .WillOnce(Return(std::nullopt)); - - mDisplay->setConfiguration( - DisplayCreationArgsBuilder() - .setUseHwcVirtualDisplays(true) - .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator) - .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) - .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888)) - .setIsSecure(false) - .setLayerStackId(DEFAULT_LAYER_STACK) - .setPowerAdvisor(&mPowerAdvisor) - .setName(getDisplayNameFromCurrentTest()) - .build()); - - EXPECT_TRUE(GpuVirtualDisplayId::tryCast(mDisplay->getId())); +TEST_F(DisplaySetConfigurationTest, configuresHalVirtualDisplay) { + mDisplay->setConfiguration(DisplayCreationArgsBuilder() + .setId(HAL_VIRTUAL_DISPLAY_ID) + .setPixels(DEFAULT_RESOLUTION) + .setIsSecure(false) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .setName(getDisplayNameFromCurrentTest()) + .build()); + + EXPECT_EQ(HAL_VIRTUAL_DISPLAY_ID, mDisplay->getId()); EXPECT_FALSE(mDisplay->isSecure()); EXPECT_TRUE(mDisplay->isVirtual()); EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId); @@ -356,20 +308,17 @@ TEST_F(DisplaySetConfigurationTest, configuresNonHwcBackedVirtualDisplayIfHwcAll EXPECT_FALSE(mDisplay->isValid()); } -TEST_F(DisplaySetConfigurationTest, configuresNonHwcBackedVirtualDisplayIfShouldNotUseHwc) { - mDisplay->setConfiguration( - DisplayCreationArgsBuilder() - .setUseHwcVirtualDisplays(false) - .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator) - .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH)) - .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888)) - .setIsSecure(false) - .setLayerStackId(DEFAULT_LAYER_STACK) - .setPowerAdvisor(&mPowerAdvisor) - .setName(getDisplayNameFromCurrentTest()) - .build()); - - EXPECT_TRUE(GpuVirtualDisplayId::tryCast(mDisplay->getId())); +TEST_F(DisplaySetConfigurationTest, configuresGpuVirtualDisplay) { + mDisplay->setConfiguration(DisplayCreationArgsBuilder() + .setId(GPU_VIRTUAL_DISPLAY_ID) + .setPixels(DEFAULT_RESOLUTION) + .setIsSecure(false) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&mPowerAdvisor) + .setName(getDisplayNameFromCurrentTest()) + .build()); + + EXPECT_EQ(GPU_VIRTUAL_DISPLAY_ID, mDisplay->getId()); EXPECT_FALSE(mDisplay->isSecure()); EXPECT_TRUE(mDisplay->isVirtual()); EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId); @@ -476,7 +425,7 @@ TEST_F(DisplaySetColorModeTest, setsModeUnlessNoChange) { TEST_F(DisplaySetColorModeTest, doesNothingForVirtualDisplay) { using ColorProfile = Output::ColorProfile; - auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); + auto args = getDisplayCreationArgsForGpuVirtualDisplay(); std::shared_ptr<impl::Display> virtualDisplay = impl::createDisplay(mCompositionEngine, args); mock::DisplayColorProfile* colorProfile = new StrictMock<mock::DisplayColorProfile>(); @@ -521,7 +470,11 @@ using DisplayCreateRenderSurfaceTest = PartialMockDisplayTestCommon; TEST_F(DisplayCreateRenderSurfaceTest, setsRenderSurface) { EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL)).WillRepeatedly(Return(NO_ERROR)); EXPECT_TRUE(mDisplay->getRenderSurface() == nullptr); - mDisplay->createRenderSurface(RenderSurfaceCreationArgs{640, 480, mNativeWindow, nullptr}); + mDisplay->createRenderSurface(RenderSurfaceCreationArgsBuilder() + .setDisplayWidth(640) + .setDisplayHeight(480) + .setNativeWindow(mNativeWindow) + .build()); EXPECT_TRUE(mDisplay->getRenderSurface() != nullptr); } @@ -551,25 +504,25 @@ TEST_F(DisplayCreateOutputLayerTest, setsHwcLayer) { using DisplaySetReleasedLayersTest = DisplayWithLayersTestCommon; -TEST_F(DisplaySetReleasedLayersTest, doesNothingIfNotHwcDisplay) { - auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); - std::shared_ptr<impl::Display> nonHwcDisplay = impl::createDisplay(mCompositionEngine, args); +TEST_F(DisplaySetReleasedLayersTest, doesNothingIfGpuDisplay) { + auto args = getDisplayCreationArgsForGpuVirtualDisplay(); + std::shared_ptr<impl::Display> gpuDisplay = impl::createDisplay(mCompositionEngine, args); sp<mock::LayerFE> layerXLayerFE = new StrictMock<mock::LayerFE>(); { Output::ReleasedLayers releasedLayers; releasedLayers.emplace_back(layerXLayerFE); - nonHwcDisplay->setReleasedLayers(std::move(releasedLayers)); + gpuDisplay->setReleasedLayers(std::move(releasedLayers)); } CompositionRefreshArgs refreshArgs; refreshArgs.layersWithQueuedFrames.push_back(layerXLayerFE); - nonHwcDisplay->setReleasedLayers(refreshArgs); + gpuDisplay->setReleasedLayers(refreshArgs); - const auto& releasedLayers = nonHwcDisplay->getReleasedLayersForTest(); - ASSERT_EQ(1, releasedLayers.size()); + const auto& releasedLayers = gpuDisplay->getReleasedLayersForTest(); + ASSERT_EQ(1u, releasedLayers.size()); } TEST_F(DisplaySetReleasedLayersTest, doesNothingIfNoLayersWithQueuedFrames) { @@ -585,7 +538,7 @@ TEST_F(DisplaySetReleasedLayersTest, doesNothingIfNoLayersWithQueuedFrames) { mDisplay->setReleasedLayers(refreshArgs); const auto& releasedLayers = mDisplay->getReleasedLayersForTest(); - ASSERT_EQ(1, releasedLayers.size()); + ASSERT_EQ(1u, releasedLayers.size()); } TEST_F(DisplaySetReleasedLayersTest, setReleasedLayers) { @@ -599,7 +552,7 @@ TEST_F(DisplaySetReleasedLayersTest, setReleasedLayers) { mDisplay->setReleasedLayers(refreshArgs); const auto& releasedLayers = mDisplay->getReleasedLayersForTest(); - ASSERT_EQ(2, releasedLayers.size()); + ASSERT_EQ(2u, releasedLayers.size()); ASSERT_EQ(mLayer1.layerFE.get(), releasedLayers[0].promote().get()); ASSERT_EQ(mLayer2.layerFE.get(), releasedLayers[1].promote().get()); } @@ -610,15 +563,15 @@ TEST_F(DisplaySetReleasedLayersTest, setReleasedLayers) { using DisplayChooseCompositionStrategyTest = PartialMockDisplayTestCommon; -TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfNotAHwcDisplay) { - auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); - std::shared_ptr<Display> nonHwcDisplay = +TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfGpuDisplay) { + auto args = getDisplayCreationArgsForGpuVirtualDisplay(); + std::shared_ptr<Display> gpuDisplay = createPartialMockDisplay<Display>(mCompositionEngine, args); - EXPECT_TRUE(GpuVirtualDisplayId::tryCast(nonHwcDisplay->getId())); + EXPECT_TRUE(GpuVirtualDisplayId::tryCast(gpuDisplay->getId())); - nonHwcDisplay->chooseCompositionStrategy(); + gpuDisplay->chooseCompositionStrategy(); - auto& state = nonHwcDisplay->getState(); + auto& state = gpuDisplay->getState(); EXPECT_TRUE(state.usesClientComposition); EXPECT_FALSE(state.usesDeviceComposition); } @@ -700,12 +653,12 @@ TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) { using DisplayGetSkipColorTransformTest = DisplayWithLayersTestCommon; -TEST_F(DisplayGetSkipColorTransformTest, checksCapabilityIfNonHwcDisplay) { +TEST_F(DisplayGetSkipColorTransformTest, checksCapabilityIfGpuDisplay) { EXPECT_CALL(mHwComposer, hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM)) .WillOnce(Return(true)); - auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); - auto nonHwcDisplay{impl::createDisplay(mCompositionEngine, args)}; - EXPECT_TRUE(nonHwcDisplay->getSkipColorTransform()); + auto args = getDisplayCreationArgsForGpuVirtualDisplay(); + auto gpuDisplay{impl::createDisplay(mCompositionEngine, args)}; + EXPECT_TRUE(gpuDisplay->getSkipColorTransform()); } TEST_F(DisplayGetSkipColorTransformTest, checksDisplayCapability) { @@ -847,16 +800,39 @@ TEST_F(DisplayApplyLayerRequestsToLayersTest, appliesDeviceLayerRequests) { } /* + * Display::applyClientTargetRequests() + */ + +using DisplayApplyClientTargetRequests = DisplayWithLayersTestCommon; + +TEST_F(DisplayApplyLayerRequestsToLayersTest, applyClientTargetRequests) { + Display::ClientTargetProperty clientTargetProperty = { + .pixelFormat = hal::PixelFormat::RGB_565, + .dataspace = hal::Dataspace::STANDARD_BT470M, + }; + + mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>(); + mDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); + + EXPECT_CALL(*renderSurface, setBufferPixelFormat(clientTargetProperty.pixelFormat)); + EXPECT_CALL(*renderSurface, setBufferDataspace(clientTargetProperty.dataspace)); + mDisplay->applyClientTargetRequests(clientTargetProperty); + + auto& state = mDisplay->getState(); + EXPECT_EQ(clientTargetProperty.dataspace, state.dataspace); +} + +/* * Display::presentAndGetFrameFences() */ using DisplayPresentAndGetFrameFencesTest = DisplayWithLayersTestCommon; -TEST_F(DisplayPresentAndGetFrameFencesTest, returnsNoFencesOnNonHwcDisplay) { - auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); - auto nonHwcDisplay{impl::createDisplay(mCompositionEngine, args)}; +TEST_F(DisplayPresentAndGetFrameFencesTest, returnsNoFencesOnGpuDisplay) { + auto args = getDisplayCreationArgsForGpuVirtualDisplay(); + auto gpuDisplay{impl::createDisplay(mCompositionEngine, args)}; - auto result = nonHwcDisplay->presentAndGetFrameFences(); + auto result = gpuDisplay->presentAndGetFrameFences(); ASSERT_TRUE(result.presentFence.get()); EXPECT_FALSE(result.presentFence->isValid()); @@ -885,9 +861,9 @@ TEST_F(DisplayPresentAndGetFrameFencesTest, returnsPresentAndLayerFences) { EXPECT_EQ(presentFence, result.presentFence); EXPECT_EQ(2u, result.layerFences.size()); - ASSERT_EQ(1, result.layerFences.count(&mLayer1.hwc2Layer)); + ASSERT_EQ(1u, result.layerFences.count(&mLayer1.hwc2Layer)); EXPECT_EQ(layer1Fence, result.layerFences[&mLayer1.hwc2Layer]); - ASSERT_EQ(1, result.layerFences.count(&mLayer2.hwc2Layer)); + ASSERT_EQ(1u, result.layerFences.count(&mLayer2.hwc2Layer)); EXPECT_EQ(layer2Fence, result.layerFences[&mLayer2.hwc2Layer]); } @@ -933,66 +909,66 @@ TEST_F(DisplayFinishFrameTest, doesNotSkipCompositionIfNotDirtyOnHwcDisplay) { } TEST_F(DisplayFinishFrameTest, skipsCompositionIfNotDirty) { - auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); - std::shared_ptr<impl::Display> nonHwcDisplay = impl::createDisplay(mCompositionEngine, args); + auto args = getDisplayCreationArgsForGpuVirtualDisplay(); + std::shared_ptr<impl::Display> gpuDisplay = impl::createDisplay(mCompositionEngine, args); mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>(); - nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); + gpuDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); // We expect no calls to queueBuffer if composition was skipped. EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(0); - nonHwcDisplay->editState().isEnabled = true; - nonHwcDisplay->editState().usesClientComposition = false; - nonHwcDisplay->editState().layerStackSpace.content = Rect(0, 0, 1, 1); - nonHwcDisplay->editState().dirtyRegion = Region::INVALID_REGION; + gpuDisplay->editState().isEnabled = true; + gpuDisplay->editState().usesClientComposition = false; + gpuDisplay->editState().layerStackSpace.content = Rect(0, 0, 1, 1); + gpuDisplay->editState().dirtyRegion = Region::INVALID_REGION; CompositionRefreshArgs refreshArgs; refreshArgs.repaintEverything = false; - nonHwcDisplay->finishFrame(refreshArgs); + gpuDisplay->finishFrame(refreshArgs); } TEST_F(DisplayFinishFrameTest, performsCompositionIfDirty) { - auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); - std::shared_ptr<impl::Display> nonHwcDisplay = impl::createDisplay(mCompositionEngine, args); + auto args = getDisplayCreationArgsForGpuVirtualDisplay(); + std::shared_ptr<impl::Display> gpuDisplay = impl::createDisplay(mCompositionEngine, args); mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>(); - nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); + gpuDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); // We expect a single call to queueBuffer when composition is not skipped. EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1); - nonHwcDisplay->editState().isEnabled = true; - nonHwcDisplay->editState().usesClientComposition = false; - nonHwcDisplay->editState().layerStackSpace.content = Rect(0, 0, 1, 1); - nonHwcDisplay->editState().dirtyRegion = Region(Rect(0, 0, 1, 1)); + gpuDisplay->editState().isEnabled = true; + gpuDisplay->editState().usesClientComposition = false; + gpuDisplay->editState().layerStackSpace.content = Rect(0, 0, 1, 1); + gpuDisplay->editState().dirtyRegion = Region(Rect(0, 0, 1, 1)); CompositionRefreshArgs refreshArgs; refreshArgs.repaintEverything = false; - nonHwcDisplay->finishFrame(refreshArgs); + gpuDisplay->finishFrame(refreshArgs); } TEST_F(DisplayFinishFrameTest, performsCompositionIfRepaintEverything) { - auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); - std::shared_ptr<impl::Display> nonHwcDisplay = impl::createDisplay(mCompositionEngine, args); + auto args = getDisplayCreationArgsForGpuVirtualDisplay(); + std::shared_ptr<impl::Display> gpuDisplay = impl::createDisplay(mCompositionEngine, args); mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>(); - nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); + gpuDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); // We expect a single call to queueBuffer when composition is not skipped. EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1); - nonHwcDisplay->editState().isEnabled = true; - nonHwcDisplay->editState().usesClientComposition = false; - nonHwcDisplay->editState().layerStackSpace.content = Rect(0, 0, 1, 1); - nonHwcDisplay->editState().dirtyRegion = Region::INVALID_REGION; + gpuDisplay->editState().isEnabled = true; + gpuDisplay->editState().usesClientComposition = false; + gpuDisplay->editState().layerStackSpace.content = Rect(0, 0, 1, 1); + gpuDisplay->editState().dirtyRegion = Region::INVALID_REGION; CompositionRefreshArgs refreshArgs; refreshArgs.repaintEverything = true; - nonHwcDisplay->finishFrame(refreshArgs); + gpuDisplay->finishFrame(refreshArgs); } /* @@ -1017,23 +993,26 @@ struct DisplayFunctionalTest : public testing::Test { NiceMock<mock::CompositionEngine> mCompositionEngine; sp<mock::NativeWindow> mNativeWindow = new NiceMock<mock::NativeWindow>(); sp<mock::DisplaySurface> mDisplaySurface = new NiceMock<mock::DisplaySurface>(); + std::shared_ptr<Display> mDisplay = impl::createDisplayTemplated< Display>(mCompositionEngine, DisplayCreationArgsBuilder() - .setPhysical({DEFAULT_DISPLAY_ID, ui::DisplayConnectionType::Internal}) - .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) - .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888)) + .setId(DEFAULT_DISPLAY_ID) + .setConnectionType(ui::DisplayConnectionType::Internal) + .setPixels(DEFAULT_RESOLUTION) .setIsSecure(true) .setLayerStackId(DEFAULT_LAYER_STACK) .setPowerAdvisor(&mPowerAdvisor) - .build() + .build()); - ); impl::RenderSurface* mRenderSurface = new impl::RenderSurface{mCompositionEngine, *mDisplay, - RenderSurfaceCreationArgs{DEFAULT_DISPLAY_WIDTH, - DEFAULT_DISPLAY_HEIGHT, mNativeWindow, - mDisplaySurface}}; + RenderSurfaceCreationArgsBuilder() + .setDisplayWidth(DEFAULT_RESOLUTION.width) + .setDisplayHeight(DEFAULT_RESOLUTION.height) + .setNativeWindow(mNativeWindow) + .setDisplaySurface(mDisplaySurface) + .build()}; }; TEST_F(DisplayFunctionalTest, postFramebufferCriticalCallsAreOrdered) { @@ -1049,6 +1028,3 @@ TEST_F(DisplayFunctionalTest, postFramebufferCriticalCallsAreOrdered) { } // namespace } // namespace android::compositionengine - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wextra"
\ No newline at end of file diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h index cd2d09e3db..64cbea91a3 100644 --- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h @@ -39,14 +39,17 @@ public: HWComposer(); ~HWComposer() override; - MOCK_METHOD2(setConfiguration, void(HWC2::ComposerCallback*, int32_t)); + MOCK_METHOD1(setCallback, void(HWC2::ComposerCallback*)); MOCK_CONST_METHOD3(getDisplayIdentificationData, bool(hal::HWDisplayId, uint8_t*, DisplayIdentificationData*)); MOCK_CONST_METHOD1(hasCapability, bool(hal::Capability)); MOCK_CONST_METHOD2(hasDisplayCapability, bool(HalDisplayId, hal::DisplayCapability)); - MOCK_METHOD3(allocateVirtualDisplay, - std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*)); + MOCK_CONST_METHOD0(getMaxVirtualDisplayCount, size_t()); + MOCK_CONST_METHOD0(getMaxVirtualDisplayDimension, size_t()); + MOCK_METHOD4(allocateVirtualDisplay, + bool(HalVirtualDisplayId, ui::Size, ui::PixelFormat*, + std::optional<PhysicalDisplayId>)); MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId)); MOCK_METHOD1(createLayer, std::shared_ptr<HWC2::Layer>(HalDisplayId)); MOCK_METHOD4(getDeviceCompositionChanges, diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index 6677f408ad..52e042821a 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -3784,6 +3784,46 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositi EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp); } +MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") { + *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n"; + *result_listener << "expected " << expectedBlurSetting << "\n"; + *result_listener << "actual " << arg.blurSetting << "\n"; + + return expectedBlurSetting == arg.blurSetting; +} + +TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) { + LayerFE::LayerSettings mShadowSettings; + mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f}; + + mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true; + + EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_)) + .WillOnce(Return(std::vector<LayerFE::LayerSettings>())); + EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_)) + .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings}))); + EXPECT_CALL(*mLayers[2].mLayerFE, + prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq( + LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly))) + .WillOnce(Return(std::vector<LayerFE::LayerSettings>( + {mShadowSettings, mLayers[2].mLayerSettings}))); + + Region accumClearRegion(Rect(10, 11, 12, 13)); + auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */, + accumClearRegion, kDisplayDataspace); + ASSERT_EQ(3u, requests.size()); + EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]); + EXPECT_EQ(mShadowSettings, requests[1]); + EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]); + + EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13)))); + + // Check that a timestamp was set for the layers that generated requests + EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp); + EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp); + EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp); +} + TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, onlyClientComposesClientComposedLayersIfNoClearingNeeded) { EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false)); @@ -3867,7 +3907,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqu kDisplayDataspace, false /* realContentIsVisible */, true /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{ Region(kDisplayFrame), @@ -3879,7 +3919,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqu kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings; @@ -3923,7 +3963,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{ Region(Rect(0, 0, 30, 30)), @@ -3935,7 +3975,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{ Region(Rect(0, 0, 40, 201)), @@ -3947,7 +3987,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings)))) @@ -3979,7 +4019,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{ Region(kDisplayFrame), @@ -3991,7 +4031,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{ Region(kDisplayFrame), @@ -4003,7 +4043,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings)))) @@ -4035,7 +4075,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{ @@ -4048,7 +4088,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{ Region(kDisplayFrame), @@ -4060,7 +4100,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings)))) @@ -4091,7 +4131,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{ Region(kDisplayFrame), @@ -4103,7 +4143,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{ Region(kDisplayFrame), @@ -4115,7 +4155,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings)))) @@ -4144,7 +4184,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{ Region(kDisplayFrame), @@ -4156,7 +4196,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{ Region(kDisplayFrame), @@ -4168,7 +4208,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings)))) @@ -4306,7 +4346,7 @@ TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenReq kOutputDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); @@ -4324,7 +4364,7 @@ TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenReq kOutputDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); @@ -4358,7 +4398,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, false /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; LayerFE::LayerSettings mShadowSettings; @@ -4404,7 +4444,7 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, kDisplayDataspace, true /* realContentIsVisible */, false /* clearContent */, - false /* disabledBlurs */, + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, }; EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false)); diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp index 9aeb290eb5..5090bb280f 100644 --- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp @@ -14,12 +14,6 @@ * limitations under the License. */ -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#include "renderengine/ExternalTexture.h" -#include "ui/GraphicBuffer.h" -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wextra" - #include <cstdarg> #include <cstdint> @@ -32,7 +26,9 @@ #include <compositionengine/mock/NativeWindow.h> #include <compositionengine/mock/OutputLayer.h> #include <gtest/gtest.h> +#include <renderengine/ExternalTexture.h> #include <renderengine/mock/RenderEngine.h> +#include <ui/GraphicBuffer.h> namespace android::compositionengine { namespace { @@ -67,9 +63,12 @@ public: sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>(); sp<mock::DisplaySurface> mDisplaySurface = new StrictMock<mock::DisplaySurface>(); impl::RenderSurface mSurface{mCompositionEngine, mDisplay, - RenderSurfaceCreationArgs{DEFAULT_DISPLAY_WIDTH, - DEFAULT_DISPLAY_HEIGHT, mNativeWindow, - mDisplaySurface}}; + RenderSurfaceCreationArgsBuilder() + .setDisplayWidth(DEFAULT_DISPLAY_WIDTH) + .setDisplayHeight(DEFAULT_DISPLAY_HEIGHT) + .setNativeWindow(mNativeWindow) + .setDisplaySurface(mDisplaySurface) + .build()}; }; /* @@ -367,11 +366,8 @@ TEST_F(RenderSurfaceTest, flipForwardsSignal) { mSurface.flip(); - EXPECT_EQ(501, mSurface.getPageFlipCount()); + EXPECT_EQ(501u, mSurface.getPageFlipCount()); } } // namespace } // namespace android::compositionengine - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wextra"
\ No newline at end of file diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp index 8f44677676..3396ec0b67 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp @@ -24,6 +24,7 @@ #include <renderengine/ExternalTexture.h> #include <renderengine/mock/RenderEngine.h> #include <ui/GraphicTypes.h> +#include <utils/Errors.h> #include <memory> namespace android::compositionengine { @@ -42,6 +43,14 @@ using impl::planner::LayerStateField; namespace { +MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") { + *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n"; + *result_listener << "expected " << expectedBlurSetting << "\n"; + *result_listener << "actual " << arg.blurSetting << "\n"; + + return expectedBlurSetting == arg.blurSetting; +} + class CachedSetTest : public testing::Test { public: CachedSetTest() = default; @@ -548,6 +557,56 @@ TEST_F(CachedSetTest, addHolePunch) { cachedSet.render(mRenderEngine, mOutputState); } +TEST_F(CachedSetTest, addHolePunch_noBuffer) { + // Same as addHolePunch, except that clientCompList3 does not contain a + // buffer. This imitates the case where the buffer had protected content, so + // BufferLayer did not add it to the LayerSettings. This should not assert. + mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5); + CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get(); + sp<mock::LayerFE> layerFE1 = mTestLayers[0]->layerFE; + + CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get(); + sp<mock::LayerFE> layerFE2 = mTestLayers[1]->layerFE; + + CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get(); + sp<mock::LayerFE> layerFE3 = mTestLayers[2]->layerFE; + + CachedSet cachedSet(layer1); + cachedSet.addLayer(layer2.getState(), kStartTime + 10ms); + + cachedSet.addHolePunchLayerIfFeasible(layer3, true); + + std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1; + clientCompList1.push_back({}); + std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2; + clientCompList2.push_back({}); + std::vector<compositionengine::LayerFE::LayerSettings> clientCompList3; + clientCompList3.push_back({}); + + EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1)); + EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2)); + EXPECT_CALL(*layerFE3, prepareClientCompositionList(_)).WillOnce(Return(clientCompList3)); + + const auto drawLayers = [&](const renderengine::DisplaySettings&, + const std::vector<const renderengine::LayerSettings*>& layers, + const std::shared_ptr<renderengine::ExternalTexture>&, const bool, + base::unique_fd&&, base::unique_fd*) -> size_t { + // If the highlight layer is enabled, it will increase the size by 1. + // We're interested in the third layer either way. + EXPECT_GE(layers.size(), 3u); + const auto* holePunchSettings = layers[2]; + EXPECT_EQ(nullptr, holePunchSettings->source.buffer.buffer); + EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings->source.solidColor); + EXPECT_TRUE(holePunchSettings->disableBlending); + EXPECT_EQ(0.0f, holePunchSettings->alpha); + + return NO_ERROR; + }; + + EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers)); + cachedSet.render(mRenderEngine, mOutputState); +} + TEST_F(CachedSetTest, decompose_removesHolePunch) { mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5); CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get(); @@ -593,5 +652,78 @@ TEST_F(CachedSetTest, hasBlurBehind) { EXPECT_TRUE(cachedSet4.hasBlurBehind()); } +TEST_F(CachedSetTest, addBackgroundBlurLayer) { + CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get(); + CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get(); + CachedSet cachedSet(layer1); + + EXPECT_EQ(nullptr, cachedSet.getBlurLayer()); + + cachedSet.addBackgroundBlurLayer(layer2); + EXPECT_EQ(layer2.getState()->getOutputLayer(), cachedSet.getBlurLayer()); +} + +TEST_F(CachedSetTest, addBlur) { + mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5); + CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get(); + sp<mock::LayerFE> layerFE1 = mTestLayers[0]->layerFE; + + CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get(); + sp<mock::LayerFE> layerFE2 = mTestLayers[1]->layerFE; + + CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get(); + sp<mock::LayerFE> layerFE3 = mTestLayers[2]->layerFE; + + CachedSet cachedSet(layer1); + cachedSet.addLayer(layer2.getState(), kStartTime + 10ms); + + cachedSet.addBackgroundBlurLayer(layer3); + + std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1; + clientCompList1.push_back({}); + std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2; + clientCompList2.push_back({}); + std::vector<compositionengine::LayerFE::LayerSettings> clientCompList3; + clientCompList3.push_back({}); + + clientCompList3[0].source.buffer.buffer = std::make_shared< + renderengine::ExternalTexture>(sp<GraphicBuffer>::make(), mRenderEngine, + renderengine::ExternalTexture::READABLE); + + EXPECT_CALL(*layerFE1, + prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq( + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting:: + Enabled))) + .WillOnce(Return(clientCompList1)); + EXPECT_CALL(*layerFE2, + prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq( + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting:: + Enabled))) + .WillOnce(Return(clientCompList2)); + EXPECT_CALL(*layerFE3, + prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq( + compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting:: + BackgroundBlurOnly))) + .WillOnce(Return(clientCompList3)); + + const auto drawLayers = [&](const renderengine::DisplaySettings&, + const std::vector<const renderengine::LayerSettings*>& layers, + const std::shared_ptr<renderengine::ExternalTexture>&, const bool, + base::unique_fd&&, base::unique_fd*) -> int32_t { + // If the highlight layer is enabled, it will increase the size by 1. + // We're interested in the third layer either way. + EXPECT_GE(layers.size(), 3u); + const auto* blurSettings = layers[2]; + EXPECT_TRUE(blurSettings->skipContentDraw); + EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), blurSettings->source.solidColor); + EXPECT_EQ(0.0f, blurSettings->alpha); + + return NO_ERROR; + }; + + EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers)); + cachedSet.render(mRenderEngine, mOutputState); +} + } // namespace } // namespace android::compositionengine diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp index 7ec2c98bc1..8b03964ad2 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp @@ -27,6 +27,7 @@ namespace android::compositionengine { using namespace std::chrono_literals; +using impl::planner::CachedSet; using impl::planner::Flattener; using impl::planner::LayerState; using impl::planner::NonBufferHash; @@ -43,9 +44,15 @@ using testing::SetArgPointee; namespace { +class TestableFlattener : public Flattener { +public: + TestableFlattener(bool enableHolePunch) : Flattener(enableHolePunch) {} + const std::optional<CachedSet>& getNewCachedSetForTesting() const { return mNewCachedSet; } +}; + class FlattenerTest : public testing::Test { public: - FlattenerTest() : mFlattener(std::make_unique<Flattener>(true)) {} + FlattenerTest() : mFlattener(std::make_unique<TestableFlattener>(true)) {} void SetUp() override; protected: @@ -55,7 +62,7 @@ protected: // mRenderEngine may be held as a pointer to mFlattener, so mFlattener must be destroyed first. renderengine::mock::RenderEngine mRenderEngine; - std::unique_ptr<Flattener> mFlattener; + std::unique_ptr<TestableFlattener> mFlattener; const std::chrono::steady_clock::time_point kStartTime = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point mTime = kStartTime; @@ -786,6 +793,56 @@ TEST_F(FlattenerTest, flattenLayers_flattenSkipsLayerWithBlurBehind) { EXPECT_EQ(overrideBuffer3, overrideBuffer4); } +TEST_F(FlattenerTest, flattenLayers_whenBlurLayerIsChanging_appliesBlurToInactiveBehindLayers) { + auto& layerState1 = mTestLayers[0]->layerState; + auto& layerState2 = mTestLayers[1]->layerState; + + auto& layerStateWithBlurBehind = mTestLayers[2]->layerState; + mTestLayers[2]->layerFECompositionState.backgroundBlurRadius = 1; + layerStateWithBlurBehind->update(&mTestLayers[2]->outputLayer); + const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer; + const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer; + const auto& blurOverrideBuffer = + layerStateWithBlurBehind->getOutputLayer()->getState().overrideInfo.buffer; + + const std::vector<const LayerState*> layers = { + layerState1.get(), + layerState2.get(), + layerStateWithBlurBehind.get(), + }; + + initializeFlattener(layers); + + // Mark the first two layers inactive, but update the blur layer + mTime += 200ms; + layerStateWithBlurBehind->resetFramesSinceBufferUpdate(); + + // layers would be flattened but the buffer would not be overridden + EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR)); + + initializeOverrideBuffer(layers); + EXPECT_EQ(getNonBufferHash(layers), + mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime)); + mFlattener->renderCachedSets(mRenderEngine, mOutputState); + + const auto& cachedSet = mFlattener->getNewCachedSetForTesting(); + ASSERT_NE(std::nullopt, cachedSet); + EXPECT_EQ(&mTestLayers[2]->outputLayer, cachedSet->getBlurLayer()); + + for (const auto layer : layers) { + EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer); + } + + // the new flattened layer is replaced + initializeOverrideBuffer(layers); + EXPECT_NE(getNonBufferHash(layers), + mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime)); + mFlattener->renderCachedSets(mRenderEngine, mOutputState); + EXPECT_NE(nullptr, overrideBuffer1); + EXPECT_EQ(overrideBuffer2, overrideBuffer1); + EXPECT_EQ(nullptr, blurOverrideBuffer); +} + TEST_F(FlattenerTest, flattenLayers_renderCachedSets_doesNotRenderTwice) { auto& layerState1 = mTestLayers[0]->layerState; auto& layerState2 = mTestLayers[1]->layerState; diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 0f18235751..ca4b6abc03 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -70,13 +70,14 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) mIsPrimary(args.isPrimary) { mCompositionDisplay->editState().isSecure = args.isSecure; mCompositionDisplay->createRenderSurface( - compositionengine:: - RenderSurfaceCreationArgs{ANativeWindow_getWidth(args.nativeWindow.get()), - ANativeWindow_getHeight(args.nativeWindow.get()), - args.nativeWindow, args.displaySurface, - static_cast<size_t>( - SurfaceFlinger:: - maxFrameBufferAcquiredBuffers)}); + compositionengine::RenderSurfaceCreationArgsBuilder() + .setDisplayWidth(ANativeWindow_getWidth(args.nativeWindow.get())) + .setDisplayHeight(ANativeWindow_getHeight(args.nativeWindow.get())) + .setNativeWindow(std::move(args.nativeWindow)) + .setDisplaySurface(std::move(args.displaySurface)) + .setMaxTextureCacheSize( + static_cast<size_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers)) + .build()); if (!mFlinger->mDisableClientCompositionCache && SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) { diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index bf249cdb25..7e4d92308c 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -103,15 +103,21 @@ public: bool needsFiltering() const; ui::LayerStack getLayerStack() const; - // Returns the physical ID of this display. This function asserts the ID is physical and it - // shouldn't be called for other display types, e.g. virtual. + DisplayId getId() const; + + // Shorthand to upcast the ID of a display whose type is known as a precondition. PhysicalDisplayId getPhysicalId() const { - const auto displayIdOpt = PhysicalDisplayId::tryCast(getId()); - LOG_FATAL_IF(!displayIdOpt); - return *displayIdOpt; + const auto id = PhysicalDisplayId::tryCast(getId()); + LOG_FATAL_IF(!id); + return *id; + } + + VirtualDisplayId getVirtualId() const { + const auto id = VirtualDisplayId::tryCast(getId()); + LOG_FATAL_IF(!id); + return *id; } - DisplayId getId() const; const wp<IBinder>& getDisplayToken() const { return mDisplayToken; } int32_t getSequenceId() const { return mSequenceId; } @@ -285,4 +291,16 @@ struct DisplayDeviceCreationArgs { DisplayModes supportedModes; }; +// Predicates for display lookup. + +struct WithLayerStack { + explicit WithLayerStack(ui::LayerStack layerStack) : layerStack(layerStack) {} + + bool operator()(const DisplayDevice& display) const { + return display.getLayerStack() == layerStack; + } + + ui::LayerStack layerStack; +}; + } // namespace android diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index 1cbcf592db..caf0294a56 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -211,9 +211,8 @@ uint32_t Composer::getMaxVirtualDisplayCount() return unwrapRet(ret, 0); } -Error Composer::createVirtualDisplay(uint32_t width, uint32_t height, - PixelFormat* format, Display* outDisplay) -{ +Error Composer::createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format, + std::optional<Display>, Display* outDisplay) { const uint32_t bufferSlotCount = 1; Error error = kDefaultError; if (mClient_2_2) { diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 0619b8c444..b525e63c66 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -18,6 +18,7 @@ #define ANDROID_SF_COMPOSER_HAL_H #include <memory> +#include <optional> #include <string> #include <unordered_map> #include <utility> @@ -94,8 +95,8 @@ public: virtual Error executeCommands() = 0; virtual uint32_t getMaxVirtualDisplayCount() = 0; - virtual Error createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format, - Display* outDisplay) = 0; + virtual Error createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat*, + std::optional<Display> mirror, Display* outDisplay) = 0; virtual Error destroyVirtualDisplay(Display display) = 0; virtual Error acceptDisplayChanges(Display display) = 0; @@ -341,7 +342,7 @@ public: uint32_t getMaxVirtualDisplayCount() override; Error createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format, - Display* outDisplay) override; + std::optional<Display> mirror, Display* outDisplay) override; Error destroyVirtualDisplay(Display display) override; Error acceptDisplayChanges(Display display) override; diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index fae95e79c3..871465d717 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -56,20 +56,16 @@ namespace hal = android::hardware::graphics::composer::hal; // Implement this interface to receive hardware composer events. // // These callback functions will generally be called on a hwbinder thread, but -// when first registering the callback the onHotplugReceived() function will +// when first registering the callback the onComposerHalHotplug() function will // immediately be called on the thread calling registerCallback(). -// -// All calls receive a sequenceId, which will be the value that was supplied to -// HWC2::Device::registerCallback(). It's used to help differentiate callbacks -// from different hardware composer instances. struct ComposerCallback { - virtual void onHotplugReceived(int32_t sequenceId, hal::HWDisplayId, hal::Connection) = 0; - virtual void onRefreshReceived(int32_t sequenceId, hal::HWDisplayId) = 0; - virtual void onVsyncReceived(int32_t sequenceId, hal::HWDisplayId, int64_t timestamp, - std::optional<hal::VsyncPeriodNanos>) = 0; - virtual void onVsyncPeriodTimingChangedReceived(int32_t sequenceId, hal::HWDisplayId, - const hal::VsyncPeriodChangeTimeline&) = 0; - virtual void onSeamlessPossible(int32_t sequenceId, hal::HWDisplayId) = 0; + virtual void onComposerHalHotplug(hal::HWDisplayId, hal::Connection) = 0; + virtual void onComposerHalRefresh(hal::HWDisplayId) = 0; + virtual void onComposerHalVsync(hal::HWDisplayId, int64_t timestamp, + std::optional<hal::VsyncPeriodNanos>) = 0; + virtual void onComposerHalVsyncPeriodTimingChanged(hal::HWDisplayId, + const hal::VsyncPeriodChangeTimeline&) = 0; + virtual void onComposerHalSeamlessPossible(hal::HWDisplayId) = 0; protected: ~ComposerCallback() = default; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 36876dc7f1..32f04e56bc 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -38,7 +38,6 @@ #include <utils/Trace.h> #include "../Layer.h" // needed only for debugging -#include "../SurfaceFlinger.h" #include "../SurfaceFlingerProperties.h" #include "ComposerHal.h" #include "HWC2.h" @@ -83,25 +82,22 @@ using android::HWC2::ComposerCallback; class ComposerCallbackBridge : public hal::IComposerCallback { public: - ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId, - bool vsyncSwitchingSupported) - : mCallback(callback), - mSequenceId(sequenceId), - mVsyncSwitchingSupported(vsyncSwitchingSupported) {} - - Return<void> onHotplug(hal::HWDisplayId display, hal::Connection conn) override { - mCallback->onHotplugReceived(mSequenceId, display, conn); + ComposerCallbackBridge(ComposerCallback* callback, bool vsyncSwitchingSupported) + : mCallback(callback), mVsyncSwitchingSupported(vsyncSwitchingSupported) {} + + Return<void> onHotplug(hal::HWDisplayId display, hal::Connection connection) override { + mCallback->onComposerHalHotplug(display, connection); return Void(); } Return<void> onRefresh(hal::HWDisplayId display) override { - mCallback->onRefreshReceived(mSequenceId, display); + mCallback->onComposerHalRefresh(display); return Void(); } Return<void> onVsync(hal::HWDisplayId display, int64_t timestamp) override { if (!mVsyncSwitchingSupported) { - mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::nullopt); + mCallback->onComposerHalVsync(display, timestamp, std::nullopt); } else { ALOGW("Unexpected onVsync callback on composer >= 2.4, ignoring."); } @@ -111,8 +107,7 @@ public: Return<void> onVsync_2_4(hal::HWDisplayId display, int64_t timestamp, hal::VsyncPeriodNanos vsyncPeriodNanos) override { if (mVsyncSwitchingSupported) { - mCallback->onVsyncReceived(mSequenceId, display, timestamp, - std::make_optional(vsyncPeriodNanos)); + mCallback->onComposerHalVsync(display, timestamp, vsyncPeriodNanos); } else { ALOGW("Unexpected onVsync_2_4 callback on composer <= 2.3, ignoring."); } @@ -120,20 +115,18 @@ public: } Return<void> onVsyncPeriodTimingChanged( - hal::HWDisplayId display, - const hal::VsyncPeriodChangeTimeline& updatedTimeline) override { - mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, updatedTimeline); + hal::HWDisplayId display, const hal::VsyncPeriodChangeTimeline& timeline) override { + mCallback->onComposerHalVsyncPeriodTimingChanged(display, timeline); return Void(); } Return<void> onSeamlessPossible(hal::HWDisplayId display) override { - mCallback->onSeamlessPossible(mSequenceId, display); + mCallback->onComposerHalSeamlessPossible(display); return Void(); } private: - ComposerCallback* mCallback; - const int32_t mSequenceId; + ComposerCallback* const mCallback; const bool mVsyncSwitchingSupported; }; @@ -145,8 +138,9 @@ namespace impl { HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer) : mComposer(std::move(composer)), + mMaxVirtualDisplayDimension(static_cast<size_t>(sysprop::max_virtual_display_dimension(0))), mUpdateDeviceProductInfoOnHotplugReconnect( - android::sysprop::update_device_product_info_on_hotplug_reconnect(false)) {} + sysprop::update_device_product_info_on_hotplug_reconnect(false)) {} HWComposer::HWComposer(const std::string& composerServiceName) : HWComposer(std::make_unique<Hwc2::impl::Composer>(composerServiceName)) {} @@ -155,7 +149,7 @@ HWComposer::~HWComposer() { mDisplayData.clear(); } -void HWComposer::setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) { +void HWComposer::setCallback(HWC2::ComposerCallback* callback) { loadCapabilities(); loadLayerMetadataSupport(); @@ -164,10 +158,9 @@ void HWComposer::setConfiguration(HWC2::ComposerCallback* callback, int32_t sequ return; } mRegisteredCallback = true; - sp<ComposerCallbackBridge> callbackBridge( - new ComposerCallbackBridge(callback, sequenceId, - mComposer->isVsyncPeriodSwitchSupported())); - mComposer->registerCallback(callbackBridge); + + mComposer->registerCallback( + sp<ComposerCallbackBridge>::make(callback, mComposer->isVsyncPeriodSwitchSupported())); } bool HWComposer::getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId, uint8_t* outPort, @@ -243,38 +236,49 @@ bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp) { return true; } -std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height, - ui::PixelFormat* format) { - if (SurfaceFlinger::maxVirtualDisplaySize != 0 && - (width > SurfaceFlinger::maxVirtualDisplaySize || - height > SurfaceFlinger::maxVirtualDisplaySize)) { - ALOGE("%s: Display size %ux%u exceeds maximum dimension of %" PRIu64, __FUNCTION__, width, - height, SurfaceFlinger::maxVirtualDisplaySize); - return {}; +size_t HWComposer::getMaxVirtualDisplayCount() const { + return mComposer->getMaxVirtualDisplayCount(); +} + +size_t HWComposer::getMaxVirtualDisplayDimension() const { + return mMaxVirtualDisplayDimension; +} + +bool HWComposer::allocateVirtualDisplay(HalVirtualDisplayId displayId, ui::Size resolution, + ui::PixelFormat* format, + std::optional<PhysicalDisplayId> mirror) { + if (!resolution.isValid()) { + ALOGE("%s: Invalid resolution %dx%d", __func__, resolution.width, resolution.height); + return false; } - const auto displayId = mVirtualIdGenerator.nextId(); - if (!displayId) { - ALOGE("%s: No remaining virtual displays", __FUNCTION__); - return {}; + const uint32_t width = static_cast<uint32_t>(resolution.width); + const uint32_t height = static_cast<uint32_t>(resolution.height); + + if (mMaxVirtualDisplayDimension > 0 && + (width > mMaxVirtualDisplayDimension || height > mMaxVirtualDisplayDimension)) { + ALOGE("%s: Resolution %ux%u exceeds maximum dimension %zu", __func__, width, height, + mMaxVirtualDisplayDimension); + return false; } - hal::HWDisplayId hwcDisplayId = 0; - const auto error = static_cast<hal::Error>( - mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId)); - if (error != hal::Error::NONE) { - ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__); - mVirtualIdGenerator.markUnused(*displayId); - return {}; + std::optional<hal::HWDisplayId> hwcMirrorId; + if (mirror) { + hwcMirrorId = fromPhysicalDisplayId(*mirror); } + hal::HWDisplayId hwcDisplayId; + const auto error = static_cast<hal::Error>( + mComposer->createVirtualDisplay(width, height, format, hwcMirrorId, &hwcDisplayId)); + RETURN_IF_HWC_ERROR_FOR("createVirtualDisplay", error, displayId, false); + auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId, hal::DisplayType::VIRTUAL); display->setConnected(true); - auto& displayData = mDisplayData[*displayId]; + auto& displayData = mDisplayData[displayId]; displayData.hwcDisplay = std::move(display); displayData.isVirtual = true; - return displayId; + return true; } void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, @@ -670,13 +674,6 @@ status_t HWComposer::setColorTransform(HalDisplayId displayId, const mat4& trans void HWComposer::disconnectDisplay(HalDisplayId displayId) { RETURN_IF_INVALID_DISPLAY(displayId); auto& displayData = mDisplayData[displayId]; - - // If this was a virtual display, add its slot back for reuse by future - // virtual displays - if (displayData.isVirtual) { - mVirtualIdGenerator.markUnused(*HalVirtualDisplayId::tryCast(displayId)); - } - const auto hwcDisplayId = displayData.hwcDisplay->getId(); // TODO(b/74619554): Select internal/external display from remaining displays. @@ -983,10 +980,6 @@ void HWComposer::loadLayerMetadataSupport() { } } -uint32_t HWComposer::getMaxVirtualDisplayCount() const { - return mComposer->getMaxVirtualDisplayCount(); -} - } // namespace impl } // namespace android diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index d0c0c1105a..cd6f9f516f 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -39,7 +39,6 @@ #include <utils/StrongPointer.h> #include <utils/Timers.h> -#include "DisplayIdGenerator.h" #include "DisplayIdentification.h" #include "DisplayMode.h" #include "HWC2.h" @@ -101,7 +100,7 @@ public: virtual ~HWComposer(); - virtual void setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) = 0; + virtual void setCallback(HWC2::ComposerCallback*) = 0; virtual bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort, DisplayIdentificationData* outData) const = 0; @@ -109,9 +108,16 @@ public: virtual bool hasCapability(hal::Capability) const = 0; virtual bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const = 0; - // Attempts to allocate a virtual display and returns its ID if created on the HWC device. - virtual std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height, - ui::PixelFormat*) = 0; + virtual size_t getMaxVirtualDisplayCount() const = 0; + virtual size_t getMaxVirtualDisplayDimension() const = 0; + + // Attempts to allocate a virtual display on the HWC. The maximum number of virtual displays + // supported by the HWC can be queried in advance, but allocation may fail for other reasons. + // For virtualized compositors, the PhysicalDisplayId is a hint that this virtual display is + // a mirror of a physical display, and that the screen should be captured by the host rather + // than guest compositor. + virtual bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*, + std::optional<PhysicalDisplayId> mirror) = 0; virtual void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) = 0; @@ -246,7 +252,7 @@ public: ~HWComposer() override; - void setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) override; + void setCallback(HWC2::ComposerCallback*) override; bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort, DisplayIdentificationData* outData) const override; @@ -254,9 +260,11 @@ public: bool hasCapability(hal::Capability) const override; bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const override; - // Attempts to allocate a virtual display and returns its ID if created on the HWC device. - std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height, - ui::PixelFormat*) override; + size_t getMaxVirtualDisplayCount() const override; + size_t getMaxVirtualDisplayDimension() const override; + + bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*, + std::optional<PhysicalDisplayId>) override; // Called from SurfaceFlinger, when the state for a new physical display needs to be recreated. void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) override; @@ -402,7 +410,6 @@ private: void loadCapabilities(); void loadLayerMetadataSupport(); - uint32_t getMaxVirtualDisplayCount() const; std::unordered_map<HalDisplayId, DisplayData> mDisplayData; @@ -416,8 +423,7 @@ private: std::optional<hal::HWDisplayId> mExternalHwcDisplayId; bool mHasMultiDisplaySupport = false; - RandomDisplayIdGenerator<HalVirtualDisplayId> mVirtualIdGenerator{getMaxVirtualDisplayCount()}; - + const size_t mMaxVirtualDisplayDimension; const bool mUpdateDeviceProductInfoOnHotplugReconnect; }; diff --git a/services/surfaceflinger/DisplayIdGenerator.h b/services/surfaceflinger/DisplayIdGenerator.h index e7c69a8094..9791a2504a 100644 --- a/services/surfaceflinger/DisplayIdGenerator.h +++ b/services/surfaceflinger/DisplayIdGenerator.h @@ -27,23 +27,16 @@ namespace android { -template <typename T> +// Generates pseudo-random IDs of type GpuVirtualDisplayId or HalVirtualDisplayId. +template <typename Id> class DisplayIdGenerator { public: - virtual std::optional<T> nextId() = 0; - virtual void markUnused(T id) = 0; - -protected: - ~DisplayIdGenerator() {} -}; - -template <typename T> -class RandomDisplayIdGenerator final : public DisplayIdGenerator<T> { -public: - explicit RandomDisplayIdGenerator(size_t maxIdsCount = std::numeric_limits<size_t>::max()) + explicit DisplayIdGenerator(size_t maxIdsCount = std::numeric_limits<size_t>::max()) : mMaxIdsCount(maxIdsCount) {} - std::optional<T> nextId() override { + bool inUse() const { return !mUsedIds.empty(); } + + std::optional<Id> generateId() { if (mUsedIds.size() >= mMaxIdsCount) { return std::nullopt; } @@ -51,8 +44,7 @@ public: constexpr int kMaxAttempts = 1000; for (int attempts = 0; attempts < kMaxAttempts; attempts++) { - const auto baseId = mDistribution(mGenerator); - const T id(baseId); + const Id id{mDistribution(mGenerator)}; if (mUsedIds.count(id) == 0) { mUsedIds.insert(id); return id; @@ -62,14 +54,18 @@ public: LOG_ALWAYS_FATAL("Couldn't generate ID after %d attempts", kMaxAttempts); } - void markUnused(T id) override { mUsedIds.erase(id); } + void releaseId(Id id) { mUsedIds.erase(id); } private: const size_t mMaxIdsCount; - std::unordered_set<T> mUsedIds; + std::unordered_set<Id> mUsedIds; + + // Pseudo-random with random seed, in contrast to physical display IDs, which are stable + // across reboots. The only ISurfaceComposer exposure for these IDs is a restricted API + // for screencap, so there is little benefit in making them unpredictable. std::default_random_engine mGenerator{std::random_device()()}; - std::uniform_int_distribution<typename T::BaseId> mDistribution; + std::uniform_int_distribution<typename Id::BaseId> mDistribution; }; -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index d720bcb20f..9fcc17c4b4 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -587,11 +587,24 @@ std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCom layerSettings.alpha = alpha; layerSettings.sourceDataspace = getDataSpace(); - if (!targetSettings.disableBlurs) { - layerSettings.backgroundBlurRadius = getBackgroundBlurRadius(); - layerSettings.blurRegions = getBlurRegions(); - layerSettings.blurRegionTransform = - getActiveTransform(getDrawingState()).inverse().asMatrix4(); + switch (targetSettings.blurSetting) { + case LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled: + layerSettings.backgroundBlurRadius = getBackgroundBlurRadius(); + layerSettings.blurRegions = getBlurRegions(); + layerSettings.blurRegionTransform = + getActiveTransform(getDrawingState()).inverse().asMatrix4(); + break; + case LayerFE::ClientCompositionTargetSettings::BlurSetting::BackgroundBlurOnly: + layerSettings.backgroundBlurRadius = getBackgroundBlurRadius(); + break; + case LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly: + layerSettings.blurRegions = getBlurRegions(); + layerSettings.blurRegionTransform = + getActiveTransform(getDrawingState()).inverse().asMatrix4(); + break; + case LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled: + default: + break; } layerSettings.stretchEffect = getStretchEffect(); // Record the name of the layer for debugging further down the stack. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a86e0610fb..2b4f9ef638 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -295,7 +295,6 @@ const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled // --------------------------------------------------------------------------- int64_t SurfaceFlinger::dispSyncPresentTimeOffset; bool SurfaceFlinger::useHwcForRgbToYuv; -uint64_t SurfaceFlinger::maxVirtualDisplaySize; bool SurfaceFlinger::hasSyncFramework; int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers; uint32_t SurfaceFlinger::maxGraphicsWidth; @@ -358,8 +357,6 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI useHwcForRgbToYuv = force_hwc_copy_for_virtual_displays(false); - maxVirtualDisplaySize = max_virtual_display_dimension(0); - maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2); maxGraphicsWidth = std::max(max_graphics_width(0), 0); @@ -435,10 +432,6 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI ALOGI_IF(mPropagateBackpressureClientComposition, "Enabling backpressure propagation for Client Composition"); - property_get("debug.sf.enable_hwc_vds", value, "0"); - mUseHwcVirtualDisplays = atoi(value); - ALOGI_IF(mUseHwcVirtualDisplays, "Enabling HWC virtual displays"); - property_get("ro.surface_flinger.supports_background_blur", value, "0"); bool supportsBlurs = atoi(value); mSupportsBlur = supportsBlurs; @@ -579,6 +572,59 @@ void SurfaceFlinger::destroyDisplay(const sp<IBinder>& displayToken) { setTransactionFlags(eDisplayTransactionNeeded); } +void SurfaceFlinger::enableHalVirtualDisplays(bool enable) { + auto& generator = mVirtualDisplayIdGenerators.hal; + if (!generator && enable) { + ALOGI("Enabling HAL virtual displays"); + generator.emplace(getHwComposer().getMaxVirtualDisplayCount()); + } else if (generator && !enable) { + ALOGW_IF(generator->inUse(), "Disabling HAL virtual displays while in use"); + generator.reset(); + } +} + +VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution, ui::PixelFormat format, + ui::LayerStack layerStack) { + if (auto& generator = mVirtualDisplayIdGenerators.hal) { + if (const auto id = generator->generateId()) { + std::optional<PhysicalDisplayId> mirror; + + if (const auto display = findDisplay([layerStack](const auto& display) { + return !display.isVirtual() && display.getLayerStack() == layerStack; + })) { + mirror = display->getPhysicalId(); + } + + if (getHwComposer().allocateVirtualDisplay(*id, resolution, &format, mirror)) { + return *id; + } + + generator->releaseId(*id); + } else { + ALOGW("%s: Exhausted HAL virtual displays", __func__); + } + + ALOGW("%s: Falling back to GPU virtual display", __func__); + } + + const auto id = mVirtualDisplayIdGenerators.gpu.generateId(); + LOG_ALWAYS_FATAL_IF(!id, "Failed to generate ID for GPU virtual display"); + return *id; +} + +void SurfaceFlinger::releaseVirtualDisplay(VirtualDisplayId displayId) { + if (const auto id = HalVirtualDisplayId::tryCast(displayId)) { + if (auto& generator = mVirtualDisplayIdGenerators.hal) { + generator->releaseId(*id); + } + return; + } + + const auto id = GpuVirtualDisplayId::tryCast(displayId); + LOG_ALWAYS_FATAL_IF(!id); + mVirtualDisplayIdGenerators.gpu.releaseId(*id); +} + std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIds() const { Mutex::Autolock lock(mStateLock); @@ -737,8 +783,13 @@ void SurfaceFlinger::init() { .build())); mCompositionEngine->setTimeStats(mTimeStats); mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName)); - mCompositionEngine->getHwComposer().setConfiguration(this, getBE().mComposerSequenceId); + mCompositionEngine->getHwComposer().setCallback(this); ClientCache::getInstance().setRenderEngine(&getRenderEngine()); + + if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) { + enableHalVirtualDisplays(true); + } + // Process any initial hotplug and resulting display changes. processDisplayHotplugEventsLocked(); const auto display = getDefaultDisplayDeviceLocked(); @@ -1029,10 +1080,6 @@ void SurfaceFlinger::setDesiredActiveMode(const ActiveModeInfo& info) { updatePhaseConfiguration(refreshRate.getFps()); mScheduler->setModeChangePending(true); } - - if (mRefreshRateOverlay) { - mRefreshRateOverlay->changeRefreshRate(refreshRate.getFps()); - } } status_t SurfaceFlinger::setActiveMode(const sp<IBinder>& displayToken, int modeId) { @@ -1190,6 +1237,10 @@ void SurfaceFlinger::performSetActiveMode() { } mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline); + if (mRefreshRateOverlay) { + mRefreshRateOverlay->changeRefreshRate(desiredMode->getFps()); + } + // Scheduler will submit an empty frame to HWC if needed. mSetActiveModePending = true; } @@ -1612,16 +1663,11 @@ nsecs_t SurfaceFlinger::getVsyncPeriodFromHWC() const { return 0; } -void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, - int64_t timestamp, - std::optional<hal::VsyncPeriodNanos> vsyncPeriod) { - ATRACE_NAME("SF onVsync"); +void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp, + std::optional<hal::VsyncPeriodNanos> vsyncPeriod) { + ATRACE_CALL(); Mutex::Autolock lock(mStateLock); - // Ignore any vsyncs from a previous hardware composer. - if (sequenceId != getBE().mComposerSequenceId) { - return; - } if (const auto displayId = getHwComposer().toPhysicalDisplayId(hwcDisplayId)) { auto token = getPhysicalDisplayTokenLocked(*displayId); @@ -1672,16 +1718,11 @@ void SurfaceFlinger::changeRefreshRateLocked(const RefreshRate& refreshRate, setDesiredActiveMode({refreshRate.getModeId(), event}); } -void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, - hal::Connection connection) { - ALOGI("%s(%d, %" PRIu64 ", %s)", __FUNCTION__, sequenceId, hwcDisplayId, +void SurfaceFlinger::onComposerHalHotplug(hal::HWDisplayId hwcDisplayId, + hal::Connection connection) { + ALOGI("%s(%" PRIu64 ", %s)", __func__, hwcDisplayId, connection == hal::Connection::CONNECTED ? "connected" : "disconnected"); - // Ignore events that do not have the right sequenceId. - if (sequenceId != getBE().mComposerSequenceId) { - return; - } - // Only lock if we're not on the main thread. This function is normally // called on a hwbinder thread, but for the primary display it's called on // the main thread with the state lock already held, so don't attempt to @@ -1698,26 +1739,19 @@ void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcD setTransactionFlags(eDisplayTransactionNeeded); } -void SurfaceFlinger::onVsyncPeriodTimingChangedReceived( - int32_t sequenceId, hal::HWDisplayId /*display*/, - const hal::VsyncPeriodChangeTimeline& updatedTimeline) { +void SurfaceFlinger::onComposerHalVsyncPeriodTimingChanged( + hal::HWDisplayId, const hal::VsyncPeriodChangeTimeline& timeline) { Mutex::Autolock lock(mStateLock); - if (sequenceId != getBE().mComposerSequenceId) { - return; - } - mScheduler->onNewVsyncPeriodChangeTimeline(updatedTimeline); + mScheduler->onNewVsyncPeriodChangeTimeline(timeline); } -void SurfaceFlinger::onSeamlessPossible(int32_t /*sequenceId*/, hal::HWDisplayId /*display*/) { +void SurfaceFlinger::onComposerHalSeamlessPossible(hal::HWDisplayId) { // TODO(b/142753666): use constraints when calling to setActiveModeWithConstraints and // use this callback to know when to retry in case of SEAMLESS_NOT_POSSIBLE. } -void SurfaceFlinger::onRefreshReceived(int sequenceId, hal::HWDisplayId /*hwcDisplayId*/) { +void SurfaceFlinger::onComposerHalRefresh(hal::HWDisplayId) { Mutex::Autolock lock(mStateLock); - if (sequenceId != getBE().mComposerSequenceId) { - return; - } repaintEverythingForHWC(); } @@ -2212,11 +2246,10 @@ void SurfaceFlinger::postComposition() { mTunnelModeEnabledReporter->updateTunnelModeStatus(); } hdrInfoListeners.reserve(mHdrLayerInfoListeners.size()); - for (auto& [key, value] : mHdrLayerInfoListeners) { - if (value && value->hasListeners()) { - auto listenersDisplay = getDisplayById(key); - if (listenersDisplay) { - hdrInfoListeners.emplace_back(listenersDisplay->getCompositionDisplay(), value); + for (const auto& [displayId, reporter] : mHdrLayerInfoListeners) { + if (reporter && reporter->hasListeners()) { + if (const auto display = getDisplayDeviceLocked(displayId)) { + hdrInfoListeners.emplace_back(display->getCompositionDisplay(), reporter); } } } @@ -2642,10 +2675,10 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, ALOGE_IF(status != NO_ERROR, "Unable to query width (%d)", status); status = state.surface->query(NATIVE_WINDOW_HEIGHT, &resolution.height); ALOGE_IF(status != NO_ERROR, "Unable to query height (%d)", status); - int intPixelFormat; - status = state.surface->query(NATIVE_WINDOW_FORMAT, &intPixelFormat); + int format; + status = state.surface->query(NATIVE_WINDOW_FORMAT, &format); ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status); - pixelFormat = static_cast<ui::PixelFormat>(intPixelFormat); + pixelFormat = static_cast<ui::PixelFormat>(format); } else { // Virtual displays without a surface are dormant: // they have external state (layer stack, projection, @@ -2655,17 +2688,18 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, compositionengine::DisplayCreationArgsBuilder builder; if (const auto& physical = state.physical) { - builder.setPhysical({physical->id, physical->type}); + builder.setId(physical->id); + builder.setConnectionType(physical->type); + } else { + builder.setId(acquireVirtualDisplay(resolution, pixelFormat, state.layerStack)); } + builder.setPixels(resolution); - builder.setPixelFormat(pixelFormat); builder.setIsSecure(state.isSecure); builder.setLayerStackId(state.layerStack); builder.setPowerAdvisor(&mPowerAdvisor); - builder.setUseHwcVirtualDisplays(mUseHwcVirtualDisplays); - builder.setGpuVirtualDisplayIdGenerator(mGpuVirtualDisplayIdGenerator); builder.setName(state.displayName); - const auto compositionDisplay = getCompositionEngine().createDisplay(builder.build()); + auto compositionDisplay = getCompositionEngine().createDisplay(builder.build()); compositionDisplay->setLayerCachingEnabled(mLayerCachingEnabled); sp<compositionengine::DisplaySurface> displaySurface; @@ -2674,33 +2708,30 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, sp<IGraphicBufferConsumer> bqConsumer; getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false); - DisplayId displayId = compositionDisplay->getId(); - if (state.isVirtual()) { - const auto virtualId = VirtualDisplayId::tryCast(displayId); - LOG_FATAL_IF(!virtualId); - sp<VirtualDisplaySurface> vds = - new VirtualDisplaySurface(getHwComposer(), *virtualId, state.surface, bqProducer, - bqConsumer, state.displayName); - - displaySurface = vds; - producer = vds; + const auto displayId = VirtualDisplayId::tryCast(compositionDisplay->getId()); + LOG_FATAL_IF(!displayId); + auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *displayId, state.surface, + bqProducer, bqConsumer, state.displayName); + displaySurface = surface; + producer = std::move(surface); } else { ALOGE_IF(state.surface != nullptr, "adding a supported display, but rendering " "surface is provided (%p), ignoring it", state.surface.get()); - const auto physicalId = PhysicalDisplayId::tryCast(displayId); - LOG_FATAL_IF(!physicalId); - displaySurface = new FramebufferSurface(getHwComposer(), *physicalId, bqConsumer, - state.physical->activeMode->getSize(), - ui::Size(maxGraphicsWidth, maxGraphicsHeight)); + const auto displayId = PhysicalDisplayId::tryCast(compositionDisplay->getId()); + LOG_FATAL_IF(!displayId); + displaySurface = + sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqConsumer, + state.physical->activeMode->getSize(), + ui::Size(maxGraphicsWidth, maxGraphicsHeight)); producer = bqProducer; } LOG_FATAL_IF(!displaySurface); - const auto display = setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, - displaySurface, producer); + const auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), + state, displaySurface, producer); mDisplays.emplace(displayToken, display); if (!state.isVirtual()) { dispatchDisplayHotplugEvent(display->getPhysicalId(), true); @@ -2716,7 +2747,10 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) { auto display = getDisplayDeviceLocked(displayToken); if (display) { display->disconnect(); - if (!display->isVirtual()) { + + if (display->isVirtual()) { + releaseVirtualDisplay(display->getVirtualId()); + } else { dispatchDisplayHotplugEvent(display->getPhysicalId(), false); } } @@ -2745,17 +2779,26 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, const DisplayDeviceState& drawingState) { const sp<IBinder> currentBinder = IInterface::asBinder(currentState.surface); const sp<IBinder> drawingBinder = IInterface::asBinder(drawingState.surface); + + // Recreate the DisplayDevice if the surface or sequence ID changed. if (currentBinder != drawingBinder || currentState.sequenceId != drawingState.sequenceId) { - // changing the surface is like destroying and recreating the DisplayDevice getRenderEngine().cleanFramebufferCache(); + if (const auto display = getDisplayDeviceLocked(displayToken)) { display->disconnect(); + if (display->isVirtual()) { + releaseVirtualDisplay(display->getVirtualId()); + } } + mDisplays.erase(displayToken); + if (const auto& physical = currentState.physical) { getHwComposer().allocatePhysicalDisplay(physical->hwcDisplayId, physical->id); } + processDisplayAdded(displayToken, currentState); + if (currentState.physical) { const auto display = getDisplayDeviceLocked(displayToken); setPowerModeInternal(display, hal::PowerMode::ON); @@ -4629,7 +4672,8 @@ void SurfaceFlinger::appendSfConfigString(std::string& result) const { StringAppendF(&result, " PRESENT_TIME_OFFSET=%" PRId64, dispSyncPresentTimeOffset); StringAppendF(&result, " FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv); - StringAppendF(&result, " MAX_VIRT_DISPLAY_DIM=%" PRIu64, maxVirtualDisplaySize); + StringAppendF(&result, " MAX_VIRT_DISPLAY_DIM=%zu", + getHwComposer().getMaxVirtualDisplayDimension()); StringAppendF(&result, " RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework); StringAppendF(&result, " NUM_FRAMEBUFFER_SURFACE_BUFFERS=%" PRId64, maxFrameBufferAcquiredBuffers); @@ -5389,8 +5433,8 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r return NO_ERROR; } case 1021: { // Disable HWC virtual displays - n = data.readInt32(); - mUseHwcVirtualDisplays = !n; + const bool enable = data.readInt32() != 0; + static_cast<void>(schedule([this, enable] { enableHalVirtualDisplays(enable); })); return NO_ERROR; } case 1022: { // Set saturation boost @@ -5590,7 +5634,7 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r Mutex::Autolock lock(mStateLock); hwcId = getHwComposer().getInternalHwcDisplayId(); } - onHotplugReceived(getBE().mComposerSequenceId, *hwcId, hal::Connection::CONNECTED); + onComposerHalHotplug(*hwcId, hal::Connection::CONNECTED); return NO_ERROR; } // Modify the max number of display frames stored within FrameTimeline @@ -5800,34 +5844,6 @@ status_t SurfaceFlinger::setSchedFifo(bool enabled) { return NO_ERROR; } -sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) { - if (const sp<IBinder> displayToken = - getPhysicalDisplayTokenLocked(PhysicalDisplayId{displayOrLayerStack})) { - return getDisplayDeviceLocked(displayToken); - } - // Couldn't find display by displayId. Try to get display by layerStack since virtual displays - // may not have a displayId. - return getDisplayByLayerStack(displayOrLayerStack); -} - -sp<DisplayDevice> SurfaceFlinger::getDisplayById(DisplayId displayId) const { - for (const auto& [token, display] : mDisplays) { - if (display->getId() == displayId) { - return display; - } - } - return nullptr; -} - -sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) { - for (const auto& [token, display] : mDisplays) { - if (display->getLayerStack() == layerStack) { - return display; - } - } - return nullptr; -} - status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); @@ -5839,7 +5855,7 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, if (!args.displayToken) return BAD_VALUE; - wp<DisplayDevice> displayWeak; + wp<const DisplayDevice> displayWeak; ui::LayerStack layerStack; ui::Size reqSize(args.width, args.height); ui::Dataspace dataspace; @@ -5880,18 +5896,26 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, captureListener); } -status_t SurfaceFlinger::captureDisplay(uint64_t displayOrLayerStack, +status_t SurfaceFlinger::captureDisplay(uint64_t displayIdOrLayerStack, const sp<IScreenCaptureListener>& captureListener) { ui::LayerStack layerStack; - wp<DisplayDevice> displayWeak; + wp<const DisplayDevice> displayWeak; ui::Size size; ui::Dataspace dataspace; { Mutex::Autolock lock(mStateLock); - sp<DisplayDevice> display = getDisplayByIdOrLayerStack(displayOrLayerStack); + auto display = getDisplayDeviceLocked(PhysicalDisplayId{displayIdOrLayerStack}); + + // Fall back to first display whose layer stack matches. + if (!display) { + const auto layerStack = static_cast<ui::LayerStack>(displayIdOrLayerStack); + display = findDisplay(WithLayerStack(layerStack)); + } + if (!display) { return NAME_NOT_FOUND; } + layerStack = display->getLayerStack(); displayWeak = display; @@ -5979,7 +6003,7 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, } } - const auto display = getDisplayByLayerStack(parent->getLayerStack()); + const auto display = findDisplay(WithLayerStack(parent->getLayerStack())); if (!display) { return NAME_NOT_FOUND; } @@ -6202,9 +6226,12 @@ status_t SurfaceFlinger::renderScreenImplLocked( clearRegion, layerStackSpaceRect, clientCompositionDisplay.outputDataspace, - true, /* realContentIsVisible */ + true, /* realContentIsVisible */ false, /* clearContent */ - disableBlurs, + disableBlurs ? compositionengine::LayerFE::ClientCompositionTargetSettings:: + BlurSetting::Disabled + : compositionengine::LayerFE::ClientCompositionTargetSettings:: + BlurSetting::Enabled, }; std::vector<compositionengine::LayerFE::LayerSettings> results = layer->prepareClientCompositionList(targetSettings); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 30d76af61f..be3417b762 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -170,11 +170,6 @@ struct SurfaceFlingerBE { }; mutable Mutex mBufferingStatsMutex; std::unordered_map<std::string, BufferingStats> mBufferingStats; - - // The composer sequence id is a monotonically increasing integer that we - // use to differentiate callbacks from different hardware composer - // instances. Each hardware composer instance gets a different sequence id. - int32_t mComposerSequenceId = 0; }; class SurfaceFlinger : public BnSurfaceComposer, @@ -229,10 +224,6 @@ public: // GL composition. static bool useHwcForRgbToYuv; - // Maximum dimension supported by HWC for virtual display. - // Equal to min(max_height, max_width). - static uint64_t maxVirtualDisplaySize; - // Controls the number of buffers SurfaceFlinger will allocate for use in // FramebufferSurface static int64_t maxFrameBufferAcquiredBuffers; @@ -722,18 +713,14 @@ private: // Implements RefBase. void onFirstRef() override; - /* - * HWC2::ComposerCallback / HWComposer::EventHandler interface - */ - void onVsyncReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, int64_t timestamp, - std::optional<hal::VsyncPeriodNanos> vsyncPeriod) override; - void onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, - hal::Connection connection) override; - void onRefreshReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId) override; - void onVsyncPeriodTimingChangedReceived( - int32_t sequenceId, hal::HWDisplayId display, - const hal::VsyncPeriodChangeTimeline& updatedTimeline) override; - void onSeamlessPossible(int32_t sequenceId, hal::HWDisplayId display) override; + // HWC2::ComposerCallback overrides: + void onComposerHalVsync(hal::HWDisplayId, int64_t timestamp, + std::optional<hal::VsyncPeriodNanos>) override; + void onComposerHalHotplug(hal::HWDisplayId, hal::Connection) override; + void onComposerHalRefresh(hal::HWDisplayId) override; + void onComposerHalVsyncPeriodTimingChanged(hal::HWDisplayId, + const hal::VsyncPeriodChangeTimeline&) override; + void onComposerHalSeamlessPossible(hal::HWDisplayId) override; /* * ISchedulerCallback @@ -924,10 +911,6 @@ private: bool canCaptureBlackoutContent, bool regionSampling, bool grayscale, ScreenCaptureResults&); - sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock); - sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock); - sp<DisplayDevice> getDisplayByLayerStack(uint64_t layerStack) REQUIRES(mStateLock); - // If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a // matching ownerUid void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid, const LayerVector::Visitor&); @@ -953,6 +936,14 @@ private: return it == mDisplays.end() ? nullptr : it->second; } + sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const + REQUIRES(mStateLock) { + if (const auto token = getPhysicalDisplayTokenLocked(id)) { + return getDisplayDeviceLocked(token); + } + return nullptr; + } + sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const REQUIRES(mStateLock) { return const_cast<SurfaceFlinger*>(this)->getDefaultDisplayDeviceLocked(); } @@ -969,6 +960,20 @@ private: return getDefaultDisplayDeviceLocked(); } + // Returns the first display that matches a `bool(const DisplayDevice&)` predicate. + template <typename Predicate> + sp<DisplayDevice> findDisplay(Predicate p) const REQUIRES(mStateLock) { + const auto it = std::find_if(mDisplays.begin(), mDisplays.end(), + [&](const auto& pair) { return p(*pair.second); }); + + return it == mDisplays.end() ? nullptr : it->second; + } + + sp<const DisplayDevice> getDisplayDeviceLocked(DisplayId id) const REQUIRES(mStateLock) { + // TODO(b/182939859): Replace tokens with IDs for display lookup. + return findDisplay([id](const auto& display) { return display.getId() == id; }); + } + // mark a region of a layer stack dirty. this updates the dirty // region of all screens presenting this layer stack. void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty); @@ -1086,6 +1091,14 @@ private: return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt; } + // Toggles use of HAL/GPU virtual displays. + void enableHalVirtualDisplays(bool); + + // Virtual display lifecycle for ID generation and HAL allocation. + VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat, ui::LayerStack) + REQUIRES(mStateLock); + void releaseVirtualDisplay(VirtualDisplayId); + /* * Debugging & dumpsys */ @@ -1238,7 +1251,10 @@ private: std::unordered_map<PhysicalDisplayId, sp<IBinder>> mPhysicalDisplayTokens GUARDED_BY(mStateLock); - RandomDisplayIdGenerator<GpuVirtualDisplayId> mGpuVirtualDisplayIdGenerator; + struct { + DisplayIdGenerator<GpuVirtualDisplayId> gpu; + std::optional<DisplayIdGenerator<HalVirtualDisplayId>> hal; + } mVirtualDisplayIdGenerators; std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock); @@ -1261,7 +1277,7 @@ private: const std::shared_ptr<TimeStats> mTimeStats; const std::unique_ptr<FrameTracer> mFrameTracer; const std::unique_ptr<frametimeline::FrameTimeline> mFrameTimeline; - bool mUseHwcVirtualDisplays = false; + // If blurs should be enabled on this device. bool mSupportsBlur = false; // If blurs are considered expensive and should require high GPU frequency. diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index 736ef30d7c..b5086fafb7 100644 --- a/services/surfaceflinger/tests/unittests/Android.bp +++ b/services/surfaceflinger/tests/unittests/Android.bp @@ -69,7 +69,7 @@ cc_test { "SurfaceFlinger_GetDisplayNativePrimariesTest.cpp", "SurfaceFlinger_HandleTransactionLockedTest.cpp", "SurfaceFlinger_NotifyPowerBoostTest.cpp", - "SurfaceFlinger_OnHotplugReceivedTest.cpp", + "SurfaceFlinger_HotplugTest.cpp", "SurfaceFlinger_OnInitializeDisplaysTest.cpp", "SurfaceFlinger_SetDisplayStateTest.cpp", "SurfaceFlinger_SetPowerModeInternalTest.cpp", diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 3042450f29..560f139719 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -105,7 +105,9 @@ public: mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine)); mFlinger.setupTimeStats(std::shared_ptr<TimeStats>(mTimeStats)); - setupComposer(0); + + mComposer = new Hwc2::mock::Composer(); + mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); } ~CompositionTest() { @@ -114,14 +116,6 @@ public: ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); } - void setupComposer(int virtualDisplayCount) { - mComposer = new Hwc2::mock::Composer(); - EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount)); - mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); - - Mock::VerifyAndClear(mComposer); - } - void setupScheduler() { auto eventThread = std::make_unique<mock::EventThread>(); auto sfEventThread = std::make_unique<mock::EventThread>(); @@ -289,16 +283,16 @@ struct BaseDisplayVariant { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - auto ceDisplayArgs = - compositionengine::DisplayCreationArgsBuilder() - .setPhysical({DEFAULT_DISPLAY_ID, ui::DisplayConnectionType::Internal}) - .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) - .setIsSecure(Derived::IS_SECURE) - .setLayerStackId(DEFAULT_LAYER_STACK) - .setPowerAdvisor(&test->mPowerAdvisor) - .setName(std::string("Injected display for ") + - test_info->test_case_name() + "." + test_info->name()) - .build(); + auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() + .setId(DEFAULT_DISPLAY_ID) + .setConnectionType(ui::DisplayConnectionType::Internal) + .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) + .setIsSecure(Derived::IS_SECURE) + .setLayerStackId(DEFAULT_LAYER_STACK) + .setPowerAdvisor(&test->mPowerAdvisor) + .setName(std::string("Injected display for ") + + test_info->test_case_name() + "." + test_info->name()) + .build(); auto compositionDisplay = compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), diff --git a/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp b/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp index 77a3e1449f..8d4a023615 100644 --- a/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp @@ -14,76 +14,68 @@ * limitations under the License. */ -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wextra" - #include <gtest/gtest.h> +#include <ui/DisplayId.h> +#include <algorithm> +#include <iterator> #include <vector> -#include <ui/DisplayId.h> #include "DisplayIdGenerator.h" namespace android { -template <typename T> -void testNextId(DisplayIdGenerator<T>& generator) { - constexpr int kNumIds = 5; - std::vector<T> ids; - for (int i = 0; i < kNumIds; i++) { - const auto id = generator.nextId(); - ASSERT_TRUE(id); - ids.push_back(*id); - } +template <typename Id> +void testGenerateId() { + DisplayIdGenerator<Id> generator; + + std::vector<std::optional<Id>> ids; + std::generate_n(std::back_inserter(ids), 10, [&] { return generator.generateId(); }); // All IDs should be different. - for (size_t i = 0; i < kNumIds; i++) { - for (size_t j = i + 1; j < kNumIds; j++) { - EXPECT_NE(ids[i], ids[j]); + for (auto it = ids.begin(); it != ids.end(); ++it) { + EXPECT_TRUE(*it); + + for (auto dup = it + 1; dup != ids.end(); ++dup) { + EXPECT_NE(*it, *dup); } } } -TEST(DisplayIdGeneratorTest, nextIdGpuVirtual) { - RandomDisplayIdGenerator<GpuVirtualDisplayId> generator; - testNextId(generator); +TEST(DisplayIdGeneratorTest, generateGpuVirtualDisplayId) { + testGenerateId<GpuVirtualDisplayId>(); } -TEST(DisplayIdGeneratorTest, nextIdHalVirtual) { - RandomDisplayIdGenerator<HalVirtualDisplayId> generator; - testNextId(generator); +TEST(DisplayIdGeneratorTest, generateHalVirtualDisplayId) { + testGenerateId<HalVirtualDisplayId>(); } -TEST(DisplayIdGeneratorTest, markUnused) { +TEST(DisplayIdGeneratorTest, releaseId) { constexpr size_t kMaxIdsCount = 5; - RandomDisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount); + DisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount); - const auto id = generator.nextId(); + const auto id = generator.generateId(); EXPECT_TRUE(id); - for (int i = 1; i < kMaxIdsCount; i++) { - EXPECT_TRUE(generator.nextId()); + for (size_t i = 1; i < kMaxIdsCount; i++) { + EXPECT_TRUE(generator.generateId()); } - EXPECT_FALSE(generator.nextId()); + EXPECT_FALSE(generator.generateId()); - generator.markUnused(*id); - EXPECT_TRUE(generator.nextId()); + generator.releaseId(*id); + EXPECT_TRUE(generator.generateId()); } TEST(DisplayIdGeneratorTest, maxIdsCount) { constexpr size_t kMaxIdsCount = 5; - RandomDisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount); + DisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount); - for (int i = 0; i < kMaxIdsCount; i++) { - EXPECT_TRUE(generator.nextId()); + for (size_t i = 0; i < kMaxIdsCount; i++) { + EXPECT_TRUE(generator.generateId()); } - EXPECT_FALSE(generator.nextId()); + EXPECT_FALSE(generator.generateId()); } } // namespace android - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wextra"
\ No newline at end of file diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp index a3e810871c..cc24323c98 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp @@ -41,9 +41,6 @@ DisplayTransactionTest::DisplayTransactionTest() { mFlinger.mutableUseColorManagement() = false; mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged; - // Default to using HWC virtual displays - mFlinger.mutableUseHwcVirtualDisplays() = true; - mFlinger.setCreateBufferQueueFunction([](auto, auto, auto) { ADD_FAILURE() << "Unexpected request to create a buffer queue."; }); @@ -85,10 +82,17 @@ void DisplayTransactionTest::injectMockScheduler() { } void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) { + if (mComposer) { + // If reinjecting, disable first to prevent the enable below from being a no-op. + mFlinger.enableHalVirtualDisplays(false); + } + mComposer = new Hwc2::mock::Composer(); - EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount)); mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); + EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount)); + mFlinger.enableHalVirtualDisplays(true); + Mock::VerifyAndClear(mComposer); } @@ -135,18 +139,21 @@ sp<DisplayDevice> DisplayTransactionTest::injectDefaultInternalDisplay( EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(AnyNumber()); - auto compositionDisplay = compositionengine::impl:: - createDisplay(mFlinger.getCompositionEngine(), - compositionengine::DisplayCreationArgsBuilder() - .setPhysical( - {DEFAULT_DISPLAY_ID, ui::DisplayConnectionType::Internal}) - .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) - .setPowerAdvisor(&mPowerAdvisor) - .build()); - - auto injector = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, - ui::DisplayConnectionType::Internal, - DEFAULT_DISPLAY_HWC_DISPLAY_ID, true /* isPrimary */); + constexpr auto kConnectionType = ui::DisplayConnectionType::Internal; + constexpr bool kIsPrimary = true; + + auto compositionDisplay = + compositionengine::impl::createDisplay(mFlinger.getCompositionEngine(), + compositionengine::DisplayCreationArgsBuilder() + .setId(DEFAULT_DISPLAY_ID) + .setConnectionType(kConnectionType) + .setPixels({DEFAULT_DISPLAY_WIDTH, + DEFAULT_DISPLAY_HEIGHT}) + .setPowerAdvisor(&mPowerAdvisor) + .build()); + + auto injector = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, kConnectionType, + DEFAULT_DISPLAY_HWC_DISPLAY_ID, kIsPrimary); injector.setNativeWindow(mNativeWindow); if (injectExtra) { diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h index d68fff6345..6ce281d403 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h @@ -263,40 +263,23 @@ struct DisplayVariant { static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) { auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder(); - if (auto displayId = PhysicalDisplayId::tryCast(DISPLAY_ID::get())) { - ceDisplayArgs.setPhysical({*displayId, ui::DisplayConnectionType::Internal}); - } else { - // We turn off the use of HwcVirtualDisplays, to prevent Composition Engine - // from calling into HWComposer. This way all virtual displays will get - // a GpuVirtualDisplayId, even if we are in the HwcVirtualDisplayVariant. - // In this case we later override it by calling display.setDisplayIdForTesting(). - ceDisplayArgs.setUseHwcVirtualDisplays(false); - - GpuVirtualDisplayId desiredDisplayId = GpuVirtualDisplayId::tryCast(DISPLAY_ID::get()) - .value_or(GpuVirtualDisplayId(0)); - - ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId()) - .WillByDefault(Return(desiredDisplayId)); + ceDisplayArgs.setId(DISPLAY_ID::get()) + .setPixels({WIDTH, HEIGHT}) + .setPowerAdvisor(&test->mPowerAdvisor); - auto& generator = test->mFlinger.gpuVirtualDisplayIdGenerator(); - ceDisplayArgs.setGpuVirtualDisplayIdGenerator(generator); + const auto connectionType = CONNECTION_TYPE::value; + if (connectionType) { + ceDisplayArgs.setConnectionType(*connectionType); } - ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor); auto compositionDisplay = compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), ceDisplayArgs.build()); - if (HalVirtualDisplayId::tryCast(DISPLAY_ID::get())) { - // CompositionEngine has assigned a placeholder GpuVirtualDisplayId and we need to - // override it with the correct HalVirtualDisplayId. - compositionDisplay->setDisplayIdForTesting(DISPLAY_ID::get()); - } - auto injector = TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay, - CONNECTION_TYPE::value, + connectionType, HWC_DISPLAY_ID_OPT::value, static_cast<bool>(PRIMARY)); @@ -404,8 +387,8 @@ struct HwcDisplayVariant { ::testing::UnitTest::GetInstance()->current_test_info(); auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() - .setPhysical({DisplayVariant::DISPLAY_ID::get(), - PhysicalDisplay::CONNECTION_TYPE}) + .setId(DisplayVariant::DISPLAY_ID::get()) + .setConnectionType(PhysicalDisplay::CONNECTION_TYPE) .setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT}) .setIsSecure(static_cast<bool>(DisplayVariant::SECURE)) .setPowerAdvisor(&test->mPowerAdvisor) @@ -558,17 +541,13 @@ struct NonHwcVirtualDisplayVariant const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId()) - .WillByDefault(Return(Base::DISPLAY_ID::get())); - auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() + .setId(Base::DISPLAY_ID::get()) .setPixels({Base::WIDTH, Base::HEIGHT}) .setIsSecure(static_cast<bool>(Base::SECURE)) .setPowerAdvisor(&test->mPowerAdvisor) .setName(std::string("Injected display for ") + test_info->test_case_name() + "." + test_info->name()) - .setGpuVirtualDisplayIdGenerator( - test->mFlinger.gpuVirtualDisplayIdGenerator()) .build(); return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), @@ -610,35 +589,22 @@ struct HwcVirtualDisplayVariant const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - // In order to prevent compostition engine calling into HWComposer, we - // 1. turn off the use of HWC virtual displays, - // 2. provide a GpuVirtualDisplayIdGenerator which always returns some fake ID - // 3. override the ID by calling setDisplayIdForTesting() - - ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId()) - .WillByDefault(Return(GpuVirtualDisplayId(0))); - + const auto displayId = Base::DISPLAY_ID::get(); auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() - .setUseHwcVirtualDisplays(false) + .setId(displayId) .setPixels({Base::WIDTH, Base::HEIGHT}) .setIsSecure(static_cast<bool>(Base::SECURE)) .setPowerAdvisor(&test->mPowerAdvisor) .setName(std::string("Injected display for ") + test_info->test_case_name() + "." + test_info->name()) - .setGpuVirtualDisplayIdGenerator( - test->mFlinger.gpuVirtualDisplayIdGenerator()) .build(); auto compositionDisplay = compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), ceDisplayArgs); - compositionDisplay->setDisplayIdForTesting(Base::DISPLAY_ID::get()); // Insert display data so that the HWC thinks it created the virtual display. - if (const auto displayId = Base::DISPLAY_ID::get(); - HalVirtualDisplayId::tryCast(displayId)) { - test->mFlinger.mutableHwcDisplayData().try_emplace(displayId); - } + test->mFlinger.mutableHwcDisplayData().try_emplace(displayId); return compositionDisplay; } @@ -649,8 +615,8 @@ struct HwcVirtualDisplayVariant } static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) { - EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _)) - .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE))); + EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _, _)) + .WillOnce(DoAll(SetArgPointee<4>(Self::HWC_DISPLAY_ID), Return(Error::NONE))); EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE)); } }; diff --git a/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp b/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp index dec0ff5df2..010c675574 100644 --- a/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp +++ b/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp @@ -76,11 +76,9 @@ protected: static constexpr int32_t PRIORITY_UNSET = -1; void setupScheduler(); - void setupComposer(uint32_t virtualDisplayCount); sp<BufferStateLayer> createBufferStateLayer(LayerMetadata metadata); TestableSurfaceFlinger mFlinger; - Hwc2::mock::Composer* mComposer = nullptr; mock::FrameTimeline mFrameTimeline = mock::FrameTimeline(std::make_shared<impl::TimeStats>(), 0); @@ -103,7 +101,8 @@ FpsReporterTest::FpsReporterTest() { ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); setupScheduler(); - setupComposer(0); + mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); + mFpsListener = new TestableFpsListener(); } @@ -145,19 +144,11 @@ void FpsReporterTest::setupScheduler() { std::move(eventThread), std::move(sfEventThread)); } -void FpsReporterTest::setupComposer(uint32_t virtualDisplayCount) { - mComposer = new Hwc2::mock::Composer(); - EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount)); - mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); - - Mock::VerifyAndClear(mComposer); -} - namespace { TEST_F(FpsReporterTest, callsListeners) { mParent = createBufferStateLayer(); - const constexpr int32_t kTaskId = 12; + constexpr int32_t kTaskId = 12; LayerMetadata targetMetadata; targetMetadata.setInt32(METADATA_TASK_ID, kTaskId); mTarget = createBufferStateLayer(targetMetadata); diff --git a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp index cbf8cc21bd..655baf8a77 100644 --- a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp +++ b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp @@ -58,28 +58,26 @@ using ::testing::SetArgPointee; using ::testing::StrictMock; struct MockHWC2ComposerCallback final : StrictMock<HWC2::ComposerCallback> { - MOCK_METHOD3(onHotplugReceived, void(int32_t sequenceId, hal::HWDisplayId, hal::Connection)); - MOCK_METHOD2(onRefreshReceived, void(int32_t sequenceId, hal::HWDisplayId)); - MOCK_METHOD4(onVsyncReceived, - void(int32_t sequenceId, hal::HWDisplayId, int64_t timestamp, - std::optional<hal::VsyncPeriodNanos>)); - MOCK_METHOD3(onVsyncPeriodTimingChangedReceived, - void(int32_t sequenceId, hal::HWDisplayId, const hal::VsyncPeriodChangeTimeline&)); - MOCK_METHOD2(onSeamlessPossible, void(int32_t sequenceId, hal::HWDisplayId)); + MOCK_METHOD2(onComposerHalHotplug, void(hal::HWDisplayId, hal::Connection)); + MOCK_METHOD1(onComposerHalRefresh, void(hal::HWDisplayId)); + MOCK_METHOD3(onComposerHalVsync, + void(hal::HWDisplayId, int64_t timestamp, std::optional<hal::VsyncPeriodNanos>)); + MOCK_METHOD2(onComposerHalVsyncPeriodTimingChanged, + void(hal::HWDisplayId, const hal::VsyncPeriodChangeTimeline&)); + MOCK_METHOD1(onComposerHalSeamlessPossible, void(hal::HWDisplayId)); }; -struct HWComposerSetConfigurationTest : testing::Test { +struct HWComposerSetCallbackTest : testing::Test { Hwc2::mock::Composer* mHal = new StrictMock<Hwc2::mock::Composer>(); MockHWC2ComposerCallback mCallback; }; -TEST_F(HWComposerSetConfigurationTest, loadsLayerMetadataSupport) { +TEST_F(HWComposerSetCallbackTest, loadsLayerMetadataSupport) { const std::string kMetadata1Name = "com.example.metadata.1"; constexpr bool kMetadata1Mandatory = false; const std::string kMetadata2Name = "com.example.metadata.2"; constexpr bool kMetadata2Mandatory = true; - EXPECT_CALL(*mHal, getMaxVirtualDisplayCount()).WillOnce(Return(0)); EXPECT_CALL(*mHal, getCapabilities()).WillOnce(Return(std::vector<hal::Capability>{})); EXPECT_CALL(*mHal, getLayerGenericMetadataKeys(_)) .WillOnce(DoAll(SetArgPointee<0>(std::vector<hal::LayerGenericMetadataKey>{ @@ -91,7 +89,7 @@ TEST_F(HWComposerSetConfigurationTest, loadsLayerMetadataSupport) { EXPECT_CALL(*mHal, isVsyncPeriodSwitchSupported()).WillOnce(Return(false)); impl::HWComposer hwc{std::unique_ptr<Hwc2::Composer>(mHal)}; - hwc.setConfiguration(&mCallback, 123); + hwc.setCallback(&mCallback); const auto& supported = hwc.getSupportedLayerGenericMetadata(); EXPECT_EQ(2u, supported.size()); @@ -101,8 +99,7 @@ TEST_F(HWComposerSetConfigurationTest, loadsLayerMetadataSupport) { EXPECT_EQ(kMetadata2Mandatory, supported.find(kMetadata2Name)->second); } -TEST_F(HWComposerSetConfigurationTest, handlesUnsupportedCallToGetLayerGenericMetadataKeys) { - EXPECT_CALL(*mHal, getMaxVirtualDisplayCount()).WillOnce(Return(0)); +TEST_F(HWComposerSetCallbackTest, handlesUnsupportedCallToGetLayerGenericMetadataKeys) { EXPECT_CALL(*mHal, getCapabilities()).WillOnce(Return(std::vector<hal::Capability>{})); EXPECT_CALL(*mHal, getLayerGenericMetadataKeys(_)) .WillOnce(Return(hardware::graphics::composer::V2_4::Error::UNSUPPORTED)); @@ -110,7 +107,7 @@ TEST_F(HWComposerSetConfigurationTest, handlesUnsupportedCallToGetLayerGenericMe EXPECT_CALL(*mHal, isVsyncPeriodSwitchSupported()).WillOnce(Return(false)); impl::HWComposer hwc{std::unique_ptr<Hwc2::Composer>(mHal)}; - hwc.setConfiguration(&mCallback, 123); + hwc.setCallback(&mCallback); const auto& supported = hwc.getSupportedLayerGenericMetadata(); EXPECT_EQ(0u, supported.size()); diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp index 9c6ad06e1d..fd3e564cd9 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp @@ -60,7 +60,6 @@ protected: static constexpr int32_t PRIORITY_UNSET = -1; void setupScheduler(); - void setupComposer(uint32_t virtualDisplayCount); sp<BufferQueueLayer> createBufferQueueLayer(); sp<BufferStateLayer> createBufferStateLayer(); sp<EffectLayer> createEffectLayer(); @@ -69,7 +68,6 @@ protected: void commitTransaction(Layer* layer); TestableSurfaceFlinger mFlinger; - Hwc2::mock::Composer* mComposer = nullptr; sp<Client> mClient; sp<Layer> mParent; @@ -83,7 +81,7 @@ RefreshRateSelectionTest::RefreshRateSelectionTest() { ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); setupScheduler(); - setupComposer(0); + mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); } RefreshRateSelectionTest::~RefreshRateSelectionTest() { @@ -147,14 +145,6 @@ void RefreshRateSelectionTest::setupScheduler() { std::move(eventThread), std::move(sfEventThread)); } -void RefreshRateSelectionTest::setupComposer(uint32_t virtualDisplayCount) { - mComposer = new Hwc2::mock::Composer(); - EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount)); - mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); - - Mock::VerifyAndClear(mComposer); -} - namespace { /* ------------------------------------------------------------------------ * Test cases diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp index c088ddc971..46ef75091e 100644 --- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp +++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp @@ -118,14 +118,12 @@ protected: SetFrameRateTest(); void setupScheduler(); - void setupComposer(uint32_t virtualDisplayCount); void addChild(sp<Layer> layer, sp<Layer> child); void removeChild(sp<Layer> layer, sp<Layer> child); void commitTransaction(); TestableSurfaceFlinger mFlinger; - Hwc2::mock::Composer* mComposer = nullptr; mock::MessageQueue* mMessageQueue = new mock::MessageQueue(); std::vector<sp<Layer>> mLayers; @@ -139,10 +137,11 @@ SetFrameRateTest::SetFrameRateTest() { mFlinger.mutableUseFrameRateApi() = true; setupScheduler(); - setupComposer(0); + mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); mFlinger.mutableEventQueue().reset(mMessageQueue); } + void SetFrameRateTest::addChild(sp<Layer> layer, sp<Layer> child) { layer.get()->addChild(child.get()); } @@ -184,14 +183,6 @@ void SetFrameRateTest::setupScheduler() { /*hasMultipleModes*/ true); } -void SetFrameRateTest::setupComposer(uint32_t virtualDisplayCount) { - mComposer = new Hwc2::mock::Composer(); - EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount)); - mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); - - Mock::VerifyAndClear(mComposer); -} - namespace { /* ------------------------------------------------------------------------ * Test cases diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_OnHotplugReceivedTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp index 42f4cf31ba..bd89397ef6 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_OnHotplugReceivedTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp @@ -22,19 +22,15 @@ namespace android { namespace { -class OnHotplugReceivedTest : public DisplayTransactionTest {}; +class HotplugTest : public DisplayTransactionTest {}; -TEST_F(OnHotplugReceivedTest, hotplugEnqueuesEventsForDisplayTransaction) { - constexpr int currentSequenceId = 123; +TEST_F(HotplugTest, enqueuesEventsForDisplayTransaction) { constexpr HWDisplayId hwcDisplayId1 = 456; constexpr HWDisplayId hwcDisplayId2 = 654; // -------------------------------------------------------------------- // Preconditions - // Set the current sequence id for accepted events - mFlinger.mutableComposerSequenceId() = currentSequenceId; - // Set the main thread id so that the current thread does not appear to be // the main thread. mFlinger.mutableMainThreadId() = std::thread::id(); @@ -50,8 +46,8 @@ TEST_F(OnHotplugReceivedTest, hotplugEnqueuesEventsForDisplayTransaction) { // Invocation // Simulate two hotplug events (a connect and a disconnect) - mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId1, Connection::CONNECTED); - mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId2, Connection::DISCONNECTED); + mFlinger.onComposerHalHotplug(hwcDisplayId1, Connection::CONNECTED); + mFlinger.onComposerHalHotplug(hwcDisplayId2, Connection::DISCONNECTED); // -------------------------------------------------------------------- // Postconditions @@ -68,52 +64,14 @@ TEST_F(OnHotplugReceivedTest, hotplugEnqueuesEventsForDisplayTransaction) { EXPECT_EQ(Connection::DISCONNECTED, pendingEvents[1].connection); } -TEST_F(OnHotplugReceivedTest, hotplugDiscardsUnexpectedEvents) { - constexpr int currentSequenceId = 123; - constexpr int otherSequenceId = 321; - constexpr HWDisplayId displayId = 456; - - // -------------------------------------------------------------------- - // Preconditions - - // Set the current sequence id for accepted events - mFlinger.mutableComposerSequenceId() = currentSequenceId; - - // Set the main thread id so that the current thread does not appear to be - // the main thread. - mFlinger.mutableMainThreadId() = std::thread::id(); - - // -------------------------------------------------------------------- - // Call Expectations - - // We do not expect any calls to invalidate(). - EXPECT_CALL(*mMessageQueue, invalidate()).Times(0); - - // -------------------------------------------------------------------- - // Invocation - - // Call with an unexpected sequence id - mFlinger.onHotplugReceived(otherSequenceId, displayId, Connection::INVALID); - - // -------------------------------------------------------------------- - // Postconditions - - // The display transaction needed flag should not be set - EXPECT_FALSE(hasTransactionFlagSet(eDisplayTransactionNeeded)); - - // There should be no pending events - EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty()); -} - -TEST_F(OnHotplugReceivedTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread) { - constexpr int currentSequenceId = 123; +TEST_F(HotplugTest, processesEnqueuedEventsIfCalledOnMainThread) { constexpr HWDisplayId displayId1 = 456; // -------------------------------------------------------------------- // Note: // -------------------------------------------------------------------- // This test case is a bit tricky. We want to verify that - // onHotplugReceived() calls processDisplayHotplugEventsLocked(), but we + // onComposerHalHotplug() calls processDisplayHotplugEventsLocked(), but we // don't really want to provide coverage for everything the later function // does as there are specific tests for it. // -------------------------------------------------------------------- @@ -121,9 +79,6 @@ TEST_F(OnHotplugReceivedTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread // -------------------------------------------------------------------- // Preconditions - // Set the current sequence id for accepted events - mFlinger.mutableComposerSequenceId() = currentSequenceId; - // Set the main thread id so that the current thread does appear to be the // main thread. mFlinger.mutableMainThreadId() = std::this_thread::get_id(); @@ -139,9 +94,9 @@ TEST_F(OnHotplugReceivedTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread // Invocation // Simulate a disconnect on a display id that is not connected. This should - // be enqueued by onHotplugReceived(), and dequeued by + // be enqueued by onComposerHalHotplug(), and dequeued by // processDisplayHotplugEventsLocked(), but then ignored as invalid. - mFlinger.onHotplugReceived(currentSequenceId, displayId1, Connection::DISCONNECTED); + mFlinger.onComposerHalHotplug(displayId1, Connection::DISCONNECTED); // -------------------------------------------------------------------- // Postconditions @@ -155,4 +110,4 @@ TEST_F(OnHotplugReceivedTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread } } // namespace -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index a551248dd6..d78f36cd27 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -42,7 +42,6 @@ #include "SurfaceInterceptor.h" #include "TestableScheduler.h" #include "mock/DisplayHardware/MockComposer.h" -#include "mock/MockDisplayIdGenerator.h" #include "mock/MockFrameTimeline.h" #include "mock/MockFrameTracer.h" @@ -185,9 +184,6 @@ public: SurfaceFlinger* flinger() { return mFlinger.get(); } TestableScheduler* scheduler() { return mScheduler; } - mock::DisplayIdGenerator<GpuVirtualDisplayId>& gpuVirtualDisplayIdGenerator() { - return mGpuVirtualDisplayIdGenerator; - } // Extend this as needed for accessing SurfaceFlinger private (and public) // functions. @@ -309,6 +305,8 @@ public: return mFlinger->destroyDisplay(displayToken); } + void enableHalVirtualDisplays(bool enable) { mFlinger->enableHalVirtualDisplays(enable); } + auto setupNewDisplayDeviceInternal( const wp<IBinder>& displayToken, std::shared_ptr<compositionengine::Display> compositionDisplay, @@ -324,9 +322,8 @@ public: return mFlinger->handleTransactionLocked(transactionFlags); } - auto onHotplugReceived(int32_t sequenceId, hal::HWDisplayId display, - hal::Connection connection) { - return mFlinger->onHotplugReceived(sequenceId, display, connection); + void onComposerHalHotplug(hal::HWDisplayId hwcDisplayId, hal::Connection connection) { + mFlinger->onComposerHalHotplug(hwcDisplayId, connection); } auto setDisplayStateLocked(const DisplayState& s) { @@ -437,11 +434,9 @@ public: auto& mutablePhysicalDisplayTokens() { return mFlinger->mPhysicalDisplayTokens; } auto& mutableTexturePool() { return mFlinger->mTexturePool; } auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; } - auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; } auto& mutablePowerAdvisor() { return mFlinger->mPowerAdvisor; } auto& mutableDebugDisableHWC() { return mFlinger->mDebugDisableHWC; } - auto& mutableComposerSequenceId() { return mFlinger->getBE().mComposerSequenceId; } auto& mutableHwcDisplayData() { return getHwComposer().mDisplayData; } auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; } auto& mutableInternalHwcDisplayId() { return getHwComposer().mInternalHwcDisplayId; } @@ -776,7 +771,6 @@ private: surfaceflinger::test::Factory mFactory; sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization); TestableScheduler* mScheduler = nullptr; - mock::DisplayIdGenerator<GpuVirtualDisplayId> mGpuVirtualDisplayIdGenerator; }; } // namespace android diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp index 25001d3890..546bc4a17b 100644 --- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp @@ -45,7 +45,7 @@ public: ::testing::UnitTest::GetInstance()->current_test_info(); ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); setupScheduler(); - setupComposer(0); + mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); } ~TransactionFrameTracerTest() { @@ -91,17 +91,9 @@ public: std::move(eventThread), std::move(sfEventThread)); } - void setupComposer(uint32_t virtualDisplayCount) { - mComposer = new Hwc2::mock::Composer(); - EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount)); - mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); - - Mock::VerifyAndClear(mComposer); - } - TestableSurfaceFlinger mFlinger; - Hwc2::mock::Composer* mComposer = nullptr; renderengine::mock::RenderEngine mRenderEngine; + FenceToFenceTimeMap fenceFactory; client_cache_t mClientCache; diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp index b7917aa00e..c1123cd6e8 100644 --- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp @@ -45,7 +45,7 @@ public: ::testing::UnitTest::GetInstance()->current_test_info(); ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); setupScheduler(); - setupComposer(0); + mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); } ~TransactionSurfaceFrameTest() { @@ -91,17 +91,9 @@ public: std::move(eventThread), std::move(sfEventThread)); } - void setupComposer(uint32_t virtualDisplayCount) { - mComposer = new Hwc2::mock::Composer(); - EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount)); - mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); - - Mock::VerifyAndClear(mComposer); - } - TestableSurfaceFlinger mFlinger; - Hwc2::mock::Composer* mComposer = nullptr; renderengine::mock::RenderEngine mRenderEngine; + FenceToFenceTimeMap fenceFactory; client_cache_t mClientCache; diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h index 1ba3c0f56e..cb3bd73920 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -54,7 +54,8 @@ public: MOCK_METHOD0(resetCommands, void()); MOCK_METHOD0(executeCommands, Error()); MOCK_METHOD0(getMaxVirtualDisplayCount, uint32_t()); - MOCK_METHOD4(createVirtualDisplay, Error(uint32_t, uint32_t, PixelFormat*, Display*)); + MOCK_METHOD5(createVirtualDisplay, + Error(uint32_t, uint32_t, PixelFormat*, std::optional<Display>, Display*)); MOCK_METHOD1(destroyVirtualDisplay, Error(Display)); MOCK_METHOD1(acceptDisplayChanges, Error(Display)); MOCK_METHOD2(createLayer, Error(Display, Layer* outLayer)); diff --git a/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h b/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h deleted file mode 100644 index cfc37ea8d9..0000000000 --- a/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020 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 <gmock/gmock.h> - -#include "DisplayIdGenerator.h" - -namespace android::mock { - -template <typename T> -class DisplayIdGenerator : public android::DisplayIdGenerator<T> { -public: - // Explicit default instantiation is recommended. - DisplayIdGenerator() = default; - virtual ~DisplayIdGenerator() = default; - - MOCK_METHOD0(nextId, std::optional<T>()); - MOCK_METHOD1(markUnused, void(T)); -}; - -} // namespace android::mock |