[SurfaceFlinger] Add composition unit tests
Adds some simple tests to verify the hardware and software composition
of a range of layer types, using mocks to verify the right calls are
made to the HWC and RE interfaces
Test: atest libsurfaceflinger_unittest
Bug: 76421986
Bug: 76432611
Change-Id: Ic3f81008c2182048851a8ab32388e54ee815927a
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 1bba480..341734c 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -17,6 +17,7 @@
#pragma once
#include "DisplayDevice.h"
+#include "Layer.h"
#include "SurfaceFlinger.h"
namespace android {
@@ -56,6 +57,21 @@
using HotplugEvent = SurfaceFlinger::HotplugEvent;
+ auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mCurrentState; }
+ auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mDrawingState; }
+
+ void setLayerSidebandStream(sp<Layer> layer, sp<NativeHandle> sidebandStream) {
+ layer->getBE().compositionInfo.hwc.sidebandStream = sidebandStream;
+ }
+
+ void setLayerCompositionType(sp<Layer> layer, HWC2::Composition type) {
+ layer->getBE().mHwcLayers[DisplayDevice::DISPLAY_PRIMARY].compositionType = type;
+ };
+
+ void setLayerPotentialCursor(sp<Layer> layer, bool potentialCursor) {
+ layer->mPotentialCursor = potentialCursor;
+ }
+
/* ------------------------------------------------------------------------
* Forwarding for functions being tested
*/
@@ -96,6 +112,21 @@
return mFlinger->setPowerModeInternal(display, mode, stateLockHeld);
}
+ auto onMessageReceived(int32_t what) { return mFlinger->onMessageReceived(what); }
+
+ auto captureScreenImplLocked(const RenderArea& renderArea,
+ TraverseLayersFunction traverseLayers, ANativeWindowBuffer* buffer,
+ bool useIdentityTransform, bool forSystem, int* outSyncFd) {
+ return mFlinger->captureScreenImplLocked(renderArea, traverseLayers, buffer,
+ useIdentityTransform, forSystem, outSyncFd);
+ }
+
+ auto traverseLayersInDisplay(const sp<const DisplayDevice>& display, int32_t minLayerZ,
+ int32_t maxLayerZ, const LayerVector::Visitor& visitor) {
+ return mFlinger->SurfaceFlinger::traverseLayersInDisplay(display, minLayerZ, maxLayerZ,
+ visitor);
+ }
+
/* ------------------------------------------------------------------------
* Read-only access to private data to assert post-conditions.
*/
@@ -116,20 +147,22 @@
auto& mutablePrimaryDisplayOrientation() { return SurfaceFlinger::primaryDisplayOrientation; }
auto& mutableUseColorManagement() { return SurfaceFlinger::useColorManagement; }
- auto& mutableDisplayTokens() { return mFlinger->mDisplayTokens; }
auto& mutableCurrentState() { return mFlinger->mCurrentState; }
- auto& mutableDisplays() { return mFlinger->mDisplays; }
auto& mutableDisplayColorSetting() { return mFlinger->mDisplayColorSetting; }
+ auto& mutableDisplays() { return mFlinger->mDisplays; }
+ auto& mutableDisplayTokens() { return mFlinger->mDisplayTokens; }
auto& mutableDrawingState() { return mFlinger->mDrawingState; }
auto& mutableEventControlThread() { return mFlinger->mEventControlThread; }
auto& mutableEventQueue() { return mFlinger->mEventQueue; }
auto& mutableEventThread() { return mFlinger->mEventThread; }
+ auto& mutableGeometryInvalid() { return mFlinger->mGeometryInvalid; }
auto& mutableHWVsyncAvailable() { return mFlinger->mHWVsyncAvailable; }
auto& mutableInterceptor() { return mFlinger->mInterceptor; }
auto& mutableMainThreadId() { return mFlinger->mMainThreadId; }
auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
auto& mutablePrimaryDispSync() { return mFlinger->mPrimaryDispSync; }
auto& mutablePrimaryHWVsyncEnabled() { return mFlinger->mPrimaryHWVsyncEnabled; }
+ auto& mutableTexturePool() { return mFlinger->mTexturePool; }
auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; }
@@ -175,6 +208,7 @@
auto& mutableIsConnected() { return this->mIsConnected; }
auto& mutableConfigs() { return this->mConfigs; }
+ auto& mutableLayers() { return this->mLayers; }
};
class FakeHwcDisplayInjector {
@@ -324,14 +358,25 @@
return *this;
}
+ auto& setDisplaySize(int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ return *this;
+ }
+
+ auto& setPowerMode(int mode) {
+ mPowerMode = mode;
+ return *this;
+ }
+
sp<DisplayDevice> inject() {
std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hdrAndRenderIntents;
sp<DisplayDevice> device =
new DisplayDevice(mFlinger.mFlinger.get(), mType, mDisplayId, mSecure,
mDisplayToken, mNativeWindow, mDisplaySurface,
- std::move(mRenderSurface), 0, 0,
+ std::move(mRenderSurface), mWidth, mHeight,
DisplayState::eOrientationDefault, false, HdrCapabilities(),
- 0, hdrAndRenderIntents, HWC_POWER_MODE_NORMAL);
+ 0, hdrAndRenderIntents, mPowerMode);
mFlinger.mutableDisplays().emplace(mDisplayToken, device);
DisplayDeviceState state;
@@ -356,6 +401,9 @@
sp<DisplaySurface> mDisplaySurface;
std::unique_ptr<renderengine::Surface> mRenderSurface;
bool mSecure = false;
+ int mWidth = 0;
+ int mHeight = 0;
+ int mPowerMode = HWC_POWER_MODE_NORMAL;
};
sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(SurfaceFlinger::SkipInitialization);