Merge "Put debug/log code under verbose flag" into sc-dev
diff --git a/data/etc/car_core_hardware.xml b/data/etc/car_core_hardware.xml
index adfd6e2..cc0ee82 100644
--- a/data/etc/car_core_hardware.xml
+++ b/data/etc/car_core_hardware.xml
@@ -47,12 +47,6 @@
<feature name="android.software.secure_lock_screen" />
<feature name="android.software.input_methods" />
-
- <!-- Feature to support device admins -->
- <!-- TODO(b/178412797): not fully supported yet, CTS tests are still
- failing. -->
- <feature name="android.software.device_admin" />
-
<!-- devices with GPS must include android.hardware.location.gps.xml -->
<!-- devices with an autofocus camera and/or flash must include either
android.hardware.camera.autofocus.xml or
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index be260e8..91cd90d 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -68,6 +68,8 @@
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 0000000..9ca14bc
--- /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 ada689a..75f2385 100644
--- a/libs/nativewindow/ANativeWindow.cpp
+++ b/libs/nativewindow/ANativeWindow.cpp
@@ -213,6 +213,7 @@
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 f576660..de36a7a 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -1453,7 +1453,9 @@
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/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index e3e6c12..b19b419 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -67,6 +67,8 @@
// v4l2 devices go directly into /dev
static const char* VIDEO_DEVICE_PATH = "/dev";
+static constexpr size_t OBFUSCATED_LENGTH = 8;
+
static constexpr int32_t FF_STRONG_MAGNITUDE_CHANNEL_IDX = 0;
static constexpr int32_t FF_WEAK_MAGNITUDE_CHANNEL_IDX = 1;
@@ -1828,9 +1830,21 @@
void EventHub::reportDeviceAddedForStatisticsLocked(const InputDeviceIdentifier& identifier,
Flags<InputDeviceClass> classes) {
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, reinterpret_cast<const uint8_t*>(identifier.uniqueId.c_str()),
+ identifier.uniqueId.size());
+ std::array<uint8_t, SHA256_DIGEST_LENGTH> digest;
+ SHA256_Final(digest.data(), &ctx);
+
+ std::string obfuscatedId;
+ for (size_t i = 0; i < OBFUSCATED_LENGTH; i++) {
+ obfuscatedId += StringPrintf("%02x", digest[i]);
+ }
+
android::util::stats_write(android::util::INPUTDEVICE_REGISTERED, identifier.name.c_str(),
identifier.vendor, identifier.product, identifier.version,
- identifier.bus, identifier.uniqueId.c_str(), classes.get());
+ identifier.bus, obfuscatedId.c_str(), classes.get());
}
void EventHub::openDeviceLocked(const std::string& devicePath) {
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index cacad52..23779be 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -425,7 +425,8 @@
mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence,
refreshRate, renderRate,
frameRateToSetFrameRateVotePayload(
- mDrawingState.frameRate));
+ mDrawingState.frameRate),
+ getGameMode());
mFlinger->mFrameTracer->traceFence(layerId, getCurrentBufferId(), mCurrentFrameNumber,
presentFence, FrameTracer::FrameEvent::PRESENT_FENCE);
mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
@@ -439,7 +440,8 @@
mFlinger->mTimeStats->setPresentTime(layerId, mCurrentFrameNumber, actualPresentTime,
refreshRate, renderRate,
frameRateToSetFrameRateVotePayload(
- mDrawingState.frameRate));
+ mDrawingState.frameRate),
+ getGameMode());
mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(), mCurrentFrameNumber,
actualPresentTime,
FrameTracer::FrameEvent::PRESENT_FENCE);
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 54daa10..5298772 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -444,7 +444,7 @@
const int32_t layerId = getSequence();
mFlinger->mTimeStats->setPostTime(layerId, mCurrentState.frameNumber, getName().c_str(),
- mOwnerUid, postTime);
+ mOwnerUid, postTime, getGameMode());
mCurrentState.desiredPresentTime = desiredPresentTime;
mCurrentState.isAutoTimestamp = isAutoTimestamp;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 633668e..14eddb1 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 @@
* 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 @@
// 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,8 +64,13 @@
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& setConnectionType(ui::DisplayConnectionType connectionType) {
+ mArgs.connectionType = connectionType;
return *this;
}
@@ -90,22 +79,6 @@
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;
- return *this;
- }
-
DisplayCreationArgsBuilder& setIsSecure(bool isSecure) {
mArgs.isSecure = isSecure;
return *this;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
index a8d372c..4110346 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 @@
// 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 @@
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 @@
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 54e91ae..bb540ea 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -80,19 +80,13 @@
// 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/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
index 801dc74..4e2f879 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
@@ -93,6 +93,7 @@
mOutputDataspace = ui::Dataspace::UNKNOWN;
mDrawFence = nullptr;
mBlurLayer = nullptr;
+ mHolePunchLayer = nullptr;
mLayers.insert(mLayers.end(), other.mLayers.cbegin(), other.mLayers.cend());
Region boundingRegion;
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 3d49183..ae1336e 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -50,36 +50,14 @@
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 @@
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) {
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index 0a67050..9a294c7 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -228,7 +228,6 @@
// 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);
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index ac3ba0d..db9437b 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::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 @@
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 @@
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 @@
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 @@
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 @@
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, 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,25 +290,17 @@
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));
+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());
- 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_EQ(HAL_VIRTUAL_DISPLAY_ID, mDisplay->getId());
EXPECT_FALSE(mDisplay->isSecure());
EXPECT_TRUE(mDisplay->isVirtual());
EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId);
@@ -329,47 +308,17 @@
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));
+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());
- 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()));
- 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, 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()));
+ 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, 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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) {
@@ -875,11 +828,11 @@
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());
@@ -908,9 +861,9 @@
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]);
}
@@ -956,66 +909,66 @@
}
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);
}
/*
@@ -1040,23 +993,26 @@
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) {
@@ -1072,6 +1028,3 @@
} // 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 cd2d09e..64cbea9 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -39,14 +39,17 @@
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/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 9aeb290..5090bb2 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 @@
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 @@
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 591f981..8eeb0bf 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -557,6 +557,75 @@
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, append_removesHolePunch) {
+ mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
+ mTestLayers[0]->layerFECompositionState.isOpaque = true;
+ CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
+ CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
+ CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
+
+ CachedSet cachedSet(layer1);
+ cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
+
+ cachedSet.addHolePunchLayerIfFeasible(layer3, false);
+
+ ASSERT_EQ(&mTestLayers[2]->outputLayer, cachedSet.getHolePunchLayer());
+
+ CachedSet cachedSet3(layer3);
+ cachedSet.append(cachedSet3);
+ ASSERT_EQ(nullptr, cachedSet.getHolePunchLayer());
+}
+
TEST_F(CachedSetTest, decompose_removesHolePunch) {
mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 0f18235..ca4b6ab 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -70,13 +70,14 @@
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 bf249cd..7e4d923 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -103,15 +103,21 @@
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;
}
- DisplayId getId() const;
+ VirtualDisplayId getVirtualId() const {
+ const auto id = VirtualDisplayId::tryCast(getId());
+ LOG_FATAL_IF(!id);
+ return *id;
+ }
+
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
int32_t getSequenceId() const { return mSequenceId; }
@@ -285,4 +291,16 @@
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 1cbcf59..caf0294 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -211,9 +211,8 @@
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 0619b8c..b525e63 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 @@
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 @@
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 fae95e7..871465d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -56,20 +56,16 @@
// 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 36876dc..32f04e5 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 @@
class ComposerCallbackBridge : public hal::IComposerCallback {
public:
- ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId,
- bool vsyncSwitchingSupported)
- : mCallback(callback),
- mSequenceId(sequenceId),
- mVsyncSwitchingSupported(vsyncSwitchingSupported) {}
+ ComposerCallbackBridge(ComposerCallback* callback, bool vsyncSwitchingSupported)
+ : mCallback(callback), mVsyncSwitchingSupported(vsyncSwitchingSupported) {}
- Return<void> onHotplug(hal::HWDisplayId display, hal::Connection conn) override {
- mCallback->onHotplugReceived(mSequenceId, display, conn);
+ 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 @@
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 @@
}
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 @@
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 @@
mDisplayData.clear();
}
-void HWComposer::setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) {
+void HWComposer::setCallback(HWC2::ComposerCallback* callback) {
loadCapabilities();
loadLayerMetadataSupport();
@@ -164,10 +158,9 @@
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 @@
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;
+ 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, &hwcDisplayId));
- if (error != hal::Error::NONE) {
- ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__);
- mVirtualIdGenerator.markUnused(*displayId);
- return {};
- }
+ 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 @@
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 @@
}
}
-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 d0c0c11..cd6f9f5 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 @@
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 @@
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 @@
~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 @@
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 @@
void loadCapabilities();
void loadLayerMetadataSupport();
- uint32_t getMaxVirtualDisplayCount() const;
std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
@@ -416,8 +423,7 @@
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 e7c69a8..9791a25 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 @@
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 @@
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/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index 9b03287..3523b56 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -304,7 +304,7 @@
frametimeline::TimelineItem&& predictions,
std::shared_ptr<TimeStats> timeStats,
JankClassificationThresholds thresholds,
- TraceCookieCounter* traceCookieCounter, bool isBuffer)
+ TraceCookieCounter* traceCookieCounter, bool isBuffer, int32_t gameMode)
: mToken(frameTimelineInfo.vsyncId),
mInputEventId(frameTimelineInfo.inputEventId),
mOwnerPid(ownerPid),
@@ -319,7 +319,8 @@
mTimeStats(timeStats),
mJankClassificationThresholds(thresholds),
mTraceCookieCounter(*traceCookieCounter),
- mIsBuffer(isBuffer) {}
+ mIsBuffer(isBuffer),
+ mGameMode(gameMode) {}
void SurfaceFrame::setActualStartTime(nsecs_t actualStartTime) {
std::scoped_lock lock(mMutex);
@@ -607,8 +608,8 @@
if (mPredictionState != PredictionState::None) {
// Only update janky frames if the app used vsync predictions
mTimeStats->incrementJankyFrames({refreshRate, mRenderRate, mOwnerUid, mLayerName,
- mJankType, displayDeadlineDelta, displayPresentDelta,
- deadlineDelta});
+ mGameMode, mJankType, displayDeadlineDelta,
+ displayPresentDelta, deadlineDelta});
}
}
@@ -776,14 +777,14 @@
std::shared_ptr<SurfaceFrame> FrameTimeline::createSurfaceFrameForToken(
const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid, int32_t layerId,
- std::string layerName, std::string debugName, bool isBuffer) {
+ std::string layerName, std::string debugName, bool isBuffer, int32_t gameMode) {
ATRACE_CALL();
if (frameTimelineInfo.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
return std::make_shared<SurfaceFrame>(frameTimelineInfo, ownerPid, ownerUid, layerId,
std::move(layerName), std::move(debugName),
PredictionState::None, TimelineItem(), mTimeStats,
mJankClassificationThresholds, &mTraceCookieCounter,
- isBuffer);
+ isBuffer, gameMode);
}
std::optional<TimelineItem> predictions =
mTokenManager.getPredictionsForToken(frameTimelineInfo.vsyncId);
@@ -792,13 +793,13 @@
std::move(layerName), std::move(debugName),
PredictionState::Valid, std::move(*predictions),
mTimeStats, mJankClassificationThresholds,
- &mTraceCookieCounter, isBuffer);
+ &mTraceCookieCounter, isBuffer, gameMode);
}
return std::make_shared<SurfaceFrame>(frameTimelineInfo, ownerPid, ownerUid, layerId,
std::move(layerName), std::move(debugName),
PredictionState::Expired, TimelineItem(), mTimeStats,
mJankClassificationThresholds, &mTraceCookieCounter,
- isBuffer);
+ isBuffer, gameMode);
}
FrameTimeline::DisplayFrame::DisplayFrame(std::shared_ptr<TimeStats> timeStats,
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
index 42be55a..15ecf13 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
@@ -154,7 +154,7 @@
int32_t layerId, std::string layerName, std::string debugName,
PredictionState predictionState, TimelineItem&& predictions,
std::shared_ptr<TimeStats> timeStats, JankClassificationThresholds thresholds,
- TraceCookieCounter* traceCookieCounter, bool isBuffer);
+ TraceCookieCounter* traceCookieCounter, bool isBuffer, int32_t gameMode);
~SurfaceFrame() = default;
// Returns std::nullopt if the frame hasn't been classified yet.
@@ -259,6 +259,8 @@
// Tells if the SurfaceFrame is representing a buffer or a transaction without a
// buffer(animations)
bool mIsBuffer;
+ // GameMode from the layer. Used in metrics.
+ int32_t mGameMode = 0;
};
/*
@@ -278,7 +280,8 @@
// Debug name is the human-readable debugging string for dumpsys.
virtual std::shared_ptr<SurfaceFrame> createSurfaceFrameForToken(
const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid,
- int32_t layerId, std::string layerName, std::string debugName, bool isBuffer) = 0;
+ int32_t layerId, std::string layerName, std::string debugName, bool isBuffer,
+ int32_t gameMode) = 0;
// Adds a new SurfaceFrame to the current DisplayFrame. Frames from multiple layers can be
// composited into one display frame.
@@ -437,7 +440,8 @@
frametimeline::TokenManager* getTokenManager() override { return &mTokenManager; }
std::shared_ptr<SurfaceFrame> createSurfaceFrameForToken(
const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid,
- int32_t layerId, std::string layerName, std::string debugName, bool isBuffer) override;
+ int32_t layerId, std::string layerName, std::string debugName, bool isBuffer,
+ int32_t gameMode) override;
void addSurfaceFrame(std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame) override;
void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate) override;
void setSfPresent(nsecs_t sfPresentTime, const std::shared_ptr<FenceTime>& presentFence,
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 9fcc17c..e50087f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1357,7 +1357,7 @@
mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
getSequence(), mName,
mTransactionName,
- /*isBuffer*/ false);
+ /*isBuffer*/ false, getGameMode());
// For Transactions, the post time is considered to be both queue and acquire fence time.
surfaceFrame->setActualQueueTime(postTime);
surfaceFrame->setAcquireFenceTime(postTime);
@@ -1374,7 +1374,7 @@
auto surfaceFrame =
mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
getSequence(), mName, debugName,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, getGameMode());
// For buffers, acquire fence time will set during latch.
surfaceFrame->setActualQueueTime(queueTime);
const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
@@ -1635,7 +1635,8 @@
FrameEventHistoryDelta* outDelta) {
if (newTimestamps) {
mFlinger->mTimeStats->setPostTime(getSequence(), newTimestamps->frameNumber,
- getName().c_str(), mOwnerUid, newTimestamps->postedTime);
+ getName().c_str(), mOwnerUid, newTimestamps->postedTime,
+ getGameMode());
mFlinger->mTimeStats->setAcquireFence(getSequence(), newTimestamps->frameNumber,
newTimestamps->acquireFence);
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index af26045..dde0031 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -850,9 +850,9 @@
// Sets the parent's gameMode for this layer and all its children. Parent's gameMode is applied
// only to layers that do not have the GAME_MODE_METADATA set by WMShell. Any layer(along with
// its children) that has the metadata set will use the gameMode from the metadata.
- void setGameModeForTree(int parentGameMode);
- void setGameMode(int gameMode) { mGameMode = gameMode; };
- int getGameMode() const { return mGameMode; }
+ void setGameModeForTree(int32_t parentGameMode);
+ void setGameMode(int32_t gameMode) { mGameMode = gameMode; };
+ int32_t getGameMode() const { return mGameMode; }
virtual uid_t getOwnerUid() const { return mOwnerUid; }
@@ -1098,7 +1098,7 @@
// Game mode for the layer. Set by WindowManagerShell, game mode is used in
// metrics(SurfaceFlingerStats).
- int mGameMode = 0;
+ int32_t mGameMode = 0;
// A list of regions on this layer that should have blurs.
const std::vector<BlurRegion> getBlurRegions() const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d76c274..2b4f9ef 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -295,7 +295,6 @@
// ---------------------------------------------------------------------------
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 @@
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 @@
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 @@
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 @@
.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();
@@ -1612,16 +1663,11 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
- const auto display = getDisplayByLayerStack(parent->getLayerStack());
+ const auto display = findDisplay(WithLayerStack(parent->getLayerStack()));
if (!display) {
return NAME_NOT_FOUND;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 30d76af..be3417b 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -170,11 +170,6 @@
};
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index d6a0787..f1b153f 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -58,6 +58,21 @@
return histogramProto;
}
+SurfaceflingerStatsLayerInfo_GameMode gameModeToProto(int32_t gameMode) {
+ switch (gameMode) {
+ case TimeStatsHelper::GameModeUnsupported:
+ return SurfaceflingerStatsLayerInfo::GAME_MODE_UNSUPPORTED;
+ case TimeStatsHelper::GameModeStandard:
+ return SurfaceflingerStatsLayerInfo::GAME_MODE_STANDARD;
+ case TimeStatsHelper::GameModePerformance:
+ return SurfaceflingerStatsLayerInfo::GAME_MODE_PERFORMANCE;
+ case TimeStatsHelper::GameModeBattery:
+ return SurfaceflingerStatsLayerInfo::GAME_MODE_BATTERY;
+ default:
+ return SurfaceflingerStatsLayerInfo::GAME_MODE_UNSPECIFIED;
+ }
+}
+
SurfaceflingerStatsLayerInfo_SetFrameRateVote frameRateVoteToProto(
const TimeStats::SetFrameRateVote& setFrameRateVote) {
using FrameRateCompatibilityEnum =
@@ -206,6 +221,7 @@
*atom->mutable_app_deadline_misses() =
histogramToProto(layer->deltas["appDeadlineDeltas"].hist,
mMaxPulledHistogramBuckets);
+ atom->set_game_mode(gameModeToProto(layer->gameMode));
}
// Always clear data.
@@ -437,7 +453,8 @@
void TimeStats::flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate,
std::optional<Fps> renderRate,
- SetFrameRateVote frameRateVote) {
+ SetFrameRateVote frameRateVote,
+ int32_t gameMode) {
ATRACE_CALL();
ALOGV("[%d]-flushAvailableRecordsToStatsLocked", layerId);
@@ -464,12 +481,13 @@
TimeStatsHelper::TimelineStats& displayStats = mTimeStats.stats[timelineKey];
- TimeStatsHelper::LayerStatsKey layerKey = {uid, layerName};
+ TimeStatsHelper::LayerStatsKey layerKey = {uid, layerName, gameMode};
if (!displayStats.stats.count(layerKey)) {
displayStats.stats[layerKey].displayRefreshRateBucket = refreshRateBucket;
displayStats.stats[layerKey].renderRateBucket = renderRateBucket;
displayStats.stats[layerKey].uid = uid;
displayStats.stats[layerKey].layerName = layerName;
+ displayStats.stats[layerKey].gameMode = gameMode;
}
if (frameRateVote.frameRate > 0.0f) {
displayStats.stats[layerKey].setFrameRateVote = frameRateVote;
@@ -535,10 +553,11 @@
layerName.compare(0, kMinLenLayerName, kPopupWindowPrefix) != 0;
}
-bool TimeStats::canAddNewAggregatedStats(uid_t uid, const std::string& layerName) {
+bool TimeStats::canAddNewAggregatedStats(uid_t uid, const std::string& layerName,
+ int32_t gameMode) {
uint32_t layerRecords = 0;
for (const auto& record : mTimeStats.stats) {
- if (record.second.stats.count({uid, layerName}) > 0) {
+ if (record.second.stats.count({uid, layerName, gameMode}) > 0) {
return true;
}
@@ -549,7 +568,7 @@
}
void TimeStats::setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName,
- uid_t uid, nsecs_t postTime) {
+ uid_t uid, nsecs_t postTime, int32_t gameMode) {
if (!mEnabled.load()) return;
ATRACE_CALL();
@@ -557,13 +576,14 @@
postTime);
std::lock_guard<std::mutex> lock(mMutex);
- if (!canAddNewAggregatedStats(uid, layerName)) {
+ if (!canAddNewAggregatedStats(uid, layerName, gameMode)) {
return;
}
if (!mTimeStatsTracker.count(layerId) && mTimeStatsTracker.size() < MAX_NUM_LAYER_RECORDS &&
layerNameIsValid(layerName)) {
mTimeStatsTracker[layerId].uid = uid;
mTimeStatsTracker[layerId].layerName = layerName;
+ mTimeStatsTracker[layerId].gameMode = gameMode;
}
if (!mTimeStatsTracker.count(layerId)) return;
LayerRecord& layerRecord = mTimeStatsTracker[layerId];
@@ -698,7 +718,7 @@
void TimeStats::setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
Fps displayRefreshRate, std::optional<Fps> renderRate,
- SetFrameRateVote frameRateVote) {
+ SetFrameRateVote frameRateVote, int32_t gameMode) {
if (!mEnabled.load()) return;
ATRACE_CALL();
@@ -717,13 +737,14 @@
layerRecord.waitData++;
}
- flushAvailableRecordsToStatsLocked(layerId, displayRefreshRate, renderRate, frameRateVote);
+ flushAvailableRecordsToStatsLocked(layerId, displayRefreshRate, renderRate, frameRateVote,
+ gameMode);
}
void TimeStats::setPresentFence(int32_t layerId, uint64_t frameNumber,
const std::shared_ptr<FenceTime>& presentFence,
Fps displayRefreshRate, std::optional<Fps> renderRate,
- SetFrameRateVote frameRateVote) {
+ SetFrameRateVote frameRateVote, int32_t gameMode) {
if (!mEnabled.load()) return;
ATRACE_CALL();
@@ -743,7 +764,8 @@
layerRecord.waitData++;
}
- flushAvailableRecordsToStatsLocked(layerId, displayRefreshRate, renderRate, frameRateVote);
+ flushAvailableRecordsToStatsLocked(layerId, displayRefreshRate, renderRate, frameRateVote,
+ gameMode);
}
static const constexpr int32_t kValidJankyReason = JankType::DisplayHAL |
@@ -801,6 +823,7 @@
// the first jank record is not dropped.
static const std::string kDefaultLayerName = "none";
+ static constexpr int32_t kDefaultGameMode = TimeStatsHelper::GameModeUnsupported;
const int32_t refreshRateBucket =
clampToNearestBucket(info.refreshRate, REFRESH_RATE_BUCKET_WIDTH);
@@ -817,13 +840,14 @@
updateJankPayload<TimeStatsHelper::TimelineStats>(timelineStats, info.reasons);
- TimeStatsHelper::LayerStatsKey layerKey = {info.uid, info.layerName};
+ TimeStatsHelper::LayerStatsKey layerKey = {info.uid, info.layerName, info.gameMode};
if (!timelineStats.stats.count(layerKey)) {
- layerKey = {info.uid, kDefaultLayerName};
+ layerKey = {info.uid, kDefaultLayerName, kDefaultGameMode};
timelineStats.stats[layerKey].displayRefreshRateBucket = refreshRateBucket;
timelineStats.stats[layerKey].renderRateBucket = renderRateBucket;
timelineStats.stats[layerKey].uid = info.uid;
- timelineStats.stats[layerKey].layerName = kDefaultLayerName;
+ timelineStats.stats[layerKey].layerName = kDefaultGameMode;
+ timelineStats.stats[layerKey].gameMode = info.gameMode;
}
TimeStatsHelper::TimeStatsLayer& timeStatsLayer = timelineStats.stats[layerKey];
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 5b0f5bd..dd48950 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -87,7 +87,7 @@
const std::shared_ptr<FenceTime>& readyFence) = 0;
virtual void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName,
- uid_t uid, nsecs_t postTime) = 0;
+ uid_t uid, nsecs_t postTime, int32_t gameMode) = 0;
virtual void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) = 0;
// Reasons why latching a particular buffer may be skipped
enum class LatchSkipReason {
@@ -109,11 +109,11 @@
// rendering path, as they flush prior fences if those fences have fired.
virtual void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
Fps displayRefreshRate, std::optional<Fps> renderRate,
- SetFrameRateVote frameRateVote) = 0;
+ SetFrameRateVote frameRateVote, int32_t gameMode) = 0;
virtual void setPresentFence(int32_t layerId, uint64_t frameNumber,
const std::shared_ptr<FenceTime>& presentFence,
Fps displayRefreshRate, std::optional<Fps> renderRate,
- SetFrameRateVote frameRateVote) = 0;
+ SetFrameRateVote frameRateVote, int32_t gameMode) = 0;
// Increments janky frames, blamed to the provided {refreshRate, renderRate, uid, layerName}
// key, with JankMetadata as supplementary reasons for the jank. Because FrameTimeline is the
@@ -131,6 +131,7 @@
std::optional<Fps> renderRate;
uid_t uid = 0;
std::string layerName;
+ int32_t gameMode = 0;
int32_t reasons = 0;
nsecs_t displayDeadlineDelta = 0;
nsecs_t displayPresentJitter = 0;
@@ -141,8 +142,8 @@
((renderRate == std::nullopt && o.renderRate == std::nullopt) ||
(renderRate != std::nullopt && o.renderRate != std::nullopt &&
Fps::EqualsInBuckets{}(*renderRate, *o.renderRate))) &&
- uid == o.uid && layerName == o.layerName && reasons == o.reasons &&
- displayDeadlineDelta == o.displayDeadlineDelta &&
+ uid == o.uid && layerName == o.layerName && gameMode == o.gameMode &&
+ reasons == o.reasons && displayDeadlineDelta == o.displayDeadlineDelta &&
displayPresentJitter == o.displayPresentJitter &&
appDeadlineDelta == o.appDeadlineDelta;
}
@@ -199,6 +200,7 @@
struct LayerRecord {
uid_t uid;
std::string layerName;
+ int32_t gameMode = 0;
// This is the index in timeRecords, at which the timestamps for that
// specific frame are still not fully received. This is not waiting for
// fences to signal, but rather waiting to receive those fences/timestamps.
@@ -251,7 +253,7 @@
const std::shared_ptr<FenceTime>& readyFence) override;
void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName, uid_t uid,
- nsecs_t postTime) override;
+ nsecs_t postTime, int32_t gameMode) override;
void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) override;
void incrementLatchSkipped(int32_t layerId, LatchSkipReason reason) override;
void incrementBadDesiredPresent(int32_t layerId) override;
@@ -261,10 +263,11 @@
const std::shared_ptr<FenceTime>& acquireFence) override;
void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
Fps displayRefreshRate, std::optional<Fps> renderRate,
- SetFrameRateVote frameRateVote) override;
+ SetFrameRateVote frameRateVote, int32_t gameMode) override;
void setPresentFence(int32_t layerId, uint64_t frameNumber,
const std::shared_ptr<FenceTime>& presentFence, Fps displayRefreshRate,
- std::optional<Fps> renderRate, SetFrameRateVote frameRateVote) override;
+ std::optional<Fps> renderRate, SetFrameRateVote frameRateVote,
+ int32_t gameMode) override;
void incrementJankyFrames(const JankyFramesInfo& info) override;
// Clean up the layer record
@@ -286,10 +289,10 @@
bool recordReadyLocked(int32_t layerId, TimeRecord* timeRecord);
void flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate,
std::optional<Fps> renderRate,
- SetFrameRateVote frameRateVote);
+ SetFrameRateVote frameRateVote, int32_t gameMode);
void flushPowerTimeLocked();
void flushAvailableGlobalRecordsToStatsLocked();
- bool canAddNewAggregatedStats(uid_t uid, const std::string& layerName);
+ bool canAddNewAggregatedStats(uid_t uid, const std::string& layerName, int32_t gameMode);
void enable();
void disable();
diff --git a/services/surfaceflinger/TimeStats/timestatsatomsproto/timestats_atoms.proto b/services/surfaceflinger/TimeStats/timestatsatomsproto/timestats_atoms.proto
index 133a541..e45757d 100644
--- a/services/surfaceflinger/TimeStats/timestatsatomsproto/timestats_atoms.proto
+++ b/services/surfaceflinger/TimeStats/timestatsatomsproto/timestats_atoms.proto
@@ -166,6 +166,23 @@
// This is intended to be used as a dimension in collecting per-render rate
// jank statistics.
optional int32 render_rate_bucket = 23;
+
+ enum GameMode {
+ GAME_MODE_UNSPECIFIED = 0;
+ GAME_MODE_UNSUPPORTED = 1;
+ GAME_MODE_STANDARD = 2;
+ GAME_MODE_PERFORMANCE = 3;
+ GAME_MODE_BATTERY = 4;
+ }
+
+ // Game mode that the layer was running at. Used to track user engagement
+ // in different modes. The modes are defined in GameManager.java
+ // Game modes are used only for integrating with GameManager. All non-game
+ // layers will have this field set to UNSUPPORTED.
+ // Introduced in Android 12
+ // This is intended to be used as a dimension in collecting per-game mode
+ // fps and frame related metrics.
+ optional GameMode game_mode = 26;
// The layer for this set of metrics
// In many scenarios the package name is included in the layer name, e.g.,
// layers created by Window Manager. But this is not a guarantee - in the
@@ -271,7 +288,7 @@
// Introduced in Android 12.
optional FrameTimingHistogram app_deadline_misses = 25;
- // Next ID: 26
+ // Next ID: 27
}
/**
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
index a7e7db2..ffb2f09 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
@@ -122,6 +122,20 @@
return result;
}
+std::string TimeStatsHelper::TimeStatsLayer::toString(int32_t gameMode) const {
+ switch (gameMode) {
+ case TimeStatsHelper::GameModeUnsupported:
+ return "GameModeUnsupported";
+ case TimeStatsHelper::GameModeStandard:
+ return "GameModeStandard";
+ case TimeStatsHelper::GameModePerformance:
+ return "GameModePerformance";
+ case TimeStatsHelper::GameModeBattery:
+ return "GameModeBattery";
+ default:
+ return "GameModeUnspecified";
+ }
+}
std::string TimeStatsHelper::TimeStatsLayer::toString() const {
std::string result = "\n";
StringAppendF(&result, "displayRefreshRate = %d fps\n", displayRefreshRateBucket);
@@ -129,6 +143,7 @@
StringAppendF(&result, "uid = %d\n", uid);
StringAppendF(&result, "layerName = %s\n", layerName.c_str());
StringAppendF(&result, "packageName = %s\n", packageName.c_str());
+ StringAppendF(&result, "gameMode = %s\n", toString(gameMode).c_str());
StringAppendF(&result, "totalFrames = %d\n", totalFrames);
StringAppendF(&result, "droppedFrames = %d\n", droppedFrames);
StringAppendF(&result, "lateAcquireFrames = %d\n", lateAcquireFrames);
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
index 2b37ffe..2afff8d 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
+++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
@@ -77,6 +77,18 @@
std::string toString() const;
};
+ /**
+ * GameMode of the layer. GameModes are set by SysUI through WMShell.
+ * Actual game mode definitions are managed by GameManager.java
+ * The values defined here should always be in sync with the ones in GameManager.
+ */
+ enum GameMode {
+ GameModeUnsupported = 0,
+ GameModeStandard = 1,
+ GameModePerformance = 2,
+ GameModeBattery = 3,
+ };
+
class TimeStatsLayer {
public:
uid_t uid;
@@ -84,6 +96,7 @@
std::string packageName;
int32_t displayRefreshRateBucket = 0;
int32_t renderRateBucket = 0;
+ int32_t gameMode = 0;
int32_t totalFrames = 0;
int32_t droppedFrames = 0;
int32_t lateAcquireFrames = 0;
@@ -93,6 +106,7 @@
std::unordered_map<std::string, Histogram> deltas;
std::string toString() const;
+ std::string toString(int32_t gameMode) const;
SFTimeStatsLayerProto toProto() const;
};
@@ -123,24 +137,19 @@
struct LayerStatsKey {
uid_t uid = 0;
std::string layerName;
+ int32_t gameMode = 0;
struct Hasher {
size_t operator()(const LayerStatsKey& key) const {
- size_t result = std::hash<uid_t>{}(key.uid);
- return HashCombine(result, std::hash<std::string>{}(key.layerName));
+ size_t uidHash = std::hash<uid_t>{}(key.uid);
+ size_t layerNameHash = std::hash<std::string>{}(key.layerName);
+ size_t gameModeHash = std::hash<int32_t>{}(key.gameMode);
+ return HashCombine(uidHash, HashCombine(layerNameHash, gameModeHash));
}
};
bool operator==(const LayerStatsKey& o) const {
- return uid == o.uid && layerName == o.layerName;
- }
- };
-
- struct LayerStatsHasher {
- size_t operator()(const std::pair<uid_t, std::string>& p) const {
- // Normally this isn't a very good hash function due to symmetry reasons,
- // but these are distinct types so this should be good enough
- return std::hash<uid_t>{}(p.first) ^ std::hash<std::string>{}(p.second);
+ return uid == o.uid && layerName == o.layerName && gameMode == o.gameMode;
}
};
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 736ef30..b5086fa 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -69,7 +69,7 @@
"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 3042450..560f139 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -105,7 +105,9 @@
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 @@
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 @@
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 77a3e14..8d4a023 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 a3e8108..cc24323 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -41,9 +41,6 @@
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::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 @@
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());
+ constexpr auto kConnectionType = ui::DisplayConnectionType::Internal;
+ constexpr bool kIsPrimary = true;
- auto injector = FakeDisplayDeviceInjector(mFlinger, compositionDisplay,
- ui::DisplayConnectionType::Internal,
- DEFAULT_DISPLAY_HWC_DISPLAY_ID, true /* isPrimary */);
+ 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 d68fff6..6ce281d 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -263,40 +263,23 @@
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);
+ ceDisplayArgs.setId(DISPLAY_ID::get())
+ .setPixels({WIDTH, HEIGHT})
+ .setPowerAdvisor(&test->mPowerAdvisor);
- GpuVirtualDisplayId desiredDisplayId = GpuVirtualDisplayId::tryCast(DISPLAY_ID::get())
- .value_or(GpuVirtualDisplayId(0));
-
- ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
- .WillByDefault(Return(desiredDisplayId));
-
- 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 @@
::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 @@
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 @@
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 @@
}
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 dec0ff5..010c675 100644
--- a/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp
@@ -76,11 +76,9 @@
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 @@
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 @@
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/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index c6a4115..71a567a 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -175,6 +175,7 @@
static constexpr int32_t sInputEventId = 5;
static constexpr int32_t sLayerIdOne = 1;
static constexpr int32_t sLayerIdTwo = 2;
+static constexpr int32_t sGameMode = 0;
TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
@@ -194,11 +195,11 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
}
@@ -207,7 +208,7 @@
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
}
@@ -217,7 +218,7 @@
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
}
@@ -227,7 +228,7 @@
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
@@ -239,7 +240,7 @@
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
}
@@ -250,7 +251,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
// Set up the display frame
mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
@@ -278,11 +279,11 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdTwo, sLayerNameTwo,
- sLayerNameTwo, /*isBuffer*/ true);
+ sLayerNameTwo, /*isBuffer*/ true, sGameMode);
mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
@@ -325,7 +326,7 @@
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
sPidOne, sUidOne, sLayerIdOne,
sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame);
@@ -347,7 +348,7 @@
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame);
@@ -361,20 +362,20 @@
}
TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
- auto surfaceFrame =
- mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
- "acquireFenceAfterQueue",
- "acquireFenceAfterQueue", /*isBuffer*/ true);
+ auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
+ "acquireFenceAfterQueue",
+ "acquireFenceAfterQueue",
+ /*isBuffer*/ true, sGameMode);
surfaceFrame->setActualQueueTime(123);
surfaceFrame->setAcquireFenceTime(456);
EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
}
TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
- auto surfaceFrame =
- mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
- "acquireFenceAfterQueue",
- "acquireFenceAfterQueue", /*isBuffer*/ true);
+ auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
+ "acquireFenceAfterQueue",
+ "acquireFenceAfterQueue",
+ /*isBuffer*/ true, sGameMode);
surfaceFrame->setActualQueueTime(456);
surfaceFrame->setAcquireFenceTime(123);
EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
@@ -389,7 +390,7 @@
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -406,7 +407,7 @@
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -423,7 +424,7 @@
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -443,7 +444,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setAcquireFenceTime(20);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -471,7 +472,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setAcquireFenceTime(20);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -486,7 +487,7 @@
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(
TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne,
+ sLayerNameOne, sGameMode,
JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
0}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
@@ -496,7 +497,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setAcquireFenceTime(20);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -511,7 +512,7 @@
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(
TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne,
+ sLayerNameOne, sGameMode,
JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
0}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
@@ -522,7 +523,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setAcquireFenceTime(20);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -537,8 +538,8 @@
Fps refreshRate = Fps::fromPeriodNsecs(30);
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne, JankType::DisplayHAL,
- -4, 0, 0}));
+ sLayerNameOne, sGameMode,
+ JankType::DisplayHAL, -4, 0, 0}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
@@ -547,7 +548,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
surfaceFrame1->setAcquireFenceTime(20);
@@ -561,7 +562,7 @@
Fps refreshRate = Fps(11.0);
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne,
+ sLayerNameOne, sGameMode,
JankType::AppDeadlineMissed, -4, 0,
25}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
@@ -571,7 +572,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(45);
mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
@@ -587,7 +588,7 @@
Fps refreshRate = Fps::fromPeriodNsecs(32);
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne,
+ sLayerNameOne, sGameMode,
JankType::SurfaceFlingerScheduling,
-4, 0, -10}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
@@ -597,7 +598,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(50);
mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
@@ -613,7 +614,7 @@
Fps refreshRate = Fps::fromPeriodNsecs(16);
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne,
+ sLayerNameOne, sGameMode,
JankType::PredictionError, -4, 5,
0}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
@@ -623,7 +624,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(40);
mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
@@ -639,7 +640,7 @@
Fps refreshRate = Fps::fromPeriodNsecs(32);
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne,
+ sLayerNameOne, sGameMode,
JankType::BufferStuffing, -4, 0,
0}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
@@ -649,7 +650,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(40);
mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
@@ -666,9 +667,10 @@
Fps refreshRate = Fps::fromPeriodNsecs(11);
Fps renderRate = Fps::fromPeriodNsecs(30);
EXPECT_CALL(*mTimeStats,
- incrementJankyFrames(
- TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
- JankType::AppDeadlineMissed, -4, 0, 25}));
+ incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
+ sLayerNameOne, sGameMode,
+ JankType::AppDeadlineMissed, -4, 0,
+ 25}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
@@ -676,7 +678,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(45);
mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
@@ -696,6 +698,7 @@
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(
TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
+ sGameMode,
JankType::Unknown | JankType::AppDeadlineMissed,
0, 0, 25}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
@@ -705,7 +708,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(45);
// Trigger a prediction expiry
flushTokens();
@@ -742,7 +745,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
// Set up the display frame
mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
@@ -769,7 +772,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
// Set up the display frame
mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
@@ -815,7 +818,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
// Set up the display frame
mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
@@ -1128,11 +1131,11 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setActualQueueTime(10);
surfaceFrame1->setDropTime(15);
@@ -1288,7 +1291,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setActualQueueTime(appEndTime);
surfaceFrame1->setAcquireFenceTime(appEndTime);
@@ -1364,7 +1367,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
@@ -1433,7 +1436,7 @@
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame);
@@ -1649,7 +1652,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(16);
mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -1669,7 +1672,7 @@
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame2->setAcquireFenceTime(36);
mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -1701,8 +1704,8 @@
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(
TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
- sLayerNameOne, JankType::PredictionError, -3, 5,
- 0}));
+ sLayerNameOne, sGameMode,
+ JankType::PredictionError, -3, 5, 0}));
addEmptyDisplayFrame();
@@ -1729,7 +1732,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(16);
mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -1749,7 +1752,7 @@
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame2->setAcquireFenceTime(36);
mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -1781,8 +1784,8 @@
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(
TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
- sLayerNameOne, JankType::PredictionError, -3, 5,
- 0}));
+ sLayerNameOne, sGameMode,
+ JankType::PredictionError, -3, 5, 0}));
addEmptyDisplayFrame();
@@ -1808,7 +1811,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(40);
mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -1852,7 +1855,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(26);
mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -1872,7 +1875,7 @@
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame2->setAcquireFenceTime(40);
mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -1927,7 +1930,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(50);
mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -1947,7 +1950,7 @@
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame2->setAcquireFenceTime(84);
mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
@@ -2005,7 +2008,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame1->setAcquireFenceTime(50);
mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
@@ -2025,7 +2028,7 @@
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
- sLayerNameOne, /*isBuffer*/ true);
+ sLayerNameOne, /*isBuffer*/ true, sGameMode);
surfaceFrame2->setAcquireFenceTime(80);
mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
// Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
@@ -2081,7 +2084,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
@@ -2097,7 +2100,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
@@ -2107,7 +2110,7 @@
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame2);
@@ -2123,7 +2126,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
@@ -2133,7 +2136,7 @@
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame2);
@@ -2149,7 +2152,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
@@ -2159,7 +2162,7 @@
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame2);
@@ -2178,7 +2181,7 @@
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
@@ -2188,7 +2191,7 @@
auto surfaceFrame2 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame2);
@@ -2198,7 +2201,7 @@
auto surfaceFrame3 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame3);
@@ -2208,7 +2211,7 @@
auto surfaceFrame4 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame4);
@@ -2218,7 +2221,7 @@
auto surfaceFrame5 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne,
- /*isBuffer*/ true);
+ /*isBuffer*/ true, sGameMode);
auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
// Dropped frames will be excluded from fps computation
surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
diff --git a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
index cbf8cc2..655baf8 100644
--- a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
@@ -58,28 +58,26 @@
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 @@
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 @@
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 @@
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 9c6ad06..fd3e564 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
@@ -60,7 +60,6 @@
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 @@
void commitTransaction(Layer* layer);
TestableSurfaceFlinger mFlinger;
- Hwc2::mock::Composer* mComposer = nullptr;
sp<Client> mClient;
sp<Layer> mParent;
@@ -83,7 +81,7 @@
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 @@
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 c088ddc..46ef750 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -118,14 +118,12 @@
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 @@
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 @@
/*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
similarity index 62%
rename from services/surfaceflinger/tests/unittests/SurfaceFlinger_OnHotplugReceivedTest.cpp
rename to services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp
index 42f4cf3..bd89397 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 @@
// 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 @@
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 @@
// --------------------------------------------------------------------
// 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 @@
// 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 @@
}
} // 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 a551248..d78f36c 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 @@
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 @@
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 @@
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 @@
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 @@
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/TimeStatsTest.cpp b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
index 3e4e130..317cdf1 100644
--- a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
@@ -54,6 +54,9 @@
using testing::UnorderedElementsAre;
using PowerMode = hardware::graphics::composer::V2_4::IComposerClient::PowerMode;
+using SurfaceflingerStatsLayerInfo = android::surfaceflinger::SurfaceflingerStatsLayerInfo;
+using SurfaceflingerStatsLayerInfoWrapper =
+ android::surfaceflinger::SurfaceflingerStatsLayerInfoWrapper;
// clang-format off
#define FMT_PROTO true
@@ -71,6 +74,7 @@
const constexpr Fps kRefreshRate0 = Fps(static_cast<float>(REFRESH_RATE_0));
const constexpr Fps kRenderRate0 = Fps(static_cast<float>(RENDER_RATE_0));
+static constexpr int32_t kGameMode = TimeStatsHelper::GameModeUnsupported;
enum InputCommand : int32_t {
ENABLE = 0,
@@ -143,15 +147,16 @@
std::string inputCommand(InputCommand cmd, bool useProto);
void setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts,
- TimeStats::SetFrameRateVote frameRateVote);
+ TimeStats::SetFrameRateVote frameRateVote, int32_t gameMode);
int32_t genRandomInt32(int32_t begin, int32_t end);
template <size_t N>
void insertTimeRecord(const TimeStamp (&sequence)[N], int32_t id, uint64_t frameNumber,
- nsecs_t ts, TimeStats::SetFrameRateVote frameRateVote = {}) {
+ nsecs_t ts, TimeStats::SetFrameRateVote frameRateVote = {},
+ int32_t gameMode = kGameMode) {
for (size_t i = 0; i < N; i++, ts += 1000000) {
- setTimeStamp(sequence[i], id, frameNumber, ts, frameRateVote);
+ setTimeStamp(sequence[i], id, frameNumber, ts, frameRateVote, gameMode);
}
}
@@ -200,11 +205,11 @@
}
void TimeStatsTest::setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts,
- TimeStats::SetFrameRateVote frameRateVote) {
+ TimeStats::SetFrameRateVote frameRateVote, int32_t gameMode) {
switch (type) {
case TimeStamp::POST:
- ASSERT_NO_FATAL_FAILURE(
- mTimeStats->setPostTime(id, frameNumber, genLayerName(id), UID_0, ts));
+ ASSERT_NO_FATAL_FAILURE(mTimeStats->setPostTime(id, frameNumber, genLayerName(id),
+ UID_0, ts, gameMode));
break;
case TimeStamp::ACQUIRE:
ASSERT_NO_FATAL_FAILURE(mTimeStats->setAcquireTime(id, frameNumber, ts));
@@ -221,12 +226,14 @@
break;
case TimeStamp::PRESENT:
ASSERT_NO_FATAL_FAILURE(mTimeStats->setPresentTime(id, frameNumber, ts, kRefreshRate0,
- kRenderRate0, frameRateVote));
+ kRenderRate0, frameRateVote,
+ gameMode));
break;
case TimeStamp::PRESENT_FENCE:
- ASSERT_NO_FATAL_FAILURE(
- mTimeStats->setPresentFence(id, frameNumber, std::make_shared<FenceTime>(ts),
- kRefreshRate0, kRenderRate0, frameRateVote));
+ ASSERT_NO_FATAL_FAILURE(mTimeStats->setPresentFence(id, frameNumber,
+ std::make_shared<FenceTime>(ts),
+ kRefreshRate0, kRenderRate0,
+ frameRateVote, gameMode));
break;
default:
ALOGD("Invalid timestamp type");
@@ -319,22 +326,24 @@
insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerCpuDeadlineMissed, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerGpuDeadlineMissed, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::DisplayHAL, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::AppDeadlineMissed, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerScheduling, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::PredictionError, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::AppDeadlineMissed | JankType::BufferStuffing, 1, 2,
+ kGameMode, JankType::SurfaceFlingerCpuDeadlineMissed, 1, 2,
3});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::None, 1, 2, 3});
+ kGameMode, JankType::SurfaceFlingerGpuDeadlineMissed, 1, 2,
+ 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::DisplayHAL, 1, 2, 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::AppDeadlineMissed, 1, 2, 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::SurfaceFlingerScheduling, 1, 2, 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::PredictionError, 1, 2, 3});
+ mTimeStats->incrementJankyFrames(
+ {kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), kGameMode,
+ JankType::AppDeadlineMissed | JankType::BufferStuffing, 1, 2, 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::None, 1, 2, 3});
const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
std::string expectedResult =
@@ -872,22 +881,24 @@
std::make_shared<FenceTime>(std::chrono::nanoseconds(1ms).count()));
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerCpuDeadlineMissed, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerGpuDeadlineMissed, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::DisplayHAL, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::AppDeadlineMissed, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerScheduling, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::PredictionError, 1, 2, 3});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::AppDeadlineMissed | JankType::BufferStuffing, 1, 2,
+ kGameMode, JankType::SurfaceFlingerCpuDeadlineMissed, 1, 2,
3});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::None, 1, 2, 3});
+ kGameMode, JankType::SurfaceFlingerGpuDeadlineMissed, 1, 2,
+ 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::DisplayHAL, 1, 2, 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::AppDeadlineMissed, 1, 2, 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::SurfaceFlingerScheduling, 1, 2, 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::PredictionError, 1, 2, 3});
+ mTimeStats->incrementJankyFrames(
+ {kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), kGameMode,
+ JankType::AppDeadlineMissed | JankType::BufferStuffing, 1, 2, 3});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::None, 1, 2, 3});
EXPECT_TRUE(inputCommand(InputCommand::CLEAR, FMT_STRING).empty());
@@ -1039,34 +1050,36 @@
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000));
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerCpuDeadlineMissed,
+ kGameMode, JankType::SurfaceFlingerCpuDeadlineMissed,
DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER,
APP_DEADLINE_DELTA});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerGpuDeadlineMissed,
+ kGameMode, JankType::SurfaceFlingerGpuDeadlineMissed,
DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER,
APP_DEADLINE_DELTA});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::DisplayHAL, DISPLAY_DEADLINE_DELTA,
+ kGameMode, JankType::DisplayHAL, DISPLAY_DEADLINE_DELTA,
DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::AppDeadlineMissed, DISPLAY_DEADLINE_DELTA,
- DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerScheduling, DISPLAY_DEADLINE_DELTA,
- DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::PredictionError, DISPLAY_DEADLINE_DELTA,
- DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::AppDeadlineMissed | JankType::BufferStuffing,
+ kGameMode, JankType::AppDeadlineMissed,
DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER,
APP_DEADLINE_DELTA});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::BufferStuffing, DISPLAY_DEADLINE_DELTA,
+ kGameMode, JankType::SurfaceFlingerScheduling,
+ DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER,
+ APP_DEADLINE_DELTA});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::PredictionError, DISPLAY_DEADLINE_DELTA,
+ DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA});
+ mTimeStats->incrementJankyFrames(
+ {kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), kGameMode,
+ JankType::AppDeadlineMissed | JankType::BufferStuffing, DISPLAY_DEADLINE_DELTA,
+ DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA});
+ mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::BufferStuffing, DISPLAY_DEADLINE_DELTA,
DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::None, DISPLAY_DEADLINE_DELTA,
+ kGameMode, JankType::None, DISPLAY_DEADLINE_DELTA,
DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA});
std::string pulledData;
@@ -1157,7 +1170,8 @@
constexpr nsecs_t APP_DEADLINE_DELTA_3MS = 3'000'000;
EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
- insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
+ insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000, {},
+ TimeStatsHelper::GameModeStandard);
for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) {
mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire);
}
@@ -1170,43 +1184,50 @@
TimeStats::SetFrameRateVote::FrameRateCompatibility::ExactOrMultiple,
.seamlessness = TimeStats::SetFrameRateVote::Seamlessness::NotRequired,
};
- insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000, frameRate60);
+ insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000, frameRate60,
+ TimeStatsHelper::GameModeStandard);
+ mTimeStats->incrementJankyFrames(
+ {kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ TimeStatsHelper::GameModeStandard, JankType::SurfaceFlingerCpuDeadlineMissed,
+ DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS});
+ mTimeStats->incrementJankyFrames(
+ {kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ TimeStatsHelper::GameModeStandard, JankType::SurfaceFlingerGpuDeadlineMissed,
+ DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerCpuDeadlineMissed,
+ TimeStatsHelper::GameModeStandard, JankType::DisplayHAL,
DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER,
APP_DEADLINE_DELTA_3MS});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::SurfaceFlingerGpuDeadlineMissed,
- DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER,
- APP_DEADLINE_DELTA_3MS});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::DisplayHAL, DISPLAY_DEADLINE_DELTA,
- DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS});
- mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ TimeStatsHelper::GameModeStandard,
JankType::AppDeadlineMissed, DISPLAY_DEADLINE_DELTA,
DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ TimeStatsHelper::GameModeStandard,
JankType::SurfaceFlingerScheduling, DISPLAY_DEADLINE_DELTA,
DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_2MS});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::PredictionError, DISPLAY_DEADLINE_DELTA,
- DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_2MS});
+ TimeStatsHelper::GameModeStandard, JankType::PredictionError,
+ DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER,
+ APP_DEADLINE_DELTA_2MS});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
+ TimeStatsHelper::GameModeStandard,
JankType::AppDeadlineMissed | JankType::BufferStuffing,
DISPLAY_DEADLINE_DELTA, APP_DEADLINE_DELTA_2MS,
APP_DEADLINE_DELTA_2MS});
mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0),
- JankType::None, DISPLAY_DEADLINE_DELTA,
- DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS});
+ TimeStatsHelper::GameModeStandard, JankType::None,
+ DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER,
+ APP_DEADLINE_DELTA_3MS});
std::string pulledData;
EXPECT_TRUE(mTimeStats->onPullAtom(10063 /*SURFACEFLINGER_STATS_LAYER_INFO*/, &pulledData));
- android::surfaceflinger::SurfaceflingerStatsLayerInfoWrapper atomList;
+ SurfaceflingerStatsLayerInfoWrapper atomList;
ASSERT_TRUE(atomList.ParseFromString(pulledData));
ASSERT_EQ(atomList.atom_size(), 1);
- const android::surfaceflinger::SurfaceflingerStatsLayerInfo& atom = atomList.atom(0);
+ const SurfaceflingerStatsLayerInfo& atom = atomList.atom(0);
EXPECT_EQ(atom.layer_name(), genLayerName(LAYER_ID_0));
EXPECT_EQ(atom.total_frames(), 1);
@@ -1236,6 +1257,7 @@
(int)frameRate60.frameRateCompatibility);
EXPECT_EQ((int)atom.set_frame_rate_vote().seamlessness(), (int)frameRate60.seamlessness);
EXPECT_THAT(atom.app_deadline_misses(), HistogramEq(buildExpectedHistogram({3, 2}, {4, 3})));
+ EXPECT_EQ(atom.game_mode(), SurfaceflingerStatsLayerInfo::GAME_MODE_STANDARD);
SFTimeStatsGlobalProto globalProto;
ASSERT_TRUE(globalProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO)));
@@ -1268,6 +1290,92 @@
EXPECT_THAT(result, Not(HasSubstr(expectedMissing)));
}
+TEST_F(TimeStatsTest, layerStatsCallback_multipleGameModes) {
+ constexpr size_t LATE_ACQUIRE_FRAMES = 2;
+ constexpr size_t BAD_DESIRED_PRESENT_FRAMES = 3;
+ EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
+
+ insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000, {},
+ TimeStatsHelper::GameModeStandard);
+ for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) {
+ mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire);
+ }
+ for (size_t i = 0; i < BAD_DESIRED_PRESENT_FRAMES; i++) {
+ mTimeStats->incrementBadDesiredPresent(LAYER_ID_0);
+ }
+ insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000, {},
+ TimeStatsHelper::GameModeStandard);
+
+ insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 3000000, {},
+ TimeStatsHelper::GameModePerformance);
+
+ insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 4000000, {}, TimeStatsHelper::GameModeBattery);
+ insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 5, 4000000, {}, TimeStatsHelper::GameModeBattery);
+
+ std::string pulledData;
+ EXPECT_TRUE(mTimeStats->onPullAtom(10063 /*SURFACEFLINGER_STATS_LAYER_INFO*/, &pulledData));
+
+ SurfaceflingerStatsLayerInfoWrapper atomList;
+ ASSERT_TRUE(atomList.ParseFromString(pulledData));
+ // The first time record is never uploaded to stats.
+ ASSERT_EQ(atomList.atom_size(), 3);
+ // Layers are ordered based on the hash in LayerStatsKey. For this test, the order happens to
+ // be: 0 - Battery 1 - Performance 2 - Standard
+ const SurfaceflingerStatsLayerInfo& atom0 = atomList.atom(0);
+
+ EXPECT_EQ(atom0.layer_name(), genLayerName(LAYER_ID_0));
+ EXPECT_EQ(atom0.total_frames(), 2);
+ EXPECT_EQ(atom0.dropped_frames(), 0);
+ EXPECT_THAT(atom0.present_to_present(), HistogramEq(buildExpectedHistogram({0, 1}, {1, 1})));
+ EXPECT_THAT(atom0.post_to_present(), HistogramEq(buildExpectedHistogram({4}, {2})));
+ EXPECT_THAT(atom0.acquire_to_present(), HistogramEq(buildExpectedHistogram({3}, {2})));
+ EXPECT_THAT(atom0.latch_to_present(), HistogramEq(buildExpectedHistogram({2}, {2})));
+ EXPECT_THAT(atom0.desired_to_present(), HistogramEq(buildExpectedHistogram({1}, {2})));
+ EXPECT_THAT(atom0.post_to_acquire(), HistogramEq(buildExpectedHistogram({1}, {2})));
+ EXPECT_EQ(atom0.late_acquire_frames(), 0);
+ EXPECT_EQ(atom0.bad_desired_present_frames(), 0);
+ EXPECT_EQ(atom0.uid(), UID_0);
+ EXPECT_EQ(atom0.display_refresh_rate_bucket(), REFRESH_RATE_BUCKET_0);
+ EXPECT_EQ(atom0.render_rate_bucket(), RENDER_RATE_BUCKET_0);
+ EXPECT_EQ(atom0.game_mode(), SurfaceflingerStatsLayerInfo::GAME_MODE_BATTERY);
+
+ const SurfaceflingerStatsLayerInfo& atom1 = atomList.atom(1);
+
+ EXPECT_EQ(atom1.layer_name(), genLayerName(LAYER_ID_0));
+ EXPECT_EQ(atom1.total_frames(), 1);
+ EXPECT_EQ(atom1.dropped_frames(), 0);
+ EXPECT_THAT(atom1.present_to_present(), HistogramEq(buildExpectedHistogram({1}, {1})));
+ EXPECT_THAT(atom1.post_to_present(), HistogramEq(buildExpectedHistogram({4}, {1})));
+ EXPECT_THAT(atom1.acquire_to_present(), HistogramEq(buildExpectedHistogram({3}, {1})));
+ EXPECT_THAT(atom1.latch_to_present(), HistogramEq(buildExpectedHistogram({2}, {1})));
+ EXPECT_THAT(atom1.desired_to_present(), HistogramEq(buildExpectedHistogram({1}, {1})));
+ EXPECT_THAT(atom1.post_to_acquire(), HistogramEq(buildExpectedHistogram({1}, {1})));
+ EXPECT_EQ(atom1.late_acquire_frames(), 0);
+ EXPECT_EQ(atom1.bad_desired_present_frames(), 0);
+ EXPECT_EQ(atom1.uid(), UID_0);
+ EXPECT_EQ(atom1.display_refresh_rate_bucket(), REFRESH_RATE_BUCKET_0);
+ EXPECT_EQ(atom1.render_rate_bucket(), RENDER_RATE_BUCKET_0);
+ EXPECT_EQ(atom1.game_mode(), SurfaceflingerStatsLayerInfo::GAME_MODE_PERFORMANCE);
+
+ const SurfaceflingerStatsLayerInfo& atom2 = atomList.atom(2);
+
+ EXPECT_EQ(atom2.layer_name(), genLayerName(LAYER_ID_0));
+ EXPECT_EQ(atom2.total_frames(), 1);
+ EXPECT_EQ(atom2.dropped_frames(), 0);
+ EXPECT_THAT(atom2.present_to_present(), HistogramEq(buildExpectedHistogram({1}, {1})));
+ EXPECT_THAT(atom2.post_to_present(), HistogramEq(buildExpectedHistogram({4}, {1})));
+ EXPECT_THAT(atom2.acquire_to_present(), HistogramEq(buildExpectedHistogram({3}, {1})));
+ EXPECT_THAT(atom2.latch_to_present(), HistogramEq(buildExpectedHistogram({2}, {1})));
+ EXPECT_THAT(atom2.desired_to_present(), HistogramEq(buildExpectedHistogram({1}, {1})));
+ EXPECT_THAT(atom2.post_to_acquire(), HistogramEq(buildExpectedHistogram({1}, {1})));
+ EXPECT_EQ(atom2.late_acquire_frames(), LATE_ACQUIRE_FRAMES);
+ EXPECT_EQ(atom2.bad_desired_present_frames(), BAD_DESIRED_PRESENT_FRAMES);
+ EXPECT_EQ(atom2.uid(), UID_0);
+ EXPECT_EQ(atom2.display_refresh_rate_bucket(), REFRESH_RATE_BUCKET_0);
+ EXPECT_EQ(atom2.render_rate_bucket(), RENDER_RATE_BUCKET_0);
+ EXPECT_EQ(atom2.game_mode(), SurfaceflingerStatsLayerInfo::GAME_MODE_STANDARD);
+}
+
TEST_F(TimeStatsTest, layerStatsCallback_pullsMultipleLayers) {
EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
@@ -1279,7 +1387,7 @@
std::string pulledData;
EXPECT_TRUE(mTimeStats->onPullAtom(10063 /*SURFACEFLINGER_STATS_LAYER_INFO*/, &pulledData));
- android::surfaceflinger::SurfaceflingerStatsLayerInfoWrapper atomList;
+ SurfaceflingerStatsLayerInfoWrapper atomList;
ASSERT_TRUE(atomList.ParseFromString(pulledData));
ASSERT_EQ(atomList.atom_size(), 2);
std::vector<std::string> actualLayerNames = {atomList.atom(0).layer_name(),
@@ -1304,10 +1412,10 @@
std::string pulledData;
EXPECT_TRUE(mTimeStats->onPullAtom(10063 /*SURFACEFLINGER_STATS_LAYER_INFO*/, &pulledData));
- android::surfaceflinger::SurfaceflingerStatsLayerInfoWrapper atomList;
+ SurfaceflingerStatsLayerInfoWrapper atomList;
ASSERT_TRUE(atomList.ParseFromString(pulledData));
ASSERT_EQ(atomList.atom_size(), 1);
- const android::surfaceflinger::SurfaceflingerStatsLayerInfo& atom = atomList.atom(0);
+ const SurfaceflingerStatsLayerInfo& atom = atomList.atom(0);
EXPECT_THAT(atom.present_to_present(), HistogramEq(buildExpectedHistogram({1, 2}, {2, 1})));
}
@@ -1323,10 +1431,10 @@
std::string pulledData;
EXPECT_TRUE(mTimeStats->onPullAtom(10063 /*SURFACEFLINGER_STATS_LAYER_INFO*/, &pulledData));
- android::surfaceflinger::SurfaceflingerStatsLayerInfoWrapper atomList;
+ SurfaceflingerStatsLayerInfoWrapper atomList;
ASSERT_TRUE(atomList.ParseFromString(pulledData));
ASSERT_EQ(atomList.atom_size(), 1);
- const android::surfaceflinger::SurfaceflingerStatsLayerInfo& atom = atomList.atom(0);
+ const SurfaceflingerStatsLayerInfo& atom = atomList.atom(0);
EXPECT_THAT(atom.present_to_present(), HistogramEq(buildExpectedHistogram({1}, {2})));
}
@@ -1343,7 +1451,7 @@
std::string pulledData;
EXPECT_TRUE(mTimeStats->onPullAtom(10063 /*SURFACEFLINGER_STATS_LAYER_INFO*/, &pulledData));
- android::surfaceflinger::SurfaceflingerStatsLayerInfoWrapper atomList;
+ SurfaceflingerStatsLayerInfoWrapper atomList;
ASSERT_TRUE(atomList.ParseFromString(pulledData));
ASSERT_EQ(atomList.atom_size(), 1);
EXPECT_EQ(atomList.atom(0).layer_name(), genLayerName(LAYER_ID_1));
@@ -1372,7 +1480,7 @@
TimeStamp type = static_cast<TimeStamp>(genRandomInt32(TIME_STAMP_BEGIN, TIME_STAMP_END));
const int32_t ts = genRandomInt32(1, 1000000000);
ALOGV("type[%d], layerId[%d], frameNumber[%d], ts[%d]", type, layerId, frameNumber, ts);
- setTimeStamp(type, layerId, frameNumber, ts, {});
+ setTimeStamp(type, layerId, frameNumber, ts, {}, kGameMode);
}
}
@@ -1383,8 +1491,8 @@
EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000);
- mTimeStats->incrementJankyFrames(
- {fps, std::nullopt, UID_0, genLayerName(LAYER_ID_0), JankType::None, 0, 0, 0});
+ mTimeStats->incrementJankyFrames({fps, std::nullopt, UID_0, genLayerName(LAYER_ID_0),
+ kGameMode, JankType::None, 0, 0, 0});
const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
std::string expectedResult = "displayRefreshRate = " + std::to_string(bucket) + " fps";
EXPECT_THAT(result, HasSubstr(expectedResult)) << "failed for " << fps;
diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
index 25001d3..546bc4a 100644
--- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
@@ -45,7 +45,7 @@
::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 @@
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 b7917aa..c1123cd 100644
--- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
@@ -45,7 +45,7 @@
::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 @@
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 1ba3c0f..cb3bd73 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -54,7 +54,8 @@
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 cfc37ea..0000000
--- 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
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
index 526a847..5aebd2f 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
@@ -41,18 +41,19 @@
MOCK_METHOD2(recordFrameDuration, void(nsecs_t, nsecs_t));
MOCK_METHOD2(recordRenderEngineDuration, void(nsecs_t, nsecs_t));
MOCK_METHOD2(recordRenderEngineDuration, void(nsecs_t, const std::shared_ptr<FenceTime>&));
- MOCK_METHOD5(setPostTime, void(int32_t, uint64_t, const std::string&, uid_t, nsecs_t));
+ MOCK_METHOD6(setPostTime, void(int32_t, uint64_t, const std::string&, uid_t, nsecs_t, int32_t));
MOCK_METHOD2(incrementLatchSkipped, void(int32_t layerId, LatchSkipReason reason));
MOCK_METHOD1(incrementBadDesiredPresent, void(int32_t layerId));
MOCK_METHOD3(setLatchTime, void(int32_t, uint64_t, nsecs_t));
MOCK_METHOD3(setDesiredTime, void(int32_t, uint64_t, nsecs_t));
MOCK_METHOD3(setAcquireTime, void(int32_t, uint64_t, nsecs_t));
MOCK_METHOD3(setAcquireFence, void(int32_t, uint64_t, const std::shared_ptr<FenceTime>&));
- MOCK_METHOD6(setPresentTime,
- void(int32_t, uint64_t, nsecs_t, Fps, std::optional<Fps>, SetFrameRateVote));
- MOCK_METHOD6(setPresentFence,
+ MOCK_METHOD7(setPresentTime,
+ void(int32_t, uint64_t, nsecs_t, Fps, std::optional<Fps>, SetFrameRateVote,
+ int32_t));
+ MOCK_METHOD7(setPresentFence,
void(int32_t, uint64_t, const std::shared_ptr<FenceTime>&, Fps, std::optional<Fps>,
- SetFrameRateVote));
+ SetFrameRateVote, int32_t));
MOCK_METHOD1(incrementJankyFrames, void(const JankyFramesInfo&));
MOCK_METHOD1(onDestroy, void(int32_t));
MOCK_METHOD2(removeTimeRecord, void(int32_t, uint64_t));