#include <binder/MemoryHeapBase.h>
#include <binder/PermissionCache.h>
+#include <dvr/vr_flinger.h>
+
#include <ui/DisplayInfo.h>
#include <ui/DisplayStatInfo.h>
#include "LayerDim.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
+#include "VrStateCallbacks.h"
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/HWComposer.h"
mLayersRemoved(false),
mLayersAdded(false),
mRepaintEverything(0),
- mRenderEngine(NULL),
+ mHwc(nullptr),
+ mRealHwc(nullptr),
+ mVrHwc(nullptr),
+ mRenderEngine(nullptr),
mBootTime(systemTime()),
mBuiltinDisplays(),
mVisibleRegionsDirty(false),
mFrameBuckets(),
mTotalTime(0),
mLastSwapTime(0),
- mNumLayers(0)
+ mNumLayers(0),
+ mEnterVrMode(false)
{
ALOGI("SurfaceFlinger is starting");
mPropagateBackpressure = !atoi(value);
ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
- property_get("debug.sf.disable_hwc_vds", value, "0");
- mUseHwcVirtualDisplays = !atoi(value);
- ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
+ property_get("debug.sf.enable_hwc_vds", value, "0");
+ mUseHwcVirtualDisplays = atoi(value);
+ ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");
- property_get("ro.sf.disable_triple_buffer", value, "0");
- mLayerTripleBufferingDisabled = !atoi(value);
+ property_get("ro.sf.disable_triple_buffer", value, "1");
+ mLayerTripleBufferingDisabled = atoi(value);
ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
}
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 */)
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) {
// 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.
- mHwc = new HWComposer(this);
+ LOG_ALWAYS_FATAL_IF(mEnterVrMode, "Starting in vr mode is not currently supported.");
+ mRealHwc = new HWComposer(false);
+ mHwc = mRealHwc;
mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
Mutex::Autolock _l(mStateLock);
}
}
-void SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) {
+void SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type,
+ nsecs_t timestamp) {
+ Mutex::Autolock lock(mStateLock);
+ // Ignore any vsyncs from the non-active hardware composer.
+ if (composer != mHwc) {
+ return;
+ }
+
bool needsHwVsync = false;
{ // Scope for the lock
bool isSecure = true;
int32_t type = DisplayDevice::DISPLAY_PRIMARY;
- createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
+
+ // When we're using the vr composer, the assumption is that we've
+ // already created the IBinder object for the primary display.
+ if (!mHwc->isUsingVrComposer()) {
+ createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
+ }
+
wp<IBinder> token = mBuiltinDisplays[type];
sp<IGraphicBufferProducer> producer;
}
}
+void SurfaceFlinger::onInvalidateReceived(HWComposer* composer) {
+ Mutex::Autolock lock(mStateLock);
+ if (composer == mHwc) {
+ repaintEverything();
+ } else {
+ // This isn't from our current hardware composer. If it's a callback
+ // from the real composer, forward the refresh request to vr
+ // flinger. Otherwise ignore it.
+ if (!composer->isUsingVrComposer()) {
+ mVrFlinger->OnHardwareComposerRefresh();
+ }
+ }
+}
+
void SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
ATRACE_CALL();
getHwComposer().setVsyncEnabled(disp,
enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
}
+void SurfaceFlinger::clearHwcLayers(const LayerVector& layers) {
+ for (size_t i = 0; i < layers.size(); ++i) {
+ layers[i]->clearHwcLayers();
+ }
+}
+
+void SurfaceFlinger::resetHwc() {
+ disableHardwareVsync(true);
+ clearHwcLayers(mDrawingState.layersSortedByZ);
+ clearHwcLayers(mCurrentState.layersSortedByZ);
+ // Clear the drawing state so that the logic inside of
+ // handleTransactionLocked will fire. It will determine the delta between
+ // mCurrentState and mDrawingState and re-apply all changes when we make the
+ // transition.
+ mDrawingState.displays.clear();
+ mDisplays.clear();
+}
+
+void SurfaceFlinger::updateVrMode() {
+ {
+ Mutex::Autolock _l(mStateLock);
+ bool enteringVrMode = mEnterVrMode;
+ if (enteringVrMode == mHwc->isUsingVrComposer()) {
+ return;
+ }
+
+ 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 (!mVrHwc) {
+ mVrHwc = new HWComposer(true);
+ ALOGV("Vr HWC created");
+ }
+
+ resetHwc();
+
+ mHwc = mVrHwc;
+ mVrFlinger->EnterVrMode();
+ } else {
+ mVrFlinger->ExitVrMode();
+
+ resetHwc();
+
+ mHwc = mRealHwc;
+ enableHardwareVsync();
+ }
+
+ mVisibleRegionsDirty = true;
+ invalidateHwcGeometry();
+ android_atomic_or(1, &mRepaintEverything);
+ setTransactionFlags(eDisplayTransactionNeeded);
+ }
+ if (mVrHwc) {
+ mVrHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
+ }
+}
+
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
+ updateVrMode();
+
bool frameMissed = !mHadClientComposition &&
mPreviousPresentFence != Fence::NO_FENCE &&
(mPreviousPresentFence->getSignalTime() ==
"adding a supported display, but rendering "
"surface is provided (%p), ignoring it",
state.surface.get());
- if (state.type == DisplayDevice::DISPLAY_EXTERNAL) {
- hwcId = DisplayDevice::DISPLAY_EXTERNAL;
- dispSurface = new FramebufferSurface(*mHwc,
- DisplayDevice::DISPLAY_EXTERNAL,
- bqConsumer);
- producer = bqProducer;
- } else {
- ALOGE("Attempted to add non-external non-virtual"
- " display");
- }
+
+ hwcId = state.type;
+ dispSurface = new FramebufferSurface(*mHwc, hwcId, bqConsumer);
+ producer = bqProducer;
}
const wp<IBinder>& display(curr.keyAt(i));
switch (layer->getCompositionType(hwcId)) {
case HWC2::Composition::Cursor:
case HWC2::Composition::Device:
+ case HWC2::Composition::Sideband:
case HWC2::Composition::SolidColor: {
const Layer::State& state(layer->getDrawingState());
if (layer->getClearClientTarget(hwcId) && !firstLayer &&