Revert "Revert "Tie vr flinger to persistent vr mode""
This reverts commit 7480c060cb3466d97ec3125d61bbace153f534c8.
Transfer display control to vr flinger when persistent vr mode is
entered, rather than when vr mode is entered. This allows cardboard
apps, which will invoke vr mode but not persistent vr mode, to work as
in N.
This activates vr flinger at device boot for Daydream ready devices,
which fixes an issue where an app would attempt to create a surface
before vr flinger was running, which would hang indefinitely.
The VrManager listener for persistent vr mode is put in vr flinger
instead of surface flinger. This is cleaner since the vr interaction
with the rest of the device is now consolidated in vr flinger.
While testing I encountered a problem where vr flinger was given control
of the display but vsync was turned off, causing vr flinger's post
thread to hang. I changed the vr flinger logic to give control over
vsync and other display settings to the post thread, and took the
opportunity to further simplify and improve vr flinger's thread
interactions.
Bug: 35885165
Test: Manually confirmed that when persistent vr mode is not invoked we
get the N-based render implementation, and when persistent vr mode is
invoked we get vr flinger.
Change-Id: I3b5ad599cc0748e38b861c714c4cc3118f854acf
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 06dd903..0aaab0c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -73,7 +73,6 @@
#include "LayerDim.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
-#include "VrStateCallbacks.h"
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/HWComposer.h"
@@ -118,6 +117,7 @@
bool SurfaceFlinger::useHwcForRgbToYuv;
uint64_t SurfaceFlinger::maxVirtualDisplaySize;
bool SurfaceFlinger::hasSyncFramework;
+bool SurfaceFlinger::useVrFlinger;
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(),
@@ -136,7 +136,6 @@
mVisibleRegionsDirty(false),
mGeometryInvalid(false),
mAnimCompositionPending(false),
- mVrModeSupported(0),
mDebugRegion(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
@@ -156,10 +155,8 @@
mFrameBuckets(),
mTotalTime(0),
mLastSwapTime(0),
- mNumLayers(0)
-#ifdef USE_HWC2
- ,mEnterVrMode(false)
-#endif
+ mNumLayers(0),
+ mVrFlingerRequestsDisplay(false)
{
ALOGI("SurfaceFlinger is starting");
@@ -184,13 +181,13 @@
maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);
+ // Vr flinger is only enabled on Daydream ready devices.
+ useVrFlinger = getBool< ISurfaceFlingerConfigs,
+ &ISurfaceFlingerConfigs::useVrFlinger>(false);
+
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
- // TODO (urbanus): remove once b/35319396 is fixed.
- property_get("ro.boot.vr", value, "0");
- mVrModeSupported = atoi(value);
-
property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
mGpuToCpuSupported = !atoi(value);
@@ -231,14 +228,6 @@
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglTerminate(display);
-
- if (mVrStateCallbacks.get()) {
- sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
- defaultServiceManager()->checkService(String16("vrmanager")));
- if (vrManagerService.get()) {
- vrManagerService->unregisterListener(mVrStateCallbacks);
- }
- }
}
void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
@@ -365,6 +354,10 @@
window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
}
+ if (mVrFlinger) {
+ mVrFlinger->OnBootFinished();
+ }
+
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
@@ -373,13 +366,6 @@
const int LOGTAG_SF_STOP_BOOTANIM = 60110;
LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
-
- sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
- defaultServiceManager()->checkService(String16("vrmanager")));
- if (vrManagerService.get()) {
- mVrStateCallbacks = new VrStateCallbacks(*this);
- vrManagerService->registerListener(mVrStateCallbacks);
- }
}
void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
@@ -575,13 +561,26 @@
// Drop the state lock while we initialize the hardware composer. We drop
// the lock because on creation, it will call back into SurfaceFlinger to
// initialize the primary display.
- LOG_ALWAYS_FATAL_IF(mEnterVrMode, "Starting in vr mode is not currently supported.");
+ LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
+ "Starting with vr flinger active is not currently supported.");
mRealHwc = new HWComposer(false);
mHwc = mRealHwc;
mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
Mutex::Autolock _l(mStateLock);
+ if (useVrFlinger) {
+ auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
+ mVrFlingerRequestsDisplay = requestDisplay;
+ signalTransaction();
+ };
+ mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
+ vrFlingerRequestDisplayCallback);
+ if (!mVrFlinger) {
+ ALOGE("Failed to start vrflinger");
+ }
+ }
+
// retrieve the EGL context that was selected/created
mEGLContext = mRenderEngine->getEGLContext();
@@ -1213,14 +1212,17 @@
// transition.
mDrawingState.displays.clear();
mDisplays.clear();
+ initializeDisplays();
}
-void SurfaceFlinger::updateVrMode() {
- bool enteringVrMode = mEnterVrMode;
- if (enteringVrMode == mHwc->isUsingVrComposer()) {
+void SurfaceFlinger::updateVrFlinger() {
+ if (!mVrFlinger)
+ return;
+ bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay;
+ if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
return;
}
- if (enteringVrMode && !mVrHwc) {
+ if (vrFlingerRequestsDisplay && !mVrHwc) {
// Construct new HWComposer without holding any locks.
mVrHwc = new HWComposer(true);
ALOGV("Vr HWC created");
@@ -1228,25 +1230,13 @@
{
Mutex::Autolock _l(mStateLock);
- if (enteringVrMode) {
- // Start vrflinger thread, if it hasn't been started already.
- if (!mVrFlinger) {
- mVrFlinger = std::make_unique<dvr::VrFlinger>();
- int err = mVrFlinger->Run(mHwc->getComposer());
- if (err != NO_ERROR) {
- ALOGE("Failed to run vrflinger: %s (%d)", strerror(-err), err);
- mVrFlinger.reset();
- mEnterVrMode = false;
- return;
- }
- }
-
+ if (vrFlingerRequestsDisplay) {
resetHwc();
mHwc = mVrHwc;
- mVrFlinger->EnterVrMode();
+ mVrFlinger->GrantDisplayOwnership();
} else {
- mVrFlinger->ExitVrMode();
+ mVrFlinger->SeizeDisplayOwnership();
resetHwc();
@@ -1268,12 +1258,6 @@
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
- // TODO(eieio): Tied to a conditional until SELinux issues
- // are resolved.
- if (mVrModeSupported) {
- updateVrMode();
- }
-
bool frameMissed = !mHadClientComposition &&
mPreviousPresentFence != Fence::NO_FENCE &&
(mPreviousPresentFence->getSignalTime() ==
@@ -1285,6 +1269,11 @@
break;
}
+ // Now that we're going to make it to the handleMessageTransaction()
+ // call below it's safe to call updateVrFlinger(), which will
+ // potentially trigger a display handoff.
+ updateVrFlinger();
+
bool refreshNeeded = handleMessageTransaction();
refreshNeeded |= handleMessageInvalidate();
refreshNeeded |= mRepaintEverything;