Merge changes I5a8bb16f,I4555ba9d,Id1e3dd5e
* changes:
vulkan: Temporarily hack around loader/driver mismatch
vulkan: Add gralloc1 usage to VK_ANDROID_native_buffer
vulkan: Tolerate missing GetSwapchainGrallocUsageANDROID function
diff --git a/aidl/gui/android/view/Surface.aidl b/aidl/gui/android/view/Surface.aidl
index 674c163..7e89220 100644
--- a/aidl/gui/android/view/Surface.aidl
+++ b/aidl/gui/android/view/Surface.aidl
@@ -17,4 +17,4 @@
package android.view;
-parcelable Surface cpp_header "gui/Surface.h";
+parcelable Surface cpp_header "gui/view/Surface.h";
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 60203f7..c3014b2 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -17,8 +17,6 @@
#ifndef ANDROID_GUI_SURFACE_H
#define ANDROID_GUI_SURFACE_H
-#include <binder/Parcelable.h>
-
#include <gui/IGraphicBufferProducer.h>
#include <gui/BufferQueueDefs.h>
@@ -410,43 +408,6 @@
std::unique_ptr<ProducerFrameEventHistory> mFrameEventHistory;
};
-namespace view {
-
-/**
- * A simple holder for an IGraphicBufferProducer, to match the managed-side
- * android.view.Surface parcelable behavior.
- *
- * This implements android/view/Surface.aidl
- *
- * TODO: Convert IGraphicBufferProducer into AIDL so that it can be directly
- * used in managed Binder calls.
- */
-class Surface : public Parcelable {
- public:
-
- String16 name;
- sp<IGraphicBufferProducer> graphicBufferProducer;
-
- virtual status_t writeToParcel(Parcel* parcel) const override;
- virtual status_t readFromParcel(const Parcel* parcel) override;
-
- // nameAlreadyWritten set to true by Surface.java, because it splits
- // Parceling itself between managed and native code, so it only wants a part
- // of the full parceling to happen on its native side.
- status_t writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const;
-
- // nameAlreadyRead set to true by Surface.java, because it splits
- // Parceling itself between managed and native code, so it only wants a part
- // of the full parceling to happen on its native side.
- status_t readFromParcel(const Parcel* parcel, bool nameAlreadyRead);
-
- private:
-
- static String16 readMaybeEmptyString16(const Parcel* parcel);
-};
-
-} // namespace view
-
-}; // namespace android
+} // namespace android
#endif // ANDROID_GUI_SURFACE_H
diff --git a/include/gui/view/Surface.h b/include/gui/view/Surface.h
new file mode 100644
index 0000000..cc64fd4
--- /dev/null
+++ b/include/gui/view/Surface.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 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_GUI_VIEW_SURFACE_H
+#define ANDROID_GUI_VIEW_SURFACE_H
+
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/String16.h>
+
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class IGraphicBufferProducer;
+
+namespace view {
+
+/**
+ * A simple holder for an IGraphicBufferProducer, to match the managed-side
+ * android.view.Surface parcelable behavior.
+ *
+ * This implements android/view/Surface.aidl
+ *
+ * TODO: Convert IGraphicBufferProducer into AIDL so that it can be directly
+ * used in managed Binder calls.
+ */
+class Surface : public Parcelable {
+ public:
+
+ String16 name;
+ sp<IGraphicBufferProducer> graphicBufferProducer;
+
+ virtual status_t writeToParcel(Parcel* parcel) const override;
+ virtual status_t readFromParcel(const Parcel* parcel) override;
+
+ // nameAlreadyWritten set to true by Surface.java, because it splits
+ // Parceling itself between managed and native code, so it only wants a part
+ // of the full parceling to happen on its native side.
+ status_t writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const;
+
+ // nameAlreadyRead set to true by Surface.java, because it splits
+ // Parceling itself between managed and native code, so it only wants a part
+ // of the full parceling to happen on its native side.
+ status_t readFromParcel(const Parcel* parcel, bool nameAlreadyRead);
+
+ private:
+
+ static String16 readMaybeEmptyString16(const Parcel* parcel);
+};
+
+} // namespace view
+} // namespace android
+
+#endif // ANDROID_GUI_VIEW_SURFACE_H
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index cb17da4..ddf1072 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -96,6 +96,7 @@
"SurfaceControl.cpp",
"SurfaceComposerClient.cpp",
"SyncFeatures.cpp",
+ "view/Surface.cpp",
],
shared_libs: [
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index c663620..72fa843 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -18,9 +18,9 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
-#include <android/native_window.h>
+#include <gui/Surface.h>
-#include <binder/Parcel.h>
+#include <android/native_window.h>
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -32,7 +32,6 @@
#include <gui/BufferItem.h>
#include <gui/IProducerListener.h>
-#include <gui/Surface.h>
#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
@@ -1539,74 +1538,4 @@
return mGraphicBufferProducer->getUniqueId(outId);
}
-namespace view {
-
-status_t Surface::writeToParcel(Parcel* parcel) const {
- return writeToParcel(parcel, false);
-}
-
-status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
- if (parcel == nullptr) return BAD_VALUE;
-
- status_t res = OK;
-
- if (!nameAlreadyWritten) {
- res = parcel->writeString16(name);
- if (res != OK) return res;
-
- /* isSingleBuffered defaults to no */
- res = parcel->writeInt32(0);
- if (res != OK) return res;
- }
-
- res = parcel->writeStrongBinder(
- IGraphicBufferProducer::asBinder(graphicBufferProducer));
-
- return res;
-}
-
-status_t Surface::readFromParcel(const Parcel* parcel) {
- return readFromParcel(parcel, false);
-}
-
-status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
- if (parcel == nullptr) return BAD_VALUE;
-
- status_t res = OK;
- if (!nameAlreadyRead) {
- name = readMaybeEmptyString16(parcel);
- // Discard this for now
- int isSingleBuffered;
- res = parcel->readInt32(&isSingleBuffered);
- if (res != OK) {
- ALOGE("Can't read isSingleBuffered");
- return res;
- }
- }
-
- sp<IBinder> binder;
-
- res = parcel->readNullableStrongBinder(&binder);
- if (res != OK) {
- ALOGE("%s: Can't read strong binder", __FUNCTION__);
- return res;
- }
-
- graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
-
- return OK;
-}
-
-String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
- size_t len;
- const char16_t* str = parcel->readString16Inplace(&len);
- if (str != nullptr) {
- return String16(str, len);
- } else {
- return String16();
- }
-}
-
-} // namespace view
-
}; // namespace android
diff --git a/libs/gui/view/Surface.cpp b/libs/gui/view/Surface.cpp
new file mode 100644
index 0000000..5ed3d3b
--- /dev/null
+++ b/libs/gui/view/Surface.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "Surface"
+
+#include <gui/view/Surface.h>
+
+#include <binder/Parcel.h>
+
+#include <utils/Log.h>
+
+#include <gui/IGraphicBufferProducer.h>
+
+namespace android {
+namespace view {
+
+status_t Surface::writeToParcel(Parcel* parcel) const {
+ return writeToParcel(parcel, false);
+}
+
+status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
+ if (parcel == nullptr) return BAD_VALUE;
+
+ status_t res = OK;
+
+ if (!nameAlreadyWritten) {
+ res = parcel->writeString16(name);
+ if (res != OK) return res;
+
+ /* isSingleBuffered defaults to no */
+ res = parcel->writeInt32(0);
+ if (res != OK) return res;
+ }
+
+ res = parcel->writeStrongBinder(
+ IGraphicBufferProducer::asBinder(graphicBufferProducer));
+
+ return res;
+}
+
+status_t Surface::readFromParcel(const Parcel* parcel) {
+ return readFromParcel(parcel, false);
+}
+
+status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
+ if (parcel == nullptr) return BAD_VALUE;
+
+ status_t res = OK;
+ if (!nameAlreadyRead) {
+ name = readMaybeEmptyString16(parcel);
+ // Discard this for now
+ int isSingleBuffered;
+ res = parcel->readInt32(&isSingleBuffered);
+ if (res != OK) {
+ ALOGE("Can't read isSingleBuffered");
+ return res;
+ }
+ }
+
+ sp<IBinder> binder;
+
+ res = parcel->readNullableStrongBinder(&binder);
+ if (res != OK) {
+ ALOGE("%s: Can't read strong binder", __FUNCTION__);
+ return res;
+ }
+
+ graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
+
+ return OK;
+}
+
+String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
+ size_t len;
+ const char16_t* str = parcel->readString16Inplace(&len);
+ if (str != nullptr) {
+ return String16(str, len);
+ } else {
+ return String16();
+ }
+}
+
+} // namespace view
+} // namespace android
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 0e05d54..aa8f189 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -49,14 +49,11 @@
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-ifeq ($(TARGET_IN_VR_MODE),true)
- LOCAL_CFLAGS += -DIN_VR_MODE
-endif
-
ifeq ($(TARGET_USES_HWC2),true)
LOCAL_CFLAGS += -DUSE_HWC2
LOCAL_SRC_FILES += \
SurfaceFlinger.cpp \
+ VrStateCallbacks.cpp \
DisplayHardware/HWComposer.cpp
ifeq ($(TARGET_USES_HWC2ON1ADAPTER), true)
LOCAL_CFLAGS += -DBYPASS_IHWC
@@ -134,7 +131,13 @@
LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
-LOCAL_STATIC_LIBRARIES := libhwcomposer-command-buffer libtrace_proto libvkjson
+LOCAL_STATIC_LIBRARIES := \
+ libhwcomposer-command-buffer \
+ libtrace_proto \
+ libvkjson \
+ libvr_manager \
+ libvrflinger
+
LOCAL_SHARED_LIBRARIES := \
android.dvr.composer@1.0 \
android.hardware.graphics.allocator@2.0 \
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 6cb1af1..3e9ef24 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -124,13 +124,11 @@
endCommand();
}
-Composer::Composer() : mWriter(kWriterInitialSize)
+Composer::Composer(bool useVrComposer)
+ : mWriter(kWriterInitialSize),
+ mIsUsingVrComposer(useVrComposer)
{
-#if defined(IN_VR_MODE)
- mIsInVrMode = true;
-#endif
-
- if (mIsInVrMode) {
+ if (mIsUsingVrComposer) {
mComposer = IComposer::getService("vr_hwcomposer");
} else {
mComposer = IComposer::getService("hwcomposer");
@@ -622,8 +620,7 @@
Error Composer::setLayerInfo(Display display, Layer layer, uint32_t type,
uint32_t appId)
{
- if (mIsInVrMode)
- {
+ if (mIsUsingVrComposer) {
mWriter.selectDisplay(display);
mWriter.selectLayer(layer);
mWriter.setLayerInfo(type, appId);
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 1ede705..18af9dd 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -26,7 +26,6 @@
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <utils/StrongPointer.h>
#include <IComposerCommandBuffer.h>
-#include <MessageQueue.h>
namespace android {
@@ -128,7 +127,7 @@
// Composer is a wrapper to IComposer, a proxy to server-side composer.
class Composer {
public:
- Composer();
+ Composer(bool useVrComposer);
std::vector<IComposer::Capability> getCapabilities();
std::string dumpDebugInfo();
@@ -136,6 +135,7 @@
void registerCallback(const sp<IComposerCallback>& callback);
uint32_t getMaxVirtualDisplayCount();
+ bool isUsingVrComposer() const { return mIsUsingVrComposer; }
Error createVirtualDisplay(uint32_t width, uint32_t height,
PixelFormat* format, Display* outDisplay);
Error destroyVirtualDisplay(Display display);
@@ -248,7 +248,9 @@
CommandWriter mWriter;
CommandReader mReader;
- bool mIsInVrMode = false;
+ // When true, the we attach to the vr_hwcomposer service instead of the
+ // hwcomposer. This allows us to redirect surfaces to 3d surfaces in vr.
+ const bool mIsUsingVrComposer;
};
} // namespace Hwc2
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 99a6d71..a25e8a1 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -135,8 +135,8 @@
mSetLayerVisibleRegion(nullptr),
mSetLayerZOrder(nullptr),
#else
-Device::Device()
- : mComposer(std::make_unique<Hwc2::Composer>()),
+Device::Device(bool useVrComposer)
+ : mComposer(std::make_unique<Hwc2::Composer>(useVrComposer)),
#endif // BYPASS_IHWC
mCapabilities(),
mDisplays(),
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index d770f22..93eb999 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -67,7 +67,10 @@
#ifdef BYPASS_IHWC
explicit Device(hwc2_device_t* device);
#else
- Device();
+ // useVrComposer is passed to the composer HAL. When true, the composer HAL
+ // will use the vr composer service, otherwise it uses the real hardware
+ // composer.
+ Device(bool useVrComposer);
#endif
~Device();
@@ -106,6 +109,12 @@
bool hasCapability(HWC2::Capability capability) const;
+#ifdef BYPASS_IHWC
+ android::Hwc2::Composer* getComposer() { return nullptr; }
+#else
+ android::Hwc2::Composer* getComposer() { return mComposer.get(); }
+#endif
+
private:
// Initialization methods
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index e86a071..1c99036 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -49,6 +49,7 @@
#include "HWComposer.h"
#include "HWC2On1Adapter.h"
#include "HWC2.h"
+#include "ComposerHal.h"
#include "../Layer.h" // needed only for debugging
#include "../SurfaceFlinger.h"
@@ -59,7 +60,7 @@
// ---------------------------------------------------------------------------
-HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
+HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger, bool useVrComposer)
: mFlinger(flinger),
mAdapter(),
mHwcDevice(),
@@ -76,7 +77,7 @@
mVSyncCounts[i] = 0;
}
- loadHwcModule();
+ loadHwcModule(useVrComposer);
}
HWComposer::~HWComposer() {}
@@ -105,11 +106,13 @@
}
// Load and prepare the hardware composer module. Sets mHwc.
-void HWComposer::loadHwcModule()
+void HWComposer::loadHwcModule(bool useVrComposer)
{
ALOGV("loadHwcModule");
#ifdef BYPASS_IHWC
+ (void)useVrComposer; // Silence unused parameter warning.
+
hw_module_t const* module;
if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
@@ -142,7 +145,7 @@
static_cast<hwc2_device_t*>(mAdapter.get()));
}
#else
- mHwcDevice = std::make_unique<HWC2::Device>();
+ mHwcDevice = std::make_unique<HWC2::Device>(useVrComposer);
#endif
mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
@@ -867,6 +870,14 @@
}
*/
+bool HWComposer::isUsingVrComposer() const {
+#ifdef BYPASS_IHWC
+ return false;
+#else
+ return getComposer()->isUsingVrComposer();
+#endif
+}
+
void HWComposer::dump(String8& result) const {
// TODO: In order to provide a dump equivalent to HWC1, we need to shadow
// all the state going into the layers. This is probably better done in
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 37f12e4..7b61e0e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -77,7 +77,10 @@
virtual ~EventHandler() {}
};
- HWComposer(const sp<SurfaceFlinger>& flinger);
+ // useVrComposer is passed to the composer HAL. When true, the composer HAL
+ // will use the vr composer service, otherwise it uses the real hardware
+ // composer.
+ HWComposer(const sp<SurfaceFlinger>& flinger, bool useVrComposer);
~HWComposer();
@@ -165,13 +168,16 @@
status_t setActiveColorMode(int32_t displayId, android_color_mode_t mode);
+ bool isUsingVrComposer() const;
+
// for debugging ----------------------------------------------------------
void dump(String8& out) const;
+ android::Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
private:
static const int32_t VIRTUAL_DISPLAY_ID_BASE = 2;
- void loadHwcModule();
+ void loadHwcModule(bool useVrComposer);
bool isValidDisplay(int32_t displayId) const;
static void validateChange(HWC2::Composition from, HWC2::Composition to);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3a9bca6..6e0a489 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -427,7 +427,9 @@
Rect bounds = win;
const auto& p = getParent();
if (p != nullptr) {
- bounds = p->computeScreenBounds();
+ // Look in computeScreenBounds recursive call for explanation of
+ // why we pass false here.
+ bounds = p->computeScreenBounds(false /* reduceTransparentRegion */);
}
Transform t = getTransform();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 76c710a..12166a8 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -413,6 +413,10 @@
}
}
+ void clearHwcLayers() {
+ mHwcLayers.clear();
+ }
+
#endif
// -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index de7795b..30bce55 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -36,6 +36,8 @@
#include <binder/MemoryHeapBase.h>
#include <binder/PermissionCache.h>
+#include <dvr/vr_flinger.h>
+
#include <ui/DisplayInfo.h>
#include <ui/DisplayStatInfo.h>
@@ -73,6 +75,7 @@
#include "LayerDim.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
+#include "VrStateCallbacks.h"
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/HWComposer.h"
@@ -155,7 +158,10 @@
mLayersRemoved(false),
mLayersAdded(false),
mRepaintEverything(0),
- mRenderEngine(NULL),
+ mHwc(nullptr),
+ mRealHwc(nullptr),
+ mVrHwc(nullptr),
+ mRenderEngine(nullptr),
mBootTime(systemTime()),
mBuiltinDisplays(),
mVisibleRegionsDirty(false),
@@ -180,7 +186,8 @@
mFrameBuckets(),
mTotalTime(0),
mLastSwapTime(0),
- mNumLayers(0)
+ mNumLayers(0),
+ mEnterVrMode(false)
{
ALOGI("SurfaceFlinger is starting");
@@ -208,12 +215,12 @@
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");
}
@@ -227,6 +234,14 @@
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 */)
@@ -361,6 +376,13 @@
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) {
@@ -556,7 +578,9 @@
// 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(this, false);
+ mHwc = mRealHwc;
mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
Mutex::Autolock _l(mStateLock);
@@ -1104,7 +1128,13 @@
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;
@@ -1139,10 +1169,79 @@
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(this, 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() == INT64_MAX;
@@ -1763,16 +1862,10 @@
"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));
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 55735b1..6dfdf08 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_SURFACE_FLINGER_H
#define ANDROID_SURFACE_FLINGER_H
+#include <memory>
#include <stdint.h>
#include <sys/types.h>
@@ -81,6 +82,11 @@
class EventControlThread;
class VSyncSource;
class InjectVSyncSource;
+class VrStateCallbacks;
+
+namespace dvr {
+class VrFlinger;
+} // namespace dvr
// ---------------------------------------------------------------------------
@@ -156,6 +162,7 @@
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.
@@ -460,6 +467,19 @@
bool isLayerTripleBufferingDisabled() const {
return this->mLayerTripleBufferingDisabled;
}
+
+#ifdef USE_HWC2
+ /* ------------------------------------------------------------------------
+ * VrFlinger
+ */
+ 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();
+#endif
+
/* ------------------------------------------------------------------------
* Attributes
*/
@@ -481,8 +501,13 @@
// access must be protected by mInvalidateLock
volatile int32_t mRepaintEverything;
- // constant members (no synchronization needed for access)
+ // current, real and vr hardware composers.
HWComposer* mHwc;
+#ifdef USE_HWC2
+ HWComposer* mRealHwc;
+ HWComposer* mVrHwc;
+#endif
+ // constant members (no synchronization needed for access)
RenderEngine* mRenderEngine;
nsecs_t mBootTime;
bool mGpuToCpuSupported;
@@ -495,6 +520,10 @@
EGLDisplay mEGLDisplay;
sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];
+#ifdef USE_HWC2
+ std::unique_ptr<dvr::VrFlinger> mVrFlinger;
+#endif
+
// Can only accessed from the main thread, these members
// don't need synchronization
State mDrawingState;
@@ -532,7 +561,7 @@
bool mPropagateBackpressure = true;
#endif
SurfaceInterceptor mInterceptor;
- bool mUseHwcVirtualDisplays = true;
+ bool mUseHwcVirtualDisplays = false;
// Restrict layers to use two buffers in their bufferqueues.
bool mLayerTripleBufferingDisabled = false;
@@ -601,6 +630,12 @@
// Verify that transaction is being called by an approved process:
// either AID_GRAPHICS or AID_SYSTEM.
status_t CheckTransactCodeCredentials(uint32_t code);
+
+#ifdef USE_HWC2
+ sp<VrStateCallbacks> mVrStateCallbacks;
+
+ std::atomic<bool> mEnterVrMode;
+#endif
};
}; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index fe9ba96..7e6eb03 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -188,12 +188,12 @@
ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
- 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");
}
diff --git a/services/surfaceflinger/VrStateCallbacks.cpp b/services/surfaceflinger/VrStateCallbacks.cpp
new file mode 100644
index 0000000..a924def
--- /dev/null
+++ b/services/surfaceflinger/VrStateCallbacks.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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
new file mode 100644
index 0000000..4e655d3
--- /dev/null
+++ b/services/surfaceflinger/VrStateCallbacks.h
@@ -0,0 +1,37 @@
+/*
+ * 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
diff --git a/services/vr/vr_window_manager/Android.mk b/services/vr/vr_window_manager/Android.mk
index 47d9dcc..85f8e1f 100644
--- a/services/vr/vr_window_manager/Android.mk
+++ b/services/vr/vr_window_manager/Android.mk
@@ -110,6 +110,7 @@
LOCAL_LDLIBS := -llog
LOCAL_MODULE := libvr_window_manager_jni
LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
LOCAL_MULTILIB := 64
LOCAL_CXX_STL := libc++_static
include $(BUILD_SHARED_LIBRARY)
@@ -126,6 +127,7 @@
LOCAL_LDLIBS := -llog
LOCAL_MODULE := vr_wm
LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
LOCAL_INIT_RC := vr_wm.rc
include $(BUILD_EXECUTABLE)
@@ -147,6 +149,7 @@
LOCAL_AAPT_FLAGS += --auto-add-overlay
LOCAL_AAPT_FLAGS += --extra-packages com.google.vr.cardboard
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
include $(BUILD_PACKAGE)