Merge "[SurfaceFlinger] Enable SurfaceInterceptorTest in presubmit."
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index df6404a..aae3931 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -326,7 +326,7 @@
if (presentFence->isValid()) {
mTimeStats.setPresentFence(layerName, mCurrentFrameNumber, presentFence);
mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
- } else {
+ } else if (mFlinger->getHwComposer().isConnected(HWC_DISPLAY_PRIMARY)) {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
const nsecs_t actualPresentTime =
@@ -710,8 +710,9 @@
mProducer->setMaxDequeuedBufferCount(2);
}
- const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
- updateTransformHint(hw);
+ if (const auto display = mFlinger->getDefaultDisplayDevice()) {
+ updateTransformHint(display);
+ }
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index a4a6554..f440d29 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -315,7 +315,6 @@
};
struct DisplayDeviceState {
- bool isValid() const { return type >= 0; }
bool isVirtual() const { return type >= DisplayDevice::DISPLAY_VIRTUAL; }
int32_t sequenceId = sNextSequenceId++;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index f626a59..9546c86 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -124,6 +124,12 @@
return mComposer->getMaxVirtualDisplayCount();
}
+Error Device::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
+ std::vector<uint8_t>* outData) const {
+ auto intError = mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData);
+ return static_cast<Error>(intError);
+}
+
Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
PixelFormat* format, Display** outDisplay)
{
@@ -460,11 +466,6 @@
return configs;
}
-Error Display::getIdentificationData(uint8_t* outPort, std::vector<uint8_t>* outData) const {
- auto intError = mComposer.getDisplayIdentificationData(mId, outPort, outData);
- return static_cast<Error>(intError);
-}
-
Error Display::getName(std::string* outName) const
{
auto intError = mComposer.getDisplayName(mId, outName);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 2cb6aea..eefab98 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -93,6 +93,9 @@
};
uint32_t getMaxVirtualDisplayCount() const;
+ Error getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
+ std::vector<uint8_t>* outData) const;
+
Error createVirtualDisplay(uint32_t width, uint32_t height,
android::ui::PixelFormat* format, Display** outDisplay);
void destroyDisplay(hwc2_display_t displayId);
@@ -224,8 +227,6 @@
// Doesn't call into the HWC2 device, so no errors are possible
std::vector<std::shared_ptr<const Config>> getConfigs() const;
- [[clang::warn_unused_result]] Error getIdentificationData(uint8_t* outPort,
- std::vector<uint8_t>* outData) const;
[[clang::warn_unused_result]] Error getName(std::string* outName) const;
[[clang::warn_unused_result]] Error getRequests(
DisplayRequest* outDisplayRequests,
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index cd0635a..4e98b88 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -54,6 +54,9 @@
#include "../Layer.h" // needed only for debugging
#include "../SurfaceFlinger.h"
+#define LOG_HWC_DISPLAY_ERROR(hwcDisplayId, msg) \
+ ALOGE("%s failed for HWC display %" PRIu64 ": %s", __FUNCTION__, hwcDisplayId, msg)
+
#define LOG_DISPLAY_ERROR(displayId, msg) \
ALOGE("%s failed for display %d: %s", __FUNCTION__, displayId, msg)
@@ -96,17 +99,11 @@
mHwcDevice->registerCallback(callback, sequenceId);
}
-bool HWComposer::getDisplayIdentificationData(hwc2_display_t displayId, uint8_t* outPort,
+bool HWComposer::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
DisplayIdentificationData* outData) const {
- HWC2::Display* display = mHwcDevice->getDisplayById(displayId);
- if (!display) {
- ALOGE("getDisplayIdentificationData: Attempted to access invalid display %" PRIu64,
- displayId);
- return false;
- }
- const auto error = display->getIdentificationData(outPort, outData);
+ const auto error = mHwcDevice->getDisplayIdentificationData(hwcDisplayId, outPort, outData);
if (error != HWC2::Error::None) {
- ALOGE("getDisplayIdentificationData failed for display %" PRIu64, displayId);
+ LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str());
return false;
}
return true;
@@ -147,65 +144,53 @@
}
}
-std::optional<DisplayId> HWComposer::onHotplug(hwc2_display_t displayId, int32_t displayType,
+std::optional<DisplayId> HWComposer::onHotplug(hwc2_display_t hwcDisplayId, int32_t displayType,
HWC2::Connection connection) {
if (displayType >= HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
ALOGE("Invalid display type of %d", displayType);
return {};
}
- ALOGV("hotplug: %" PRIu64 ", %s %s", displayId,
- displayType == DisplayDevice::DISPLAY_PRIMARY ? "primary" : "external",
- to_string(connection).c_str());
- mHwcDevice->onHotplug(displayId, connection);
+ ALOGV("hotplug: %" PRIu64 ", %s %s", hwcDisplayId,
+ displayType == DisplayDevice::DISPLAY_PRIMARY ? "primary" : "external",
+ to_string(connection).c_str());
+ mHwcDevice->onHotplug(hwcDisplayId, connection);
- std::optional<DisplayId> stableId;
+ std::optional<DisplayId> displayId;
uint8_t port;
DisplayIdentificationData data;
- if (getDisplayIdentificationData(displayId, &port, &data)) {
- stableId = generateDisplayId(port, data);
- ALOGE_IF(!stableId, "Failed to generate stable ID for display %" PRIu64, displayId);
+ if (getDisplayIdentificationData(hwcDisplayId, &port, &data)) {
+ displayId = generateDisplayId(port, data);
+ ALOGE_IF(!displayId, "Failed to generate stable ID for display %" PRIu64, hwcDisplayId);
}
// Disconnect is handled through HWComposer::disconnectDisplay via
// SurfaceFlinger's onHotplugReceived callback handling
if (connection == HWC2::Connection::Connected) {
- mDisplayData[displayType].hwcDisplay = mHwcDevice->getDisplayById(displayId);
- mHwcDisplaySlots[displayId] = displayType;
+ mDisplayData[displayType].hwcDisplay = mHwcDevice->getDisplayById(hwcDisplayId);
+ mHwcDisplaySlots[hwcDisplayId] = displayType;
}
- return stableId;
+ return displayId;
}
-bool HWComposer::onVsync(hwc2_display_t displayId, int64_t timestamp,
- int32_t* outDisplay) {
- auto display = mHwcDevice->getDisplayById(displayId);
- if (!display) {
- ALOGE("onVsync Failed to find display %" PRIu64, displayId);
- return false;
- }
- auto displayType = HWC2::DisplayType::Invalid;
- auto error = display->getType(&displayType);
- if (error != HWC2::Error::None) {
- ALOGE("onVsync: Failed to determine type of display %" PRIu64,
- display->getId());
+bool HWComposer::onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp, int32_t* outDisplayId) {
+ const auto it = mHwcDisplaySlots.find(hwcDisplayId);
+ if (it == mHwcDisplaySlots.end()) {
+ LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid display");
return false;
}
- if (displayType == HWC2::DisplayType::Virtual) {
- ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
- display->getId());
+ const int32_t displayId = it->second;
+ RETURN_IF_INVALID_DISPLAY(displayId, false);
+
+ const auto& displayData = mDisplayData[displayId];
+ if (displayData.isVirtual) {
+ LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
return false;
}
- if (mHwcDisplaySlots.count(display->getId()) == 0) {
- ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
- display->getId());
- return false;
- }
-
- int32_t disp = mHwcDisplaySlots[display->getId()];
{
Mutex::Autolock _l(mLock);
@@ -213,22 +198,22 @@
// with the same timestamp when turning the display off and on. This
// is a bug in the HWC implementation, but filter the extra events
// out here so they don't cause havoc downstream.
- if (timestamp == mLastHwVSync[disp]) {
+ if (timestamp == mLastHwVSync[displayId]) {
ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
timestamp);
return false;
}
- mLastHwVSync[disp] = timestamp;
+ mLastHwVSync[displayId] = timestamp;
}
- if (outDisplay) {
- *outDisplay = disp;
+ if (outDisplayId) {
+ *outDisplayId = displayId;
}
char tag[16];
- snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
- ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
+ snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", displayId);
+ ATRACE_INT(tag, ++mVSyncCounts[displayId] & 1);
return true;
}
@@ -236,16 +221,15 @@
status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
ui::PixelFormat* format, int32_t *outId) {
if (mRemainingHwcVirtualDisplays == 0) {
- ALOGE("allocateVirtualDisplay: No remaining virtual displays");
+ ALOGE("%s: No remaining virtual displays", __FUNCTION__);
return NO_MEMORY;
}
if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
(width > SurfaceFlinger::maxVirtualDisplaySize ||
height > SurfaceFlinger::maxVirtualDisplaySize)) {
- ALOGE("createVirtualDisplay: Can't create a virtual display with"
- " a dimension > %" PRIu64 " (tried %u x %u)",
- SurfaceFlinger::maxVirtualDisplaySize, width, height);
+ ALOGE("%s: Display size %ux%u exceeds maximum dimension of %" PRIu64, __FUNCTION__, width,
+ height, SurfaceFlinger::maxVirtualDisplaySize);
return INVALID_OPERATION;
}
@@ -253,7 +237,7 @@
auto error = mHwcDevice->createVirtualDisplay(width, height, format,
&display);
if (error != HWC2::Error::None) {
- ALOGE("allocateVirtualDisplay: Failed to create HWC virtual display");
+ ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__);
return NO_MEMORY;
}
@@ -266,11 +250,13 @@
displaySlot = mDisplayData.size();
mDisplayData.resize(displaySlot + 1);
} else {
- ALOGE("allocateVirtualDisplay: Unable to allocate a display slot");
+ ALOGE("%s: Unable to allocate a display slot", __FUNCTION__);
return NO_MEMORY;
}
- mDisplayData[displaySlot].hwcDisplay = display;
+ auto& displayData = mDisplayData[displaySlot];
+ displayData.hwcDisplay = display;
+ displayData.isVirtual = true;
--mRemainingHwcVirtualDisplays;
*outId = static_cast<int32_t>(displaySlot);
@@ -347,21 +333,19 @@
}
int HWComposer::getActiveConfigIndex(int32_t displayId) const {
- if (!isValidDisplay(displayId)) {
- ALOGV("getActiveConfigIndex: Attempted to access invalid display %d", displayId);
- return -1;
- }
+ RETURN_IF_INVALID_DISPLAY(displayId, -1);
+
int index;
auto error = mDisplayData[displayId].hwcDisplay->getActiveConfigIndex(&index);
if (error == HWC2::Error::BadConfig) {
- ALOGE("getActiveConfigIndex: No config active, returning -1");
+ LOG_DISPLAY_ERROR(displayId, "No active config");
return -1;
- } else if (error != HWC2::Error::None) {
- ALOGE("getActiveConfigIndex failed for display %d: %s (%d)", displayId,
- to_string(error).c_str(), static_cast<int32_t>(error));
- return -1;
- } else if (index < 0) {
- ALOGE("getActiveConfigIndex returned an unknown config for display %d", displayId);
+ }
+
+ RETURN_IF_HWC_ERROR(error, displayId, -1);
+
+ if (index < 0) {
+ LOG_DISPLAY_ERROR(displayId, "Unknown config");
return -1;
}
@@ -393,19 +377,19 @@
void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) {
- if (displayId < 0 || displayId >= HWC_DISPLAY_VIRTUAL) {
- ALOGD("setVsyncEnabled: Ignoring for virtual display %d", displayId);
+ RETURN_IF_INVALID_DISPLAY(displayId);
+ auto& displayData = mDisplayData[displayId];
+
+ if (displayData.isVirtual) {
+ LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
return;
}
- RETURN_IF_INVALID_DISPLAY(displayId);
-
// NOTE: we use our own internal lock here because we have to call
// into the HWC with the lock held, and we want to make sure
// that even if HWC blocks (which it shouldn't), it won't
// affect other threads.
Mutex::Autolock _l(mVsyncLock);
- auto& displayData = mDisplayData[displayId];
if (enabled != displayData.vsyncEnabled) {
ATRACE_CALL();
auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
@@ -629,7 +613,8 @@
ALOGV("setPowerMode(%d, %d)", displayId, intMode);
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
- if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
+ const auto& displayData = mDisplayData[displayId];
+ if (displayData.isVirtual) {
LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
return INVALID_OPERATION;
}
@@ -639,7 +624,7 @@
setVsyncEnabled(displayId, HWC2::Vsync::Disable);
}
- auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
+ auto& hwcDisplay = displayData.hwcDisplay;
switch (mode) {
case HWC2::PowerMode::Off:
case HWC2::PowerMode::On:
@@ -708,24 +693,20 @@
return NO_ERROR;
}
-void HWComposer::disconnectDisplay(int displayId) {
- LOG_ALWAYS_FATAL_IF(displayId < 0);
+void HWComposer::disconnectDisplay(int32_t displayId) {
+ RETURN_IF_INVALID_DISPLAY(displayId);
auto& displayData = mDisplayData[displayId];
- auto displayType = HWC2::DisplayType::Invalid;
- auto error = displayData.hwcDisplay->getType(&displayType);
- RETURN_IF_HWC_ERROR_FOR("getType", error, displayId);
-
// If this was a virtual display, add its slot back for reuse by future
// virtual displays
- if (displayType == HWC2::DisplayType::Virtual) {
+ if (displayData.isVirtual) {
mFreeDisplaySlots.insert(displayId);
++mRemainingHwcVirtualDisplays;
}
const auto hwcDisplayId = displayData.hwcDisplay->getId();
mHwcDisplaySlots.erase(hwcDisplayId);
- displayData.reset();
+ displayData = DisplayData();
mHwcDevice->destroyDisplay(hwcDisplayId);
}
@@ -733,18 +714,14 @@
status_t HWComposer::setOutputBuffer(int32_t displayId,
const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+ const auto& displayData = mDisplayData[displayId];
- auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
- auto displayType = HWC2::DisplayType::Invalid;
- auto error = hwcDisplay->getType(&displayType);
- RETURN_IF_HWC_ERROR_FOR("getType", error, displayId, NAME_NOT_FOUND);
-
- if (displayType != HWC2::DisplayType::Virtual) {
+ if (!displayData.isVirtual) {
LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display");
return INVALID_OPERATION;
}
- error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
+ auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
return NO_ERROR;
}
@@ -833,26 +810,4 @@
return mDisplayData[displayId].hwcDisplay->getId();
}
-// ---------------------------------------------------------------------------
-
-HWComposer::DisplayData::DisplayData()
- : hasClientComposition(false),
- hasDeviceComposition(false),
- hwcDisplay(nullptr),
- lastPresentFence(Fence::NO_FENCE),
- outbufHandle(nullptr),
- outbufAcquireFence(Fence::NO_FENCE),
- vsyncEnabled(HWC2::Vsync::Disable) {
- ALOGV("Created new DisplayData");
-}
-
-HWComposer::DisplayData::~DisplayData() {
-}
-
-void HWComposer::DisplayData::reset() {
- ALOGV("DisplayData reset");
- *this = DisplayData();
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 9e4a683..3c5efea 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -76,7 +76,7 @@
void registerCallback(HWC2::ComposerCallback* callback,
int32_t sequenceId);
- bool getDisplayIdentificationData(hwc2_display_t displayId, uint8_t* outPort,
+ bool getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
DisplayIdentificationData* outData) const;
bool hasCapability(HWC2::Capability capability) const;
@@ -152,9 +152,8 @@
// Returns true if successful, false otherwise. The
// DisplayDevice::DisplayType of the display is returned as an output param.
- bool onVsync(hwc2_display_t displayId, int64_t timestamp,
- int32_t* outDisplay);
- std::optional<DisplayId> onHotplug(hwc2_display_t displayId, int32_t displayType,
+ bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp, int32_t* outDisplay);
+ std::optional<DisplayId> onHotplug(hwc2_display_t hwcDisplayId, int32_t displayType,
HWC2::Connection connection);
void setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled);
@@ -189,31 +188,26 @@
// For unit tests
friend TestableSurfaceFlinger;
- static const int32_t VIRTUAL_DISPLAY_ID_BASE = 2;
-
bool isValidDisplay(int32_t displayId) const;
static void validateChange(HWC2::Composition from, HWC2::Composition to);
struct cb_context;
struct DisplayData {
- DisplayData();
- ~DisplayData();
- void reset();
-
- bool hasClientComposition;
- bool hasDeviceComposition;
- HWC2::Display* hwcDisplay;
+ bool isVirtual = false;
+ bool hasClientComposition = false;
+ bool hasDeviceComposition = false;
+ HWC2::Display* hwcDisplay = nullptr;
HWC2::DisplayRequest displayRequests;
- sp<Fence> lastPresentFence; // signals when the last set op retires
+ sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires
std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
- buffer_handle_t outbufHandle;
- sp<Fence> outbufAcquireFence;
+ buffer_handle_t outbufHandle = nullptr;
+ sp<Fence> outbufAcquireFence = Fence::NO_FENCE;
mutable std::unordered_map<int32_t,
std::shared_ptr<const HWC2::Display::Config>> configMap;
// protected by mVsyncLock
- HWC2::Vsync vsyncEnabled;
+ HWC2::Vsync vsyncEnabled = HWC2::Vsync::Disable;
bool validateWasSkipped;
HWC2::Error presentError;
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index bc271c8..5a8fd25 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -155,20 +155,17 @@
mCondition.notify_all();
}
-void EventThread::onHotplugReceived(int type, bool connected) {
- ALOGE_IF(type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
- "received hotplug event for an invalid display (id=%d)", type);
-
+void EventThread::onHotplugReceived(DisplayType displayType, bool connected) {
std::lock_guard<std::mutex> lock(mMutex);
- if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
- DisplayEventReceiver::Event event;
- event.header.type = DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;
- event.header.id = type;
- event.header.timestamp = systemTime();
- event.hotplug.connected = connected;
- mPendingEvents.add(event);
- mCondition.notify_all();
- }
+
+ DisplayEventReceiver::Event event;
+ event.header.type = DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;
+ event.header.id = displayType == DisplayType::Primary ? 0 : 1;
+ event.header.timestamp = systemTime();
+ event.hotplug.connected = connected;
+
+ mPendingEvents.add(event);
+ mCondition.notify_all();
}
void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {
@@ -205,7 +202,7 @@
// This will return when (1) a vsync event has been received, and (2) there was
// at least one connection interested in receiving it when we started waiting.
Vector<sp<EventThread::Connection> > EventThread::waitForEventLocked(
- std::unique_lock<std::mutex>* lock, DisplayEventReceiver::Event* event) {
+ std::unique_lock<std::mutex>* lock, DisplayEventReceiver::Event* outEvent) {
Vector<sp<EventThread::Connection> > signalConnections;
while (signalConnections.isEmpty() && mKeepRunning) {
@@ -214,16 +211,16 @@
size_t vsyncCount = 0;
nsecs_t timestamp = 0;
- for (int32_t i = 0; i < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; i++) {
- timestamp = mVSyncEvent[i].header.timestamp;
+ for (auto& event : mVSyncEvent) {
+ timestamp = event.header.timestamp;
if (timestamp) {
// we have a vsync event to dispatch
if (mInterceptVSyncsCallback) {
mInterceptVSyncsCallback(timestamp);
}
- *event = mVSyncEvent[i];
- mVSyncEvent[i].header.timestamp = 0;
- vsyncCount = mVSyncEvent[i].vsync.count;
+ *outEvent = event;
+ event.header.timestamp = 0;
+ vsyncCount = event.vsync.count;
break;
}
}
@@ -233,7 +230,7 @@
eventPending = !mPendingEvents.isEmpty();
if (eventPending) {
// we have some other event to dispatch
- *event = mPendingEvents[0];
+ *outEvent = mPendingEvents[0];
mPendingEvents.removeAt(0);
}
}
@@ -319,7 +316,7 @@
// FIXME: how do we decide which display id the fake
// vsync came from ?
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
- mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;
+ mVSyncEvent[0].header.id = 0;
mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
mVSyncEvent[0].vsync.count++;
}
@@ -364,8 +361,7 @@
result.appendFormat("VSYNC state: %s\n", mDebugVsyncEnabled ? "enabled" : "disabled");
result.appendFormat(" soft-vsync: %s\n", mUseSoftwareVSync ? "enabled" : "disabled");
result.appendFormat(" numListeners=%zu,\n events-delivered: %u\n",
- mDisplayEventConnections.size(),
- mVSyncEvent[DisplayDevice::DISPLAY_PRIMARY].vsync.count);
+ mDisplayEventConnections.size(), mVSyncEvent[0].vsync.count);
for (size_t i = 0; i < mDisplayEventConnections.size(); i++) {
sp<Connection> connection = mDisplayEventConnections.itemAt(i).promote();
result.appendFormat(" %p: count=%d\n", connection.get(),
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index 9c13ed2..a0262b2 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -16,9 +16,11 @@
#pragma once
-#include <stdint.h>
#include <sys/types.h>
+
+#include <array>
#include <condition_variable>
+#include <cstdint>
#include <mutex>
#include <thread>
@@ -31,8 +33,6 @@
#include <utils/Errors.h>
#include <utils/SortedVector.h>
-#include "DisplayDevice.h"
-
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
@@ -59,6 +59,9 @@
class EventThread {
public:
+ // TODO: Remove once stable display IDs are plumbed through SF/WM interface.
+ enum class DisplayType { Primary, External };
+
virtual ~EventThread();
virtual sp<BnDisplayEventConnection> createEventConnection() const = 0;
@@ -70,7 +73,7 @@
virtual void onScreenAcquired() = 0;
// called when receiving a hotplug event
- virtual void onHotplugReceived(int type, bool connected) = 0;
+ virtual void onHotplugReceived(DisplayType displayType, bool connected) = 0;
virtual void dump(String8& result) const = 0;
@@ -122,7 +125,7 @@
void onScreenAcquired() override;
// called when receiving a hotplug event
- void onHotplugReceived(int type, bool connected) override;
+ void onHotplugReceived(DisplayType displayType, bool connected) override;
void dump(String8& result) const override;
@@ -155,8 +158,7 @@
// protected by mLock
SortedVector<wp<Connection>> mDisplayEventConnections GUARDED_BY(mMutex);
Vector<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);
- DisplayEventReceiver::Event mVSyncEvent[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES] GUARDED_BY(
- mMutex);
+ std::array<DisplayEventReceiver::Event, 2> mVSyncEvent GUARDED_BY(mMutex);
bool mUseSoftwareVSync GUARDED_BY(mMutex) = false;
bool mVsyncEnabled GUARDED_BY(mMutex) = false;
bool mKeepRunning GUARDED_BY(mMutex) = true;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5a0bf43..b4b3f4a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -363,7 +363,7 @@
return reduce(floatWin, activeTransparentRegion);
}
-Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& hw) const {
+Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& display) const {
// the crop is the area of the window that gets cropped, but not
// scaled in any ways.
const State& s(getDrawingState());
@@ -382,7 +382,7 @@
Transform t = getTransform();
activeCrop = t.transform(activeCrop);
- if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
+ if (!activeCrop.intersect(display->getViewport(), &activeCrop)) {
activeCrop.clear();
}
if (!s.finalCrop.isEmpty()) {
@@ -393,14 +393,14 @@
const auto& p = mDrawingParent.promote();
if (p != nullptr) {
- auto parentCrop = p->computeInitialCrop(hw);
+ auto parentCrop = p->computeInitialCrop(display);
activeCrop.intersect(parentCrop, &activeCrop);
}
return activeCrop;
}
-FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
+FloatRect Layer::computeCrop(const sp<const DisplayDevice>& display) const {
// the content crop is the area of the content that gets scaled to the
// layer's size. This is in buffer space.
FloatRect crop = getContentCrop().toFloatRect();
@@ -409,7 +409,7 @@
const State& s(getDrawingState());
// Screen space to make reduction to parent crop clearer.
- Rect activeCrop = computeInitialCrop(hw);
+ Rect activeCrop = computeInitialCrop(display);
Transform t = getTransform();
// Back to layer space to work with the content crop.
activeCrop = t.inverse().transform(activeCrop);
@@ -1376,13 +1376,13 @@
return usage;
}
-void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
+void Layer::updateTransformHint(const sp<const DisplayDevice>& display) const {
uint32_t orientation = 0;
if (!mFlinger->mDebugDisableTransformHint) {
// The transform hint is used to improve performance, but we can
// only have a single transform hint, it cannot
// apply to all displays.
- const Transform& planeTransform(hw->getTransform());
+ const Transform& planeTransform = display->getTransform();
orientation = planeTransform.getOrientation();
if (orientation & Transform::ROT_INVALID) {
orientation = 0;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index fe953cd..fb94058 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -328,7 +328,7 @@
HWC2::Composition getCompositionType(int32_t displayId) const;
void setClearClientTarget(int32_t displayId, bool clear);
bool getClearClientTarget(int32_t displayId) const;
- void updateCursorPosition(const sp<const DisplayDevice>& hw);
+ void updateCursorPosition(const sp<const DisplayDevice>& display);
/*
* called after page-flip
@@ -425,7 +425,7 @@
// Updates the transform hint in our SurfaceFlingerConsumer to match
// the current orientation of the display device.
- void updateTransformHint(const sp<const DisplayDevice>& hw) const;
+ void updateTransformHint(const sp<const DisplayDevice>& display) const;
/*
* returns the rectangle that crops the content of the layer and scales it
@@ -556,12 +556,12 @@
uint32_t getEffectiveUsage(uint32_t usage) const;
- FloatRect computeCrop(const sp<const DisplayDevice>& hw) const;
+ FloatRect computeCrop(const sp<const DisplayDevice>& display) const;
// Compute the initial crop as specified by parent layers and the
// SurfaceControl for this layer. Does not include buffer crop from the
// IGraphicBufferProducer client, as that should not affect child clipping.
// Returns in screen space.
- Rect computeInitialCrop(const sp<const DisplayDevice>& hw) const;
+ Rect computeInitialCrop(const sp<const DisplayDevice>& display) const;
// drawing
void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index dec1178..2a2be83 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -668,12 +668,14 @@
getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);
// Process any initial hotplug and resulting display changes.
processDisplayHotplugEventsLocked();
- LOG_ALWAYS_FATAL_IF(!getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY),
- "Registered composer callback but didn't create the default primary display");
+ const auto display = getDefaultDisplayDeviceLocked();
+ LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
+ LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(display->getId()),
+ "Internal display is disconnected.");
// make the default display GLContext current so that we can create textures
// when creating Layers (which may happens before we render something)
- getDefaultDisplayDeviceLocked()->makeCurrent();
+ display->makeCurrent();
if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this](bool requestDisplay) {
@@ -689,9 +691,11 @@
signalTransaction();
}));
};
- mVrFlinger = dvr::VrFlinger::Create(getBE().mHwc->getComposer(),
- getBE().mHwc->getHwcDisplayId(HWC_DISPLAY_PRIMARY).value_or(0),
- vrFlingerRequestDisplayCallback);
+ mVrFlinger = dvr::VrFlinger::Create(getHwComposer().getComposer(),
+ getHwComposer()
+ .getHwcDisplayId(display->getId())
+ .value_or(0),
+ vrFlingerRequestDisplayCallback);
if (!mVrFlinger) {
ALOGE("Failed to start vrflinger");
}
@@ -720,8 +724,8 @@
ALOGE("Run StartPropertySetThread failed!");
}
- mLegacySrgbSaturationMatrix = getBE().mHwc->getDataspaceSaturationMatrix(HWC_DISPLAY_PRIMARY,
- Dataspace::SRGB_LINEAR);
+ mLegacySrgbSaturationMatrix =
+ getHwComposer().getDataspaceSaturationMatrix(display->getId(), Dataspace::SRGB_LINEAR);
ALOGV("Done initializing");
}
@@ -1207,7 +1211,6 @@
Mutex::Autolock _l(mHWVsyncLock);
if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
mPrimaryDispSync.beginResync();
- //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
mEventControlThread->setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
@@ -1224,7 +1227,12 @@
return;
}
- const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+ const auto displayId = DisplayDevice::DISPLAY_PRIMARY;
+ if (!getHwComposer().isConnected(displayId)) {
+ return;
+ }
+
+ const auto activeConfig = getHwComposer().getActiveConfig(displayId);
const nsecs_t period = activeConfig->getVsyncPeriod();
mPrimaryDispSync.reset();
@@ -1232,7 +1240,6 @@
if (!mPrimaryHWVsyncEnabled) {
mPrimaryDispSync.beginResync();
- //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
mEventControlThread->setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
@@ -1241,7 +1248,6 @@
void SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
Mutex::Autolock _l(mHWVsyncLock);
if (mPrimaryHWVsyncEnabled) {
- //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
mEventControlThread->setVsyncEnabled(false);
mPrimaryDispSync.endResync();
mPrimaryHWVsyncEnabled = false;
@@ -1263,8 +1269,8 @@
sLastResyncAttempted = now;
}
-void SurfaceFlinger::onVsyncReceived(int32_t sequenceId,
- hwc2_display_t displayId, int64_t timestamp) {
+void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
+ int64_t timestamp) {
Mutex::Autolock lock(mStateLock);
// Ignore any vsyncs from a previous hardware composer.
if (sequenceId != getBE().mComposerSequenceId) {
@@ -1272,7 +1278,7 @@
}
int32_t type;
- if (!getBE().mHwc->onVsync(displayId, timestamp, &type)) {
+ if (!getBE().mHwc->onVsync(hwcDisplayId, timestamp, &type)) {
return;
}
@@ -1297,9 +1303,9 @@
*compositorTiming = getBE().mCompositorTiming;
}
-void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
+void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
HWC2::Connection connection) {
- ALOGV("onHotplugReceived(%d, %" PRIu64 ", %s)", sequenceId, display,
+ ALOGV("%s(%d, %" PRIu64 ", %s)", __FUNCTION__, sequenceId, hwcDisplayId,
connection == HWC2::Connection::Connected ? "connected" : "disconnected");
// Ignore events that do not have the right sequenceId.
@@ -1313,7 +1319,7 @@
// acquire it here.
ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);
- mPendingHotplugEvents.emplace_back(HotplugEvent{display, connection});
+ mPendingHotplugEvents.emplace_back(HotplugEvent{hwcDisplayId, connection});
if (std::this_thread::get_id() == mMainThreadId) {
// Process all pending hot plug events immediately if we are on the main thread.
@@ -1323,8 +1329,7 @@
setTransactionFlags(eDisplayTransactionNeeded);
}
-void SurfaceFlinger::onRefreshReceived(int sequenceId,
- hwc2_display_t /*display*/) {
+void SurfaceFlinger::onRefreshReceived(int sequenceId, hwc2_display_t /*hwcDisplayId*/) {
Mutex::Autolock lock(mStateLock);
if (sequenceId != getBE().mComposerSequenceId) {
return;
@@ -1369,7 +1374,9 @@
Mutex::Autolock _l(mStateLock);
- int currentDisplayPowerMode = getDefaultDisplayDeviceLocked()->getPowerMode();
+ const auto display = getDefaultDisplayDeviceLocked();
+ LOG_ALWAYS_FATAL_IF(!display);
+ const int currentDisplayPowerMode = display->getPowerMode();
if (!vrFlingerRequestsDisplay) {
mVrFlinger->SeizeDisplayOwnership();
@@ -1394,11 +1401,10 @@
invalidateHwcGeometry();
// Re-enable default display.
- setPowerModeInternal(getDefaultDisplayDeviceLocked(), currentDisplayPowerMode,
- /*stateLockHeld*/ true);
+ setPowerModeInternal(display, currentDisplayPowerMode, /*stateLockHeld*/ true);
// Reset the timing values to account for the period of the swapped in HWC
- const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+ const auto activeConfig = getHwComposer().getActiveConfig(display->getId());
const nsecs_t period = activeConfig->getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(period);
@@ -1481,8 +1487,6 @@
doComposition();
postComposition(refreshStartTime);
- mPreviousPresentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
-
mHadClientComposition = false;
for (const auto& [token, display] : mDisplays) {
mHadClientComposition = mHadClientComposition ||
@@ -1649,7 +1653,7 @@
getBE().mGlCompositionDoneTimeline.updateSignalTimes();
std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
- if (display && getBE().mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
+ if (display && getHwComposer().hasClientComposition(display->getId())) {
glCompositionDoneFenceTime =
std::make_shared<FenceTime>(display->getClientTargetAcquireFence());
getBE().mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
@@ -1658,8 +1662,9 @@
}
getBE().mDisplayTimeline.updateSignalTimes();
- sp<Fence> presentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
- auto presentFenceTime = std::make_shared<FenceTime>(presentFence);
+ mPreviousPresentFence =
+ display ? getHwComposer().getPresentFence(display->getId()) : Fence::NO_FENCE;
+ auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFence);
getBE().mDisplayTimeline.push(presentFenceTime);
nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
@@ -1694,7 +1699,7 @@
}
if (!hasSyncFramework) {
- if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY) && display->isPoweredOn()) {
+ if (display && getHwComposer().isConnected(display->getId()) && display->isPoweredOn()) {
enableHardwareVsync();
}
}
@@ -1705,11 +1710,10 @@
if (presentFenceTime->isValid()) {
mAnimFrameTracker.setActualPresentFence(
std::move(presentFenceTime));
- } else if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY)) {
+ } else if (display && getHwComposer().isConnected(display->getId())) {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
- nsecs_t presentTime =
- getBE().mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
+ const nsecs_t presentTime = getHwComposer().getRefreshTimestamp(display->getId());
mAnimFrameTracker.setActualPresentTime(presentTime);
}
mAnimFrameTracker.advanceFrame();
@@ -1720,7 +1724,7 @@
mTimeStats.incrementClientCompositionFrames();
}
- if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY) &&
+ if (display && getHwComposer().isConnected(display->getId()) &&
display->getPowerMode() == HWC_POWER_MODE_OFF) {
return;
}
@@ -2070,8 +2074,9 @@
mDebugInSwapBuffers = 0;
// |mStateLock| not needed as we are on the main thread
- if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY)) {
- uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount();
+ const auto display = getDefaultDisplayDeviceLocked();
+ if (display && getHwComposer().isConnected(display->getId())) {
+ const uint32_t flipCount = display->getPageFlipCount();
if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
logFrameStats();
}
@@ -2135,9 +2140,9 @@
void SurfaceFlinger::processDisplayHotplugEventsLocked() {
for (const auto& event : mPendingHotplugEvents) {
- auto displayType = determineDisplayType(event.display, event.connection);
+ auto displayType = determineDisplayType(event.hwcDisplayId, event.connection);
if (displayType == DisplayDevice::DISPLAY_ID_INVALID) {
- ALOGW("Unable to determine the display type for display %" PRIu64, event.display);
+ ALOGW("Unable to determine the display type for display %" PRIu64, event.hwcDisplayId);
continue;
}
@@ -2147,9 +2152,9 @@
}
const auto displayId =
- getBE().mHwc->onHotplug(event.display, displayType, event.connection);
+ getBE().mHwc->onHotplug(event.hwcDisplayId, displayType, event.connection);
if (displayId) {
- ALOGV("Display %" PRIu64 " has stable ID %" PRIu64, event.display, *displayId);
+ ALOGV("Display %" PRIu64 " has stable ID %" PRIu64, event.hwcDisplayId, *displayId);
}
if (event.connection == HWC2::Connection::Connected) {
@@ -2294,8 +2299,11 @@
if (const auto display = getDisplayDeviceLocked(draw.keyAt(i))) {
display->disconnect(getHwComposer());
}
- if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
- mEventThread->onHotplugReceived(draw[i].type, false);
+ if (draw[i].type == DisplayDevice::DISPLAY_PRIMARY) {
+ mEventThread->onHotplugReceived(EventThread::DisplayType::Primary, false);
+ } else if (draw[i].type == DisplayDevice::DISPLAY_EXTERNAL) {
+ mEventThread->onHotplugReceived(EventThread::DisplayType::External, false);
+ }
mDisplays.erase(draw.keyAt(i));
} else {
// this display is in both lists. see if something changed.
@@ -2396,7 +2404,13 @@
setupNewDisplayDeviceInternal(displayToken, displayId, state,
dispSurface, producer));
if (!state.isVirtual()) {
- mEventThread->onHotplugReceived(state.type, true);
+ if (state.type == DisplayDevice::DISPLAY_PRIMARY) {
+ mEventThread->onHotplugReceived(EventThread::DisplayType::Primary,
+ true);
+ } else if (state.type == DisplayDevice::DISPLAY_EXTERNAL) {
+ mEventThread->onHotplugReceived(EventThread::DisplayType::External,
+ true);
+ }
}
}
}
@@ -2845,8 +2859,9 @@
getRenderEngine().resetCurrentSurface();
// |mStateLock| not needed as we are on the main thread
- if(!getDefaultDisplayDeviceLocked()->makeCurrent()) {
- ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
+ const auto defaultDisplay = getDefaultDisplayDeviceLocked();
+ if (!defaultDisplay || !defaultDisplay->makeCurrent()) {
+ ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
}
return false;
}
@@ -3190,53 +3205,51 @@
}
}
-uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
-{
- ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
- if (dpyIdx < 0)
- return 0;
+uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) {
+ const ssize_t index = mCurrentState.displays.indexOfKey(s.token);
+ if (index < 0) return 0;
uint32_t flags = 0;
- DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
- if (disp.isValid()) {
- const uint32_t what = s.what;
- if (what & DisplayState::eSurfaceChanged) {
- if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
- disp.surface = s.surface;
- flags |= eDisplayTransactionNeeded;
- }
- }
- if (what & DisplayState::eLayerStackChanged) {
- if (disp.layerStack != s.layerStack) {
- disp.layerStack = s.layerStack;
- flags |= eDisplayTransactionNeeded;
- }
- }
- if (what & DisplayState::eDisplayProjectionChanged) {
- if (disp.orientation != s.orientation) {
- disp.orientation = s.orientation;
- flags |= eDisplayTransactionNeeded;
- }
- if (disp.frame != s.frame) {
- disp.frame = s.frame;
- flags |= eDisplayTransactionNeeded;
- }
- if (disp.viewport != s.viewport) {
- disp.viewport = s.viewport;
- flags |= eDisplayTransactionNeeded;
- }
- }
- if (what & DisplayState::eDisplaySizeChanged) {
- if (disp.width != s.width) {
- disp.width = s.width;
- flags |= eDisplayTransactionNeeded;
- }
- if (disp.height != s.height) {
- disp.height = s.height;
- flags |= eDisplayTransactionNeeded;
- }
+ DisplayDeviceState& state = mCurrentState.displays.editValueAt(index);
+
+ const uint32_t what = s.what;
+ if (what & DisplayState::eSurfaceChanged) {
+ if (IInterface::asBinder(state.surface) != IInterface::asBinder(s.surface)) {
+ state.surface = s.surface;
+ flags |= eDisplayTransactionNeeded;
}
}
+ if (what & DisplayState::eLayerStackChanged) {
+ if (state.layerStack != s.layerStack) {
+ state.layerStack = s.layerStack;
+ flags |= eDisplayTransactionNeeded;
+ }
+ }
+ if (what & DisplayState::eDisplayProjectionChanged) {
+ if (state.orientation != s.orientation) {
+ state.orientation = s.orientation;
+ flags |= eDisplayTransactionNeeded;
+ }
+ if (state.frame != s.frame) {
+ state.frame = s.frame;
+ flags |= eDisplayTransactionNeeded;
+ }
+ if (state.viewport != s.viewport) {
+ state.viewport = s.viewport;
+ flags |= eDisplayTransactionNeeded;
+ }
+ }
+ if (what & DisplayState::eDisplaySizeChanged) {
+ if (state.width != s.width) {
+ state.width = s.width;
+ flags |= eDisplayTransactionNeeded;
+ }
+ if (state.height != s.height) {
+ state.height = s.height;
+ flags |= eDisplayTransactionNeeded;
+ }
+ }
+
return flags;
}
@@ -3570,13 +3583,16 @@
// ---------------------------------------------------------------------------
void SurfaceFlinger::onInitializeDisplays() {
+ const auto displayToken = mDisplayTokens[DisplayDevice::DISPLAY_PRIMARY];
+ if (!displayToken) return;
+
// reset screen orientation and use primary layer stack
Vector<ComposerState> state;
Vector<DisplayState> displays;
DisplayState d;
d.what = DisplayState::eDisplayProjectionChanged |
DisplayState::eLayerStackChanged;
- d.token = mDisplayTokens[DisplayDevice::DISPLAY_PRIMARY];
+ d.token = displayToken;
d.layerStack = 0;
d.orientation = DisplayState::eOrientationDefault;
d.frame.makeInvalid();
@@ -3585,10 +3601,13 @@
d.height = 0;
displays.add(d);
setTransactionState(state, displays, 0);
- setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL,
- /*stateLockHeld*/ false);
- const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+ const auto display = getDisplayDevice(displayToken);
+ if (!display) return;
+
+ setPowerModeInternal(display, HWC_POWER_MODE_NORMAL, /*stateLockHeld*/ false);
+
+ const auto activeConfig = getHwComposer().getActiveConfig(display->getId());
const nsecs_t period = activeConfig->getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(period);
@@ -3859,9 +3878,12 @@
index++;
}
- const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
- const nsecs_t period = activeConfig->getVsyncPeriod();
- result.appendFormat("%" PRId64 "\n", period);
+ if (const auto displayId = DisplayDevice::DISPLAY_PRIMARY;
+ getHwComposer().isConnected(displayId)) {
+ const auto activeConfig = getBE().mHwc->getActiveConfig(displayId);
+ const nsecs_t period = activeConfig->getVsyncPeriod();
+ result.appendFormat("%" PRId64 "\n", period);
+ }
if (name.isEmpty()) {
mAnimFrameTracker.dumpStats(result);
@@ -4142,15 +4164,20 @@
result.append(SyncFeatures::getInstance().toString());
result.append("\n");
- const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
-
colorizer.bold(result);
- result.append("DispSync configuration: ");
+ result.append("DispSync configuration:\n");
colorizer.reset(result);
- result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, early sf phase %" PRId64
- " ns, present offset %" PRId64 " ns (refresh %" PRId64 " ns)",
- vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, mVsyncModulator.getEarlyPhaseOffset(),
- dispSyncPresentTimeOffset, activeConfig->getVsyncPeriod());
+
+ if (const auto displayId = DisplayDevice::DISPLAY_PRIMARY;
+ getHwComposer().isConnected(displayId)) {
+ const auto activeConfig = getHwComposer().getActiveConfig(displayId);
+ result.appendFormat("Display %d: app phase %" PRId64 " ns, sf phase %" PRId64
+ " ns, early sf phase %" PRId64 " ns, present offset %" PRId64
+ " ns (refresh %" PRId64 " ns)",
+ displayId, vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
+ mVsyncModulator.getEarlyPhaseOffset(), dispSyncPresentTimeOffset,
+ activeConfig->getVsyncPeriod());
+ }
result.append("\n");
// Dump static screen stats
@@ -4206,22 +4233,21 @@
result.appendFormat(" orientation=%d, isPoweredOn=%d\n", display->getOrientation(),
display->isPoweredOn());
}
- result.appendFormat(
- " last eglSwapBuffers() time: %f us\n"
- " last transaction time : %f us\n"
- " transaction-flags : %08x\n"
- " refresh-rate : %f fps\n"
- " x-dpi : %f\n"
- " y-dpi : %f\n"
- " gpu_to_cpu_unsupported : %d\n"
- ,
- mLastSwapBufferTime/1000.0,
- mLastTransactionTime/1000.0,
- mTransactionFlags,
- 1e9 / activeConfig->getVsyncPeriod(),
- activeConfig->getDpiX(),
- activeConfig->getDpiY(),
- !mGpuToCpuSupported);
+ result.appendFormat(" last eglSwapBuffers() time: %f us\n"
+ " last transaction time : %f us\n"
+ " transaction-flags : %08x\n"
+ " gpu_to_cpu_unsupported : %d\n",
+ mLastSwapBufferTime / 1000.0, mLastTransactionTime / 1000.0,
+ mTransactionFlags, !mGpuToCpuSupported);
+
+ if (display) {
+ const auto activeConfig = getHwComposer().getActiveConfig(display->getId());
+ result.appendFormat(" refresh-rate : %f fps\n"
+ " x-dpi : %f\n"
+ " y-dpi : %f\n",
+ 1e9 / activeConfig->getVsyncPeriod(), activeConfig->getDpiX(),
+ activeConfig->getDpiY());
+ }
result.appendFormat(" eglSwapBuffers time: %f us\n",
inSwapBuffersDuration/1000.0);
@@ -4279,19 +4305,15 @@
const Vector<sp<Layer>>& SurfaceFlinger::getLayerSortedByZForHwcDisplay(int32_t displayId) {
// Note: mStateLock is held here
- wp<IBinder> displayToken;
for (const auto& [token, display] : mDisplays) {
if (display->getId() == displayId) {
- displayToken = token;
- break;
+ return getDisplayDeviceLocked(token)->getVisibleLayersSortedByZ();
}
}
- if (displayToken == nullptr) {
- ALOGE("getLayerSortedByZForHwcDisplay: Invalid display %d", displayId);
- // Just use the primary display so we have something to return
- displayToken = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
- }
- return getDisplayDeviceLocked(displayToken)->getVisibleLayersSortedByZ();
+
+ ALOGE("%s: Invalid display %d", __FUNCTION__, displayId);
+ static const Vector<sp<Layer>> empty;
+ return empty;
}
bool SurfaceFlinger::startDdmConnection()
@@ -4466,6 +4488,10 @@
return NO_ERROR;
case 1013: {
const auto display = getDefaultDisplayDevice();
+ if (!display) {
+ return NAME_NOT_FOUND;
+ }
+
reply->writeInt32(display->getPageFlipCount());
return NO_ERROR;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 48c3f73..87e0699 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -457,11 +457,11 @@
/* ------------------------------------------------------------------------
* HWC2::ComposerCallback / HWComposer::EventHandler interface
*/
- void onVsyncReceived(int32_t sequenceId, hwc2_display_t display,
+ void onVsyncReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
int64_t timestamp) override;
- void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
+ void onHotplugReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
HWC2::Connection connection) override;
- void onRefreshReceived(int32_t sequenceId, hwc2_display_t display) override;
+ void onRefreshReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId) override;
/* ------------------------------------------------------------------------
* Message handling
@@ -665,8 +665,7 @@
void logLayerStats();
void doDisplayComposition(const sp<const DisplayDevice>& display, const Region& dirtyRegion);
- // compose surfaces for display hw. this fails if using GL and the surface
- // has been destroyed and is no longer valid.
+ // This fails if using GL and the surface has been destroyed.
bool doComposeSurfaces(const sp<const DisplayDevice>& display);
void postFramebuffer();
@@ -675,8 +674,8 @@
/* ------------------------------------------------------------------------
* Display management
*/
- DisplayDevice::DisplayType determineDisplayType(hwc2_display_t display,
- HWC2::Connection connection) const;
+ DisplayDevice::DisplayType determineDisplayType(hwc2_display_t hwcDisplayId,
+ HWC2::Connection connection) const;
sp<DisplayDevice> setupNewDisplayDeviceInternal(const wp<IBinder>& displayToken,
int32_t displayId,
const DisplayDeviceState& state,
@@ -802,7 +801,7 @@
bool mHadClientComposition = false;
struct HotplugEvent {
- hwc2_display_t display;
+ hwc2_display_t hwcDisplayId;
HWC2::Connection connection = HWC2::Connection::Invalid;
};
// protected by mStateLock
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 1a7805a..3be2ad0 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -245,6 +245,8 @@
// The type for this display
static constexpr DisplayDevice::DisplayType TYPE = type;
+ static_assert(TYPE != DisplayDevice::DISPLAY_ID_INVALID);
+
static constexpr DisplayDevice::DisplayType DISPLAY_ID = displayId;
// When creating native window surfaces for the framebuffer, whether those should be critical
@@ -385,11 +387,6 @@
DisplayVariant<type, type, width, height, critical, Async::FALSE,
Secure::TRUE, GRALLOC_USAGE_PHYSICAL_DISPLAY>> {};
-// An invalid display
-using InvalidDisplayVariant =
- DisplayVariant<DisplayDevice::DISPLAY_ID_INVALID, DisplayDevice::DISPLAY_ID_INVALID, 0, 0,
- Critical::FALSE, Async::FALSE, Secure::FALSE, 0>;
-
// A primary display is a physical display that is critical
using PrimaryDisplayVariant =
PhysicalDisplayVariant<1001, DisplayDevice::DISPLAY_PRIMARY, 3840, 2160, Critical::TRUE>;
@@ -686,9 +683,7 @@
Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
HdrNotSupportedVariant<PrimaryDisplayVariant>,
Cta861_3_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
-using InvalidDisplayCase = Case<InvalidDisplayVariant, WideColorSupportNotConfiguredVariant,
- NonHwcDisplayHdrSupportVariant,
- NoPerFrameMetadataSupportVariant<InvalidDisplayVariant>>;
+
/* ------------------------------------------------------------------------
*
* SurfaceFlinger::onHotplugReceived
@@ -696,8 +691,8 @@
TEST_F(DisplayTransactionTest, hotplugEnqueuesEventsForDisplayTransaction) {
constexpr int currentSequenceId = 123;
- constexpr hwc2_display_t displayId1 = 456;
- constexpr hwc2_display_t displayId2 = 654;
+ constexpr hwc2_display_t hwcDisplayId1 = 456;
+ constexpr hwc2_display_t hwcDisplayId2 = 654;
// --------------------------------------------------------------------
// Preconditions
@@ -720,8 +715,8 @@
// Invocation
// Simulate two hotplug events (a connect and a disconnect)
- mFlinger.onHotplugReceived(currentSequenceId, displayId1, HWC2::Connection::Connected);
- mFlinger.onHotplugReceived(currentSequenceId, displayId2, HWC2::Connection::Disconnected);
+ mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId1, HWC2::Connection::Connected);
+ mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId2, HWC2::Connection::Disconnected);
// --------------------------------------------------------------------
// Postconditions
@@ -732,9 +727,9 @@
// All events should be in the pending event queue.
const auto& pendingEvents = mFlinger.mutablePendingHotplugEvents();
ASSERT_EQ(2u, pendingEvents.size());
- EXPECT_EQ(displayId1, pendingEvents[0].display);
+ EXPECT_EQ(hwcDisplayId1, pendingEvents[0].hwcDisplayId);
EXPECT_EQ(HWC2::Connection::Connected, pendingEvents[0].connection);
- EXPECT_EQ(displayId2, pendingEvents[1].display);
+ EXPECT_EQ(hwcDisplayId2, pendingEvents[1].hwcDisplayId);
EXPECT_EQ(HWC2::Connection::Disconnected, pendingEvents[1].connection);
}
@@ -1165,13 +1160,23 @@
Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
- EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::TYPE, true)).Times(1);
+ EXPECT_CALL(*mEventThread,
+ onHotplugReceived(Case::Display::TYPE == DisplayDevice::DISPLAY_PRIMARY
+ ? EventThread::DisplayType::Primary
+ : EventThread::DisplayType::External,
+ true))
+ .Times(1);
}
template <typename Case>
void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() {
EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
- EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::TYPE, false)).Times(1);
+ EXPECT_CALL(*mEventThread,
+ onHotplugReceived(Case::Display::TYPE == DisplayDevice::DISPLAY_PRIMARY
+ ? EventThread::DisplayType::Primary
+ : EventThread::DisplayType::External,
+ false))
+ .Times(1);
}
template <typename Case>
@@ -1824,40 +1829,6 @@
EXPECT_FALSE(hasCurrentDisplayState(displayToken));
}
-TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithInvalidDisplay) {
- using Case = InvalidDisplayCase;
-
- // --------------------------------------------------------------------
- // Preconditions
-
- // An invalid display is set up
- auto display = Case::Display::makeFakeExistingDisplayInjector(this);
- display.inject();
-
- // The invalid display has some state
- display.mutableCurrentDisplayState().layerStack = 654u;
-
- // The requested display state tries to change the display state.
- DisplayState state;
- state.what = DisplayState::eLayerStackChanged;
- state.token = display.token();
- state.layerStack = 456;
-
- // --------------------------------------------------------------------
- // Invocation
-
- uint32_t flags = mFlinger.setDisplayStateLocked(state);
-
- // --------------------------------------------------------------------
- // Postconditions
-
- // The returned flags are empty
- EXPECT_EQ(0u, flags);
-
- // The current display layer stack value is unchanged.
- EXPECT_EQ(654u, getCurrentDisplayState(display.token()).layerStack);
-}
-
TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWhenNoChanges) {
using Case = SimplePrimaryDisplayCase;
@@ -2684,7 +2655,7 @@
auto display = Case::Display::makeFakeExistingDisplayInjector(this);
display.inject();
- // The diplay is already set to HWC_POWER_MODE_NORMAL
+ // The display is already set to HWC_POWER_MODE_NORMAL
display.mutableDisplayDevice()->setPowerMode(HWC_POWER_MODE_NORMAL);
// --------------------------------------------------------------------
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index 80fdb80..19747bd 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -71,7 +71,8 @@
ConnectionEventRecorder& connectionEventRecorder,
nsecs_t expectedTimestamp, unsigned expectedCount);
void expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp, unsigned expectedCount);
- void expectHotplugEventReceivedByConnection(int expectedDisplayType, bool expectedConnected);
+ void expectHotplugEventReceivedByConnection(EventThread::DisplayType expectedDisplayType,
+ bool expectedConnected);
AsyncCallRecorder<void (*)(bool)> mVSyncSetEnabledCallRecorder;
AsyncCallRecorder<void (*)(VSyncSource::Callback*)> mVSyncSetCallbackCallRecorder;
@@ -169,13 +170,16 @@
expectedCount);
}
-void EventThreadTest::expectHotplugEventReceivedByConnection(int expectedDisplayType,
- bool expectedConnected) {
+void EventThreadTest::expectHotplugEventReceivedByConnection(
+ EventThread::DisplayType expectedDisplayType, bool expectedConnected) {
+ const uint32_t expectedDisplayId =
+ expectedDisplayType == EventThread::DisplayType::Primary ? 0 : 1;
+
auto args = mConnectionEventCallRecorder.waitForCall();
ASSERT_TRUE(args.has_value());
const auto& event = std::get<0>(args.value());
EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, event.header.type);
- EXPECT_EQ(static_cast<unsigned>(expectedDisplayType), event.header.id);
+ EXPECT_EQ(expectedDisplayId, event.header.id);
EXPECT_EQ(expectedConnected, event.hotplug.connected);
}
@@ -394,28 +398,23 @@
}
TEST_F(EventThreadTest, postHotplugPrimaryDisconnect) {
- mThread->onHotplugReceived(DisplayDevice::DISPLAY_PRIMARY, false);
- expectHotplugEventReceivedByConnection(DisplayDevice::DISPLAY_PRIMARY, false);
+ mThread->onHotplugReceived(EventThread::DisplayType::Primary, false);
+ expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, false);
}
TEST_F(EventThreadTest, postHotplugPrimaryConnect) {
- mThread->onHotplugReceived(DisplayDevice::DISPLAY_PRIMARY, true);
- expectHotplugEventReceivedByConnection(DisplayDevice::DISPLAY_PRIMARY, true);
+ mThread->onHotplugReceived(EventThread::DisplayType::Primary, true);
+ expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, true);
}
TEST_F(EventThreadTest, postHotplugExternalDisconnect) {
- mThread->onHotplugReceived(DisplayDevice::DISPLAY_EXTERNAL, false);
- expectHotplugEventReceivedByConnection(DisplayDevice::DISPLAY_EXTERNAL, false);
+ mThread->onHotplugReceived(EventThread::DisplayType::External, false);
+ expectHotplugEventReceivedByConnection(EventThread::DisplayType::External, false);
}
TEST_F(EventThreadTest, postHotplugExternalConnect) {
- mThread->onHotplugReceived(DisplayDevice::DISPLAY_EXTERNAL, true);
- expectHotplugEventReceivedByConnection(DisplayDevice::DISPLAY_EXTERNAL, true);
-}
-
-TEST_F(EventThreadTest, postHotplugVirtualDisconnectIsFilteredOut) {
- mThread->onHotplugReceived(DisplayDevice::DISPLAY_VIRTUAL, false);
- EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
+ mThread->onHotplugReceived(EventThread::DisplayType::External, true);
+ expectHotplugEventReceivedByConnection(EventThread::DisplayType::External, true);
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 5dcac92..ae5a100 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -91,8 +91,9 @@
auto onInitializeDisplays() { return mFlinger->onInitializeDisplays(); }
- auto setPowerModeInternal(const sp<DisplayDevice>& hw, int mode, bool stateLockHeld = false) {
- return mFlinger->setPowerModeInternal(hw, mode, stateLockHeld);
+ auto setPowerModeInternal(const sp<DisplayDevice>& display, int mode,
+ bool stateLockHeld = false) {
+ return mFlinger->setPowerModeInternal(display, mode, stateLockHeld);
}
/* ------------------------------------------------------------------------
@@ -232,7 +233,7 @@
display->mutableIsConnected() = true;
ASSERT_TRUE(flinger->mutableHwcDisplayData().size() > static_cast<size_t>(mType));
- flinger->mutableHwcDisplayData()[mType].reset();
+ flinger->mutableHwcDisplayData()[mType] = HWComposer::DisplayData();
flinger->mutableHwcDisplayData()[mType].hwcDisplay = display.get();
flinger->mutableHwcDisplaySlots().emplace(mHwcDisplayId, mType);
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index e6ea663..df9bfc6 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -31,7 +31,7 @@
MOCK_CONST_METHOD0(createEventConnection, sp<BnDisplayEventConnection>());
MOCK_METHOD0(onScreenReleased, void());
MOCK_METHOD0(onScreenAcquired, void());
- MOCK_METHOD2(onHotplugReceived, void(int, bool));
+ MOCK_METHOD2(onHotplugReceived, void(DisplayType, bool));
MOCK_CONST_METHOD1(dump, void(String8&));
MOCK_METHOD1(setPhaseOffset, void(nsecs_t phaseOffset));
};
diff --git a/services/vr/performanced/directory_reader.h b/services/vr/performanced/directory_reader.h
index b9d27c3..f8359c4 100644
--- a/services/vr/performanced/directory_reader.h
+++ b/services/vr/performanced/directory_reader.h
@@ -16,10 +16,11 @@
class DirectoryReader {
public:
explicit DirectoryReader(base::unique_fd directory_fd) {
- directory_ = fdopendir(directory_fd.get());
+ int fd = directory_fd.release();
+ directory_ = fdopendir(fd);
error_ = errno;
- if (directory_ != nullptr)
- (void) directory_fd.release(); // ignore return result?
+ if (directory_ == nullptr)
+ close(fd);
}
~DirectoryReader() {