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/Android.mk b/services/surfaceflinger/Android.mk
index a6ea750..c87a8d9 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -53,7 +53,6 @@
LOCAL_CFLAGS += -DUSE_HWC2
LOCAL_SRC_FILES += \
SurfaceFlinger.cpp \
- VrStateCallbacks.cpp \
DisplayHardware/HWComposer.cpp
ifeq ($(TARGET_USES_HWC2ON1ADAPTER), true)
LOCAL_CFLAGS += -DBYPASS_IHWC
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;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 921ecf6..e3637f5 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -84,7 +84,6 @@
class EventControlThread;
class VSyncSource;
class InjectVSyncSource;
-class VrStateCallbacks;
namespace dvr {
class VrFlinger;
@@ -211,7 +210,6 @@
friend class EventThread;
friend class Layer;
friend class MonitoredProducer;
- friend class VrStateCallbacks;
// This value is specified in number of frames. Log frame stats at most
// every half hour.
@@ -532,9 +530,8 @@
void clearHwcLayers(const LayerVector& layers);
void resetHwc();
- // Check to see if we should change to or from vr mode, and if so, perform
- // the handoff.
- void updateVrMode();
+ // Check to see if we should handoff to vr flinger.
+ void updateVrFlinger();
#endif
/* ------------------------------------------------------------------------
@@ -604,7 +601,6 @@
DefaultKeyedVector< wp<IBinder>, sp<DisplayDevice> > mDisplays;
// don't use a lock for these, we don't care
- int mVrModeSupported;
int mDebugRegion;
int mDebugDDMS;
int mDebugDisableHWC;
@@ -701,9 +697,8 @@
status_t CheckTransactCodeCredentials(uint32_t code);
#ifdef USE_HWC2
- sp<VrStateCallbacks> mVrStateCallbacks;
-
- std::atomic<bool> mEnterVrMode;
+ std::atomic<bool> mVrFlingerRequestsDisplay;
+ static bool useVrFlinger;
#endif
};
}; // namespace android
diff --git a/services/surfaceflinger/VrStateCallbacks.cpp b/services/surfaceflinger/VrStateCallbacks.cpp
deleted file mode 100644
index a924def..0000000
--- a/services/surfaceflinger/VrStateCallbacks.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "VrStateCallbacks.h"
-#include "SurfaceFlinger.h"
-
-namespace android {
-
-VrStateCallbacks::VrStateCallbacks(SurfaceFlinger& flinger)
- : mFlinger(flinger) {}
-
-void VrStateCallbacks::onVrStateChanged(bool enabled) {
- mFlinger.mEnterVrMode = enabled;
- mFlinger.signalTransaction();
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/VrStateCallbacks.h b/services/surfaceflinger/VrStateCallbacks.h
deleted file mode 100644
index 4e655d3..0000000
--- a/services/surfaceflinger/VrStateCallbacks.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef ANDROID_VR_STATE_CALLBACKS_H
-#define ANDROID_VR_STATE_CALLBACKS_H
-
-#include <vr/vr_manager/vr_manager.h>
-
-namespace android {
-
-class SurfaceFlinger;
-
-class VrStateCallbacks : public BnVrStateCallbacks {
-public:
- VrStateCallbacks(SurfaceFlinger& flinger);
- void onVrStateChanged(bool enabled) override;
-
-private:
- SurfaceFlinger& mFlinger;
-};
-
-} // namespace android
-
-#endif // ANDROID_VR_STATE_CALLBACKS_H