OSDN Git Service

Merge "EGL: Add eglGetCompositorTimingANDROID."
authorBrian C. Anderson <brianderson@google.com>
Wed, 15 Feb 2017 22:32:45 +0000 (22:32 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Wed, 15 Feb 2017 22:32:47 +0000 (22:32 +0000)
158 files changed:
aidl/gui/android/view/Surface.aidl
cmds/atrace/Android.bp
cmds/atrace/atrace.cpp
cmds/dumpstate/Android.mk
cmds/dumpstate/dumpstate.cpp
cmds/dumpstate/dumpstate.h
cmds/dumpstate/utils.cpp
cmds/dumpsys/Android.bp
cmds/dumpsys/dumpsys.cpp
cmds/dumpsys/dumpsys.h
cmds/dumpsys/main.cpp
cmds/dumpsys/tests/Android.bp
cmds/dumpsys/tests/dumpsys_test.cpp
cmds/lshal/lshal.cpp
data/etc/android.hardware.vulkan.compute-0.xml [new file with mode: 0644]
include/android/bitmap.h
include/audiomanager/IPlayer.h
include/batteryservice/BatteryService.h
include/binder/ProcessInfoService.h
include/gui/BufferItem.h
include/gui/GLConsumer.h
include/gui/GraphicBufferAlloc.h
include/gui/IGraphicBufferAlloc.h
include/gui/ISurfaceComposer.h
include/gui/Surface.h
include/gui/view/Surface.h [new file with mode: 0644]
include/private/gui/ComposerService.h
include/ui/Gralloc1.h
include/ui/Gralloc1On0Adapter.h
include/ui/GrallocMapper.h
include/ui/GraphicBuffer.h
include/ui/GraphicBufferAllocator.h
include/ui/GraphicBufferMapper.h
include/ui/GraphicsEnv.h [moved from include/gui/GraphicsEnv.h with 94% similarity]
include/ui/HdrCapabilities.h
libs/binder/ProcessInfoService.cpp
libs/binder/ProcessState.cpp
libs/gui/Android.bp
libs/gui/GLConsumer.cpp
libs/gui/GraphicBufferAlloc.cpp
libs/gui/IGraphicBufferAlloc.cpp
libs/gui/ISurfaceComposer.cpp
libs/gui/Sensor.cpp
libs/gui/SensorManager.cpp
libs/gui/Surface.cpp
libs/gui/view/Surface.cpp [new file with mode: 0644]
libs/ui/Android.bp
libs/ui/Gralloc1.cpp
libs/ui/GrallocMapper.cpp
libs/ui/GraphicBuffer.cpp
libs/ui/GraphicBufferAllocator.cpp
libs/ui/GraphicBufferMapper.cpp
libs/ui/GraphicsEnv.cpp [moved from libs/gui/GraphicsEnv.cpp with 98% similarity]
libs/ui/HdrCapabilities.cpp
libs/vr/libdisplay/include/private/dvr/display_rpc.h
libs/vr/libdisplay/vsync_client.cpp
libs/vr/libeds/distortion_renderer.cpp
libs/vr/libgvr/Android.mk
libs/vr/libgvr/java/com/google/vr/gvr/platform/Loader.java
libs/vr/libgvr/prebuilt/lib/android_arm/libgvr.so
libs/vr/libgvr/prebuilt/lib/android_arm/libgvr_audio.so
libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr.so
libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr_audio.so
libs/vr/libgvr/prebuilt/lib/android_x86/libgvr.so
libs/vr/libgvr/prebuilt/lib/android_x86/libgvr_audio.so
libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr.so
libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr_audio.so
libs/vr/libgvr/prebuilt/lib/common_library.aar
libs/vr/libgvr/shim_gvr.cpp
libs/vr/libsensor/include/private/dvr/pose-ipc.h
libs/vr/libsensor/include/private/dvr/sensor-ipc.h
libs/vr/libvr_manager/Android.mk [moved from services/vr/vr_manager/Android.mk with 79% similarity]
libs/vr/libvr_manager/include/private/dvr/trusted_uids.h [new file with mode: 0644]
libs/vr/libvr_manager/trusted_uids.cpp [new file with mode: 0644]
libs/vr/libvr_manager/vr_manager.cpp [moved from services/vr/vr_manager/vr_manager.cpp with 100% similarity]
libs/vr/libvrflinger/Android.mk
libs/vr/libvrflinger/display_service.cpp
libs/vr/libvrflinger/display_service.h
libs/vr/libvrflinger/display_surface.cpp
libs/vr/libvrflinger/hardware_composer.cpp
libs/vr/libvrflinger/hardware_composer.h
libs/vr/libvrflinger/include/dvr/vr_flinger.h
libs/vr/libvrflinger/screenshot_service.cpp
libs/vr/libvrflinger/vr_flinger.cpp
opengl/libs/Android.bp
opengl/libs/Android.mk
opengl/libs/EGL/Loader.cpp
opengl/libs/EGL/Loader.h
opengl/libs/EGL/eglApi.cpp
opengl/tests/EGLTest/EGL_test.cpp
services/audiomanager/IPlayer.cpp
services/sensorservice/Android.mk
services/sensorservice/SensorDevice.cpp
services/sensorservice/SensorDevice.h
services/sensorservice/SensorDeviceTreble.cpp [deleted file]
services/sensorservice/SensorDirectConnection.cpp
services/sensorservice/SensorServiceUtils.cpp
services/surfaceflinger/Android.mk
services/surfaceflinger/DisplayHardware/ComposerHal.cpp
services/surfaceflinger/DisplayHardware/ComposerHal.h
services/surfaceflinger/DisplayHardware/DisplaySurface.h
services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
services/surfaceflinger/DisplayHardware/FramebufferSurface.h
services/surfaceflinger/DisplayHardware/HWC2.cpp
services/surfaceflinger/DisplayHardware/HWC2.h
services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
services/surfaceflinger/DisplayHardware/HWComposer.cpp
services/surfaceflinger/DisplayHardware/HWComposer.h
services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
services/surfaceflinger/Layer.cpp
services/surfaceflinger/Layer.h
services/surfaceflinger/SurfaceFlinger.cpp
services/surfaceflinger/SurfaceFlinger.h
services/surfaceflinger/SurfaceFlingerConsumer.cpp
services/surfaceflinger/SurfaceFlingerConsumer.h
services/surfaceflinger/SurfaceFlinger_hwc1.cpp
services/surfaceflinger/VrStateCallbacks.cpp [new file with mode: 0644]
services/surfaceflinger/VrStateCallbacks.h [new file with mode: 0644]
services/vr/sensord/Android.mk
services/vr/vr_window_manager/Android.mk [moved from services/vr/vr_window_manager/Android.mk_disable with 75% similarity]
services/vr/vr_window_manager/AndroidManifest.xml
services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl [new file with mode: 0644]
services/vr/vr_window_manager/application.cpp
services/vr/vr_window_manager/application.h
services/vr/vr_window_manager/composer/Android.bp
services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
services/vr/vr_window_manager/composer/impl/vr_hwc.h
services/vr/vr_window_manager/controller_data_provider.h [new file with mode: 0644]
services/vr/vr_window_manager/hwc_callback.cpp
services/vr/vr_window_manager/render_thread.cpp
services/vr/vr_window_manager/shell_view.cpp
services/vr/vr_window_manager/shell_view.h
services/vr/vr_window_manager/shell_view_binder_interface.h [new file with mode: 0644]
services/vr/vr_window_manager/surface_flinger_view.cpp
services/vr/vr_window_manager/surface_flinger_view.h
services/vr/vr_window_manager/vr_window_manager.cpp
services/vr/vr_window_manager/vr_window_manager_binder.cpp [new file with mode: 0644]
services/vr/vr_window_manager/vr_window_manager_binder.h [new file with mode: 0644]
services/vr/vr_window_manager/vr_window_manager_binder_test.cpp [new file with mode: 0644]
services/vr/vr_window_manager/vr_wm_ctl.cpp [new file with mode: 0644]
vulkan/api/vulkan.api
vulkan/doc/implementors_guide/implementors_guide.adoc
vulkan/doc/implementors_guide/implementors_guide.html
vulkan/include/vulkan/vk_android_native_buffer.h
vulkan/libvulkan/Android.bp
vulkan/libvulkan/code-generator.tmpl
vulkan/libvulkan/debug_report.cpp
vulkan/libvulkan/driver.cpp
vulkan/libvulkan/driver.h
vulkan/libvulkan/driver_gen.cpp
vulkan/libvulkan/driver_gen.h
vulkan/libvulkan/swapchain.cpp
vulkan/nulldrv/null_driver.cpp
vulkan/nulldrv/null_driver_gen.h

index 674c163..7e89220 100644 (file)
@@ -17,4 +17,4 @@
 
 package android.view;
 
-parcelable Surface cpp_header "gui/Surface.h";
+parcelable Surface cpp_header "gui/view/Surface.h";
index 69ed416..225de20 100644 (file)
@@ -16,6 +16,9 @@ cc_binary {
         "libz",
         "libbase",
     ],
+    static_libs: [
+        "libpdx_default_transport",
+    ],
 
     init_rc: ["atrace.rc"],
 }
index 4be0432..ce0caed 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <ftw.h>
 #include <getopt.h>
 #include <inttypes.h>
 #include <signal.h>
@@ -41,6 +42,7 @@
 #include <hidl/ServiceManagement.h>
 #include <cutils/properties.h>
 
+#include <pdx/default_transport/service_utility.h>
 #include <utils/String8.h>
 #include <utils/Timers.h>
 #include <utils/Tokenizer.h>
@@ -48,6 +50,7 @@
 #include <android-base/file.h>
 
 using namespace android;
+using pdx::default_transport::ServiceUtility;
 
 using std::string;
 #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
@@ -569,6 +572,46 @@ static void pokeHalServices()
     }
 }
 
+// Sends the sysprop_change message to the service at fpath, so it re-reads its
+// system properties. Returns 0 on success or a negated errno code on failure.
+static int pokeOnePDXService(const char *fpath, const struct stat * /*sb*/,
+                             int typeflag, struct FTW * /*ftwbuf*/)
+{
+    const bool kIgnoreErrors = true;
+
+    if (typeflag == FTW_F) {
+        int error;
+        auto utility = ServiceUtility::Create(fpath, &error);
+        if (!utility) {
+            if (error != -ECONNREFUSED) {
+                ALOGE("pokeOnePDXService: Failed to open %s, %s.", fpath,
+                      strerror(-error));
+            }
+            return kIgnoreErrors ? 0 : error;
+        }
+
+        auto status = utility->ReloadSystemProperties();
+        if (!status) {
+            ALOGE("pokeOnePDXService: Failed to send sysprop change to %s, "
+                  "error %d, %s.", fpath, status.error(),
+                  status.GetErrorMessage().c_str());
+            return kIgnoreErrors ? 0 : -status.error();
+        }
+    }
+
+    return 0;
+}
+
+// Pokes all the PDX processes in the system to get them to re-read
+// their system properties. Returns true on success, false on failure.
+static bool pokePDXServices()
+{
+    const int kMaxDepth = 16;
+    const int result = nftw(ServiceUtility::GetRootEndpointPath().c_str(),
+                            pokeOnePDXService, kMaxDepth, FTW_PHYS);
+    return result == 0 ? true : false;
+}
+
 // Set the trace tags that userland tracing uses, and poke the running
 // processes to pick up the new value.
 static bool setTagsProperty(uint64_t tags)
@@ -812,6 +855,7 @@ static bool setUpTrace()
     ok &= setAppCmdlineProperty(&packageList[0]);
     ok &= pokeBinderServices();
     pokeHalServices();
+    ok &= pokePDXServices();
 
     // Disable all the sysfs enables.  This is done as a separate loop from
     // the enables to allow the same enable to exist in multiple categories.
@@ -849,6 +893,7 @@ static void cleanUpTrace()
     setTagsProperty(0);
     clearAppProperties();
     pokeBinderServices();
+    pokePDXServices();
 
     // Set the options back to their defaults.
     setTraceOverwriteEnable(true);
index efc050b..d1e94ed 100644 (file)
@@ -103,8 +103,7 @@ LOCAL_SRC_FILES := $(COMMON_SRC_FILES) \
 
 LOCAL_MODULE := dumpstate
 
-LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES) \
-    android.hardware.vibrator@1.0
+LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES)
 
 LOCAL_STATIC_LIBRARIES := $(COMMON_STATIC_LIBRARIES)
 
index 6dbb967..b323624 100644 (file)
@@ -42,7 +42,6 @@
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
-#include <android/hardware/vibrator/1.0/IVibrator.h>
 #include <cutils/native_handle.h>
 #include <cutils/properties.h>
 #include <openssl/sha.h>
@@ -54,8 +53,6 @@
 #include "dumpstate.h"
 
 using ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
-using ::android::hardware::vibrator::V1_0::IVibrator;
-using VibratorStatus = ::android::hardware::vibrator::V1_0::Status;
 
 // TODO: remove once moved to namespace
 using android::os::dumpstate::CommandOptions;
@@ -1339,6 +1336,40 @@ static std::string SHA256_file_hash(std::string filepath) {
     return std::string(hash_buffer);
 }
 
+static void SendShellBroadcast(const std::string& action, const std::vector<std::string>& args) {
+    std::vector<std::string> am = {
+        "/system/bin/cmd", "activity", "broadcast", "--user", "0", "-a", action};
+
+    am.insert(am.end(), args.begin(), args.end());
+
+    // TODO: explicity setting Shell's component to allow broadcast to launch it.
+    // That might break other components that are listening to the bugreport notifications
+    // (android.intent.action.BUGREPORT_STARTED and android.intent.action.BUGREPORT_STOPED), but
+    // those should be just handled by Shell anyways.
+    // A more generic alternative would be passing the -f 0x01000000 flag (or whatever
+    // value is defined by FLAG_RECEIVER_INCLUDE_BACKGROUND), but that would reset the
+    // --receiver-foreground option
+    am.push_back("com.android.shell");
+
+    RunCommand("", am,
+               CommandOptions::WithTimeout(20)
+                   .Log("Sending broadcast: '%s'\n")
+                   .Always()
+                   .DropRoot()
+                   .RedirectStderr()
+                   .Build());
+}
+
+static void Vibrate(int duration_ms) {
+    // clang-format off
+    RunCommand("", {"cmd", "vibrator", "vibrate", std::to_string(duration_ms), "dumpstate"},
+               CommandOptions::WithTimeout(10)
+                   .Log("Vibrate: '%s'\n")
+                   .Always()
+                   .Build());
+    // clang-format on
+}
+
 int main(int argc, char *argv[]) {
     int do_add_date = 0;
     int do_zip_file = 0;
@@ -1561,18 +1592,15 @@ int main(int argc, char *argv[]) {
             if (do_broadcast) {
                 // clang-format off
 
-                // NOTE: flag must be kept in sync when the value of
-                // FLAG_RECEIVER_INCLUDE_BACKGROUND is changed.
                 std::vector<std::string> am_args = {
                      "--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
-                     "-f", "0x01000000",
                      "--es", "android.intent.extra.NAME", ds.name_,
                      "--ei", "android.intent.extra.ID", std::to_string(ds.id_),
                      "--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
                      "--ei", "android.intent.extra.MAX", std::to_string(ds.progress_->GetMax()),
                 };
                 // clang-format on
-                send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args);
+                SendShellBroadcast("android.intent.action.BUGREPORT_STARTED", am_args);
             }
             if (use_control_socket) {
                 dprintf(ds.control_socket_fd_, "BEGIN:%s\n", ds.path_.c_str());
@@ -1587,22 +1615,8 @@ int main(int argc, char *argv[]) {
         fclose(cmdline);
     }
 
-    ::android::sp<IVibrator> vibrator = nullptr;
     if (do_vibrate) {
-        vibrator = IVibrator::getService();
-
-        if (vibrator != nullptr) {
-            // cancel previous vibration if any
-            ::android::hardware::Return<VibratorStatus> offStatus = vibrator->off();
-            if (!offStatus.isOk() || offStatus != VibratorStatus::OK) {
-                MYLOGE("Vibrator off failed.");
-            } else {
-                ::android::hardware::Return<VibratorStatus> onStatus = vibrator->on(150);
-                if (!onStatus.isOk() || onStatus != VibratorStatus::OK) {
-                    MYLOGE("Vibrator on failed.");
-                }
-            }
-        }
+        Vibrate(150);
     }
 
     if (do_fb && ds.do_early_screenshot_) {
@@ -1782,21 +1796,9 @@ int main(int argc, char *argv[]) {
     }
 
     /* vibrate a few but shortly times to let user know it's finished */
-    if (vibrator != nullptr) {
-        // in case dumpstate magically completes before the above vibration
-        ::android::hardware::Return<VibratorStatus> offStatus = vibrator->off();
-        if (!offStatus.isOk() || offStatus != VibratorStatus::OK) {
-            MYLOGE("Vibrator off failed.");
-        } else {
-            for (int i = 0; i < 3; i++) {
-                ::android::hardware::Return<VibratorStatus> onStatus = vibrator->on(75);
-                if (!onStatus.isOk() || onStatus != VibratorStatus::OK) {
-                    MYLOGE("Vibrator on failed.");
-                    break;
-                }
-                usleep((75 + 50) * 1000);
-            }
-        }
+    for (int i = 0; i < 3; i++) {
+        Vibrate(75);
+        usleep((75 + 50) * 1000);
     }
 
     /* tell activity manager we're done */
@@ -1805,11 +1807,8 @@ int main(int argc, char *argv[]) {
             MYLOGI("Final bugreport path: %s\n", ds.path_.c_str());
             // clang-format off
 
-            // NOTE: flag must be kept in sync when the value of
-            // FLAG_RECEIVER_INCLUDE_BACKGROUND is changed.
             std::vector<std::string> am_args = {
                  "--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
-                 "-f", "0x01000000",
                  "--ei", "android.intent.extra.ID", std::to_string(ds.id_),
                  "--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
                  "--ei", "android.intent.extra.MAX", std::to_string(ds.progress_->GetMax()),
@@ -1826,9 +1825,9 @@ int main(int argc, char *argv[]) {
                 am_args.push_back("--es");
                 am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH");
                 am_args.push_back(SHA256_file_hash(ds.path_));
-                send_broadcast("android.intent.action.REMOTE_BUGREPORT_FINISHED", am_args);
+                SendShellBroadcast("android.intent.action.REMOTE_BUGREPORT_FINISHED", am_args);
             } else {
-                send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args);
+                SendShellBroadcast("android.intent.action.BUGREPORT_FINISHED", am_args);
             }
         } else {
             MYLOGE("Skipping finished broadcast because bugreport could not be generated\n");
index b2cd241..d988429 100644 (file)
@@ -363,9 +363,6 @@ int dump_file_from_fd(const char *title, const char *path, int fd);
 int dump_files(const std::string& title, const char* dir, bool (*skip)(const char* path),
                int (*dump_from_fd)(const char* title, const char* path, int fd));
 
-/* sends a broadcast using Activity Manager */
-void send_broadcast(const std::string& action, const std::vector<std::string>& args);
-
 /* prints all the system properties */
 void print_properties();
 
index c6dfa37..baa6458 100644 (file)
@@ -710,19 +710,6 @@ void Dumpstate::RunDumpsys(const std::string& title, const std::vector<std::stri
     RunCommand(title, dumpsys, options);
 }
 
-void send_broadcast(const std::string& action, const std::vector<std::string>& args) {
-    std::vector<std::string> am = {"/system/bin/am", "broadcast", "--user", "0", "-a", action};
-
-    am.insert(am.end(), args.begin(), args.end());
-
-    RunCommand("", am, CommandOptions::WithTimeout(20)
-                           .Log("Sending broadcast: '%s'\n")
-                           .Always()
-                           .DropRoot()
-                           .RedirectStderr()
-                           .Build());
-}
-
 size_t num_props = 0;
 static char* props[2000];
 
index c5ae9d2..3476964 100644 (file)
@@ -15,8 +15,6 @@ cc_defaults {
         "libutils",
         "liblog",
         "libbinder",
-        "android.hidl.manager@1.0",
-        "libhidlbase"
     ],
 
     clang: true,
index 860b7b4..f0e7200 100644 (file)
@@ -45,7 +45,8 @@ using android::base::StringPrintf;
 using android::base::unique_fd;
 using android::base::WriteFully;
 
-static int sort_func(const String16* lhs, const String16* rhs) {
+static int sort_func(const String16* lhs, const String16* rhs)
+{
     return lhs->compare(*rhs);
 }
 
@@ -54,11 +55,10 @@ static void usage() {
         "usage: dumpsys\n"
             "         To dump all services.\n"
             "or:\n"
-            "       dumpsys [-t TIMEOUT] [--help | --hw | -l | --skip SERVICES | SERVICE [ARGS]]\n"
+            "       dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
             "         --help: shows this help\n"
             "         -l: only list services, do not dump them\n"
             "         -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n"
-            "         --hw: list all hw services running on the device\n"
             "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
             "         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
 }
@@ -72,42 +72,16 @@ static bool IsSkipped(const Vector<String16>& skipped, const String16& service)
     return false;
 }
 
-static void ListHardwareServices(android::hidl::manager::V1_0::IServiceManager* hm) {
-    using android::hardware::hidl_vec;
-    using android::hardware::hidl_string;
-    using android::hardware::Return;
-    using android::sp;
-
-    if (hm == nullptr) {
-        ALOGE("Unable to get hardware service manager!");
-        aerr << "Failed to get hardware service manager!";
-        return;
-    }
-
-    Return<void> ret = hm->list([](const hidl_vec<hidl_string> &registered){
-        aout << "Currently running hardware services:" << endl;
-        for (const auto &service : registered) {
-            aout << "  " << service << endl;
-        }
-    });
-
-    if (!ret.isOk()) {
-        aerr << "Failed to list hardware services: " << ret.description();
-    }
-}
-
 int Dumpsys::main(int argc, char* const argv[]) {
     Vector<String16> services;
     Vector<String16> args;
     Vector<String16> skippedServices;
     bool showListOnly = false;
-    bool listHwOnly = false;
     bool skipServices = false;
     int timeoutArg = 10;
     static struct option longOptions[] = {
         {"skip", no_argument, 0,  0 },
         {"help", no_argument, 0,  0 },
-        {"hw",   no_argument, 0,  0 },
         {     0,           0, 0,  0 }
     };
 
@@ -131,8 +105,6 @@ int Dumpsys::main(int argc, char* const argv[]) {
             } else if (!strcmp(longOptions[optionIndex].name, "help")) {
                 usage();
                 return 0;
-            } else if (!strcmp(longOptions[optionIndex].name, "hw")) {
-                listHwOnly = true;
             }
             break;
 
@@ -171,17 +143,11 @@ int Dumpsys::main(int argc, char* const argv[]) {
     }
 
     if ((skipServices && skippedServices.empty()) ||
-            (showListOnly && (!services.empty() || !skippedServices.empty())) ||
-            (listHwOnly && (skipServices || services.size() > 0 || showListOnly))) {
+            (showListOnly && (!services.empty() || !skippedServices.empty()))) {
         usage();
         return -1;
     }
 
-    if (listHwOnly) {
-        ListHardwareServices(hm_);
-        return 0;
-    }
-
     if (services.empty() || showListOnly) {
         // gets all services
         services = sm_->listServices();
index 20d515d..2534dde 100644 (file)
 #ifndef FRAMEWORK_NATIVE_CMD_DUMPSYS_H_
 #define FRAMEWORK_NATIVE_CMD_DUMPSYS_H_
 
-#include <android/hidl/manager/1.0/IServiceManager.h>
 #include <binder/IServiceManager.h>
 
 namespace android {
 
 class Dumpsys {
   public:
-    Dumpsys(android::IServiceManager* sm,
-            android::hidl::manager::V1_0::IServiceManager* hm) : sm_(sm), hm_(hm) {
+    Dumpsys(android::IServiceManager* sm) : sm_(sm) {
     }
     int main(int argc, char* const argv[]);
 
   private:
     android::IServiceManager* sm_;
-    android::hidl::manager::V1_0::IServiceManager* hm_;
 };
 }
 
index b180c98..8ba0eba 100644 (file)
@@ -27,7 +27,6 @@
 #include <stdio.h>
 
 using namespace android;
-using HServiceManager = android::hidl::manager::V1_0::IServiceManager;
 
 int main(int argc, char* const argv[]) {
     signal(SIGPIPE, SIG_IGN);
@@ -39,8 +38,6 @@ int main(int argc, char* const argv[]) {
         return 20;
     }
 
-    sp<HServiceManager> hm = HServiceManager::getService("manager");
-
-    Dumpsys dumpsys(sm.get(), hm.get());
+    Dumpsys dumpsys(sm.get());
     return dumpsys.main(argc, argv);
 }
index e00444f..7698ed5 100644 (file)
@@ -5,12 +5,8 @@ cc_test {
     srcs: ["dumpsys_test.cpp"],
 
     shared_libs: [
-        "android.hidl.manager@1.0",
         "libbase",
         "libbinder",
-        "liblog",
-        "libhidlbase",
-        "libhidltransport",
         "libutils",
     ],
 
index 01a2fa3..a61cb00 100644 (file)
@@ -44,12 +44,6 @@ using ::testing::internal::CaptureStdout;
 using ::testing::internal::GetCapturedStderr;
 using ::testing::internal::GetCapturedStdout;
 
-using android::hardware::hidl_vec;
-using android::hardware::hidl_string;
-using android::hardware::Void;
-using HServiceManager = android::hidl::manager::V1_0::IServiceManager;
-using IServiceNotification = android::hidl::manager::V1_0::IServiceNotification;
-
 class ServiceManagerMock : public IServiceManager {
   public:
     MOCK_CONST_METHOD1(getService, sp<IBinder>(const String16&));
@@ -61,27 +55,6 @@ class ServiceManagerMock : public IServiceManager {
     MOCK_METHOD0(onAsBinder, IBinder*());
 };
 
-class HardwareServiceManagerMock : public HServiceManager {
-  public:
-    template<typename T>
-    using R = android::hardware::Return<T>; // conflicts with ::testing::Return
-
-    MOCK_METHOD2(get, R<sp<IBase>>(const hidl_string&, const hidl_string&));
-    MOCK_METHOD3(add,
-        R<bool>(const hidl_vec<hidl_string>&,
-                const hidl_string&,
-                const sp<IBase>&));
-    MOCK_METHOD1(list, R<void>(list_cb));
-    MOCK_METHOD2(listByInterface,
-        R<void>(const hidl_string&, listByInterface_cb));
-    MOCK_METHOD3(registerForNotifications,
-        R<bool>(const hidl_string&,
-                const hidl_string&,
-                const sp<IServiceNotification>&));
-    MOCK_METHOD1(debugDump, R<void>(debugDump_cb));
-
-};
-
 class BinderMock : public BBinder {
   public:
     BinderMock() {
@@ -111,26 +84,6 @@ Action<WriteOnFdFunction> WriteOnFd(const std::string& output) {
     return MakeAction(new WriteOnFdAction(output));
 }
 
-// gmock black magic to provide a WithArg<0>(List(services)) matcher
-typedef void HardwareListFunction(HServiceManager::list_cb);
-
-class HardwareListAction : public ActionInterface<HardwareListFunction> {
-  public:
-    explicit HardwareListAction(const hidl_vec<hidl_string> &services) : services_(services) {
-    }
-    virtual Result Perform(const ArgumentTuple& args) {
-        auto cb = ::std::tr1::get<0>(args);
-        cb(services_);
-    }
-
-  private:
-    hidl_vec<hidl_string> services_;
-};
-
-Action<HardwareListFunction> HardwareList(const  hidl_vec<hidl_string> &services) {
-    return MakeAction(new HardwareListAction(services));
-}
-
 // Matcher for args using Android's Vector<String16> format
 // TODO: move it to some common testing library
 MATCHER_P(AndroidElementsAre, expected, "") {
@@ -168,7 +121,7 @@ ACTION_P(Sleep, timeout) {
 
 class DumpsysTest : public Test {
   public:
-    DumpsysTest() : sm_(), hm_(), dump_(&sm_, &hm_), stdout_(), stderr_() {
+    DumpsysTest() : sm_(), dump_(&sm_), stdout_(), stderr_() {
     }
 
     void ExpectListServices(std::vector<std::string> services) {
@@ -176,22 +129,9 @@ class DumpsysTest : public Test {
         for (auto& service : services) {
             services16.add(String16(service.c_str()));
         }
-
         EXPECT_CALL(sm_, listServices()).WillRepeatedly(Return(services16));
     }
 
-    void ExpectListHardwareServices(std::vector<std::string> services) {
-        hidl_vec<hidl_string> hidl_services;
-        hidl_services.resize(services.size());
-        for (size_t i = 0; i < services.size(); i++) {
-            hidl_services[i] = services[i];
-        }
-
-        EXPECT_CALL(hm_, list(_)).WillRepeatedly(DoAll(
-                WithArg<0>(HardwareList(hidl_services)),
-                Return(Void())));
-    }
-
     sp<BinderMock> ExpectCheckService(const char* name, bool running = true) {
         sp<BinderMock> binder_mock;
         if (running) {
@@ -235,10 +175,8 @@ class DumpsysTest : public Test {
         EXPECT_THAT(status, Eq(0));
     }
 
-    void AssertRunningServices(const std::vector<std::string>& services,
-                               const std::string &message = "Currently running services:") {
-        std::string expected(message);
-        expected.append("\n");
+    void AssertRunningServices(const std::vector<std::string>& services) {
+        std::string expected("Currently running services:\n");
         for (const std::string& service : services) {
             expected.append("  ").append(service).append("\n");
         }
@@ -266,21 +204,12 @@ class DumpsysTest : public Test {
     }
 
     ServiceManagerMock sm_;
-    HardwareServiceManagerMock hm_;
     Dumpsys dump_;
 
   private:
     std::string stdout_, stderr_;
 };
 
-TEST_F(DumpsysTest, ListHwServices) {
-    ExpectListHardwareServices({"Locksmith", "Valet"});
-
-    CallMain({"--hw"});
-
-    AssertRunningServices({"Locksmith", "Valet"}, "Currently running hardware services:");
-}
-
 // Tests 'dumpsys -l' when all services are running
 TEST_F(DumpsysTest, ListAllServices) {
     ExpectListServices({"Locksmith", "Valet"});
index bc5eaf2..9998a46 100644 (file)
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
 
-template <typename A, typename B, typename C, typename D, typename E>
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hidl::manager::V1_0::IServiceManager;
+
+template <typename A, typename B, typename C, typename D, typename E, typename F>
 void printColumn(std::stringstream &stream,
-        const A &a, const B &b, const C &c, const D &d, const E &e) {
+        const A &a, const B &b, const C &c, const D &d, const E &, const F &f) {
     using namespace ::std;
     stream << left
            << setw(70) << a << "\t"
            << setw(20) << b << "\t"
            << setw(10) << c << "\t"
            << setw(5)  << d << "\t"
-           << setw(0)  << e
+           // TODO(b/34984175): enable selecting columns
+           // << setw(16) << e << "\t"
+           << setw(0)  << f
            << endl;
 }
 
+template <typename A>
+std::string join(const A &components, const std::string &separator) {
+    std::stringstream out;
+    bool first = true;
+    for (const auto &component : components) {
+        if (!first) {
+            out << separator;
+        }
+        out << component;
+
+        first = false;
+    }
+    return out.str();
+}
+
 std::string toHexString(uint64_t t) {
     std::ostringstream os;
     os << std::hex << std::setfill('0') << std::setw(16) << t;
     return os.str();
 }
 
-::android::status_t getReferencedPids(
+std::pair<hidl_string, hidl_string> split(const hidl_string &s, char c) {
+    const char *pos = strchr(s.c_str(), c);
+    if (pos == nullptr) {
+        return {s, {}};
+    }
+    return {hidl_string(s.c_str(), pos - s.c_str()), hidl_string(pos + 1)};
+}
+
+bool getReferencedPids(
         pid_t serverPid, std::map<uint64_t, std::string> *objects) {
 
     std::ifstream ifs("/d/binder/proc/" + std::to_string(serverPid));
     if (!ifs.is_open()) {
-        return ::android::PERMISSION_DENIED;
+        return false;
     }
 
     static const std::regex prefix("^\\s*node \\d+:\\s+u([0-9a-f]+)\\s+c([0-9a-f]+)\\s+");
@@ -77,66 +106,165 @@ std::string toHexString(uint64_t t) {
             (*objects)[ptr] += line.substr(pos + proc.size());
         }
     }
-    return ::android::OK;
+    return true;
 }
 
-
-int dump() {
+void dumpAllLibraries(std::stringstream &stream, const std::string &mode,
+            const sp<IServiceManager> &manager) {
     using namespace ::std;
     using namespace ::android::hardware;
     using namespace ::android::hidl::manager::V1_0;
+    using namespace ::android::hidl::base::V1_0;
+    auto ret = manager->list([&] (const auto &fqInstanceNames) {
+        for (const auto &fqInstanceName : fqInstanceNames) {
+            const auto pair = split(fqInstanceName, '/');
+            const auto &serviceName = pair.first;
+            const auto &instanceName = pair.second;
+            printColumn(stream,
+                serviceName,
+                instanceName,
+                mode,
+                "N/A",
+                "N/A",
+                "N/A");
+        }
+    });
+    if (!ret.isOk()) {
+        cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
+             << ret.description() << endl;
+    }
+}
 
-    std::map<std::string, ::android::sp<IServiceManager>> mapping = {
-            {"hwbinder", defaultServiceManager()},
-            {"passthrough", getPassthroughServiceManager()}
-    };
-
-    std::stringstream stream;
-
-    stream << "All services:" << endl;
-    stream << left;
-    printColumn(stream, "Interface", "Instance", "Transport", "Server", "Clients");
-
-    for (const auto &pair : mapping) {
-        const std::string &mode = pair.first;
-        const ::android::sp<IServiceManager> &manager = pair.second;
+void dumpPassthrough(std::stringstream &stream, const std::string &mode,
+            const sp<IServiceManager> &manager) {
+    using namespace ::std;
+    using namespace ::android::hardware;
+    using namespace ::android::hidl::manager::V1_0;
+    using namespace ::android::hidl::base::V1_0;
+    auto ret = manager->debugDump([&] (const auto &infos) {
+        for (const auto &info : infos) {
 
-        if (manager == nullptr) {
-            cerr << "Failed to get IServiceManager for " << mode << "!" << endl;
-            continue;
+            printColumn(stream,
+                info.interfaceName,
+                info.instanceName,
+                mode,
+                info.clientPids.size() == 1 ? std::to_string(info.clientPids[0]) : "N/A",
+                "N/A",
+                join(info.clientPids, " "));
         }
+    });
+    if (!ret.isOk()) {
+        cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
+             << ret.description() << endl;
+    }
+}
 
-        auto ret = manager->debugDump([&](const auto &registered) {
-            // server pid, .ptr value of binder object, child pids
-            std::map<pid_t, std::map<uint64_t, std::string>> allPids;
-            for (const auto &info : registered) {
-                if (info.pid < 0) {
-                    continue;
-                }
-                pid_t serverPid = info.pid;
-                allPids[serverPid].clear();
+void dumpBinderized(std::stringstream &stream, const std::string &mode,
+            const sp<IServiceManager> &manager) {
+    using namespace ::std;
+    using namespace ::android::hardware;
+    using namespace ::android::hidl::manager::V1_0;
+    using namespace ::android::hidl::base::V1_0;
+    auto listRet = manager->list([&] (const auto &fqInstanceNames) {
+        // server pid, .ptr value of binder object, child pids
+        std::map<std::string, DebugInfo> allDebugInfos;
+        std::map<pid_t, std::map<uint64_t, std::string>> allPids;
+        for (const auto &fqInstanceName : fqInstanceNames) {
+            const auto pair = split(fqInstanceName, '/');
+            const auto &serviceName = pair.first;
+            const auto &instanceName = pair.second;
+            auto getRet = manager->get(serviceName, instanceName);
+            if (!getRet.isOk()) {
+                cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                     << "cannot be fetched from service manager:"
+                     << getRet.description() << endl;
+                continue;
+            }
+            sp<IBase> service = getRet;
+            if (service == nullptr) {
+                cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                     << "cannot be fetched from service manager (null)";
+                continue;
             }
-            for (auto &pair : allPids) {
-                pid_t serverPid = pair.first;
-                if (getReferencedPids(serverPid, &allPids[serverPid]) != ::android::OK) {
-                    std::cerr << "Warning: no information for PID " << serverPid
-                              << ", are you root?" << std::endl;
+            auto debugRet = service->getDebugInfo([&] (const auto &debugInfo) {
+                allDebugInfos[fqInstanceName] = debugInfo;
+                if (debugInfo.pid >= 0) {
+                    allPids[static_cast<pid_t>(debugInfo.pid)].clear();
                 }
+            });
+            if (!debugRet.isOk()) {
+                cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                     << "debugging information cannot be retrieved:"
+                     << debugRet.description() << endl;
             }
-            for (const auto &info : registered) {
+        }
+        for (auto &pair : allPids) {
+            pid_t serverPid = pair.first;
+            if (!getReferencedPids(serverPid, &allPids[serverPid])) {
+                std::cerr << "Warning: no information for PID " << serverPid
+                          << ", are you root?" << std::endl;
+            }
+        }
+        for (const auto &fqInstanceName : fqInstanceNames) {
+            const auto pair = split(fqInstanceName, '/');
+            const auto &serviceName = pair.first;
+            const auto &instanceName = pair.second;
+            auto it = allDebugInfos.find(fqInstanceName);
+            if (it == allDebugInfos.end()) {
                 printColumn(stream,
-                    info.interfaceName,
-                    info.instanceName.empty() ? "N/A" : info.instanceName,
+                    serviceName,
+                    instanceName,
                     mode,
-                    info.pid < 0 ? "N/A" : std::to_string(info.pid),
-                    info.pid < 0 || info.ptr == 0 ? "" : allPids[info.pid][info.ptr]);
+                    "N/A",
+                    "N/A",
+                    ""
+                );
+                continue;
             }
-        });
-        if (!ret.isOk()) {
-            cerr << "Failed to list services for " << mode << ": "
-                 << ret.description() << endl;
+            const DebugInfo &info = it->second;
+            printColumn(stream,
+                serviceName,
+                instanceName,
+                mode,
+                info.pid < 0 ? "N/A" : std::to_string(info.pid),
+                info.ptr == 0 ? "N/A" : toHexString(info.ptr),
+                info.pid < 0 || info.ptr == 0 ? "" : allPids[info.pid][info.ptr]
+            );
         }
+
+    });
+    if (!listRet.isOk()) {
+        cerr << "Error: Failed to list services for " << mode << ": "
+             << listRet.description() << endl;
     }
+}
+
+int dump() {
+    using namespace ::std;
+    using namespace ::android::hardware;
+
+    std::stringstream stream;
+
+    stream << "All services:" << endl;
+    stream << left;
+    printColumn(stream, "Interface", "Instance", "Transport", "Server", "PTR", "Clients");
+
+    auto bManager = defaultServiceManager();
+    if (bManager == nullptr) {
+        cerr << "Failed to get defaultServiceManager()!" << endl;
+    } else {
+        dumpBinderized(stream, "hwbinder", bManager);
+        // Passthrough PIDs are registered to the binderized manager as well.
+        dumpPassthrough(stream, "passthrough", bManager);
+    }
+
+    auto pManager = getPassthroughServiceManager();
+    if (pManager == nullptr) {
+        cerr << "Failed to get getPassthroughServiceManager()!" << endl;
+    } else {
+        dumpAllLibraries(stream, "passthrough", pManager);
+    }
+
     cout << stream.rdbuf();
     return 0;
 }
diff --git a/data/etc/android.hardware.vulkan.compute-0.xml b/data/etc/android.hardware.vulkan.compute-0.xml
new file mode 100644 (file)
index 0000000..bac2fde
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 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.
+-->
+
+<!-- This is the standard feature indicating that the device supports Vulkan
+     compute level 0. -->
+<permissions>
+    <feature name="android.hardware.vulkan.compute" version="0" />
+</permissions>
index 261e64f..2def64d 100644 (file)
@@ -56,9 +56,9 @@ enum AndroidBitmapFormat {
     ANDROID_BITMAP_FORMAT_RGBA_8888 = 1,
     /** Red: 5 bits, Green: 6 bits, Blue: 5 bits. **/
     ANDROID_BITMAP_FORMAT_RGB_565   = 4,
-    /** Red: 4 bits, Green: 4 bits, Blue: 4 bits, Alpha: 4 bits. **/
+    /** Deprecated in API level 13. Because of the poor quality of this configuration, it is advised to use ARGB_8888 instead. **/
     ANDROID_BITMAP_FORMAT_RGBA_4444 = 7,
-    /** Deprecated. */
+    /** Alpha: 8 bits. */
     ANDROID_BITMAP_FORMAT_A_8       = 8,
 };
 
index efcac74..94afae5 100644 (file)
@@ -41,6 +41,10 @@ public:
 
     virtual void setVolume(float vol) = 0;
 
+    virtual void setPan(float pan) = 0;
+
+    virtual void setStartDelayMs(int delayMs) = 0;
+
 };
 
 // ----------------------------------------------------------------------------
index 30d7317..80ab7f3 100644 (file)
@@ -26,13 +26,15 @@ namespace android {
 
 #include "BatteryServiceConstants.h"
 
-// must be kept in sync with definitions in BatteryProperty.java
+// must be kept in sync with definitions in
+// frameworks/base/core/java/android/os/BatteryManager.java
 enum {
-    BATTERY_PROP_CHARGE_COUNTER = 1, // equals BatteryProperty.CHARGE_COUNTER constant
-    BATTERY_PROP_CURRENT_NOW = 2, // equals BatteryProperty.CURRENT_NOW constant
-    BATTERY_PROP_CURRENT_AVG = 3, // equals BatteryProperty.CURRENT_AVG constant
-    BATTERY_PROP_CAPACITY = 4, // equals BatteryProperty.CAPACITY constant
-    BATTERY_PROP_ENERGY_COUNTER = 5, // equals BatteryProperty.ENERGY_COUNTER constant
+    BATTERY_PROP_CHARGE_COUNTER = 1, // equals BATTERY_PROPERTY_CHARGE_COUNTER
+    BATTERY_PROP_CURRENT_NOW = 2, // equals BATTERY_PROPERTY_CURRENT_NOW
+    BATTERY_PROP_CURRENT_AVG = 3, // equals BATTERY_PROPERTY_CURRENT_AVERAGE
+    BATTERY_PROP_CAPACITY = 4, // equals BATTERY_PROPERTY_CAPACITY
+    BATTERY_PROP_ENERGY_COUNTER = 5, // equals BATTERY_PROPERTY_ENERGY_COUNTER
+    BATTERY_PROP_BATTERY_STATUS = 6, // equals BATTERY_PROPERTY_BATTERY_STATUS
 };
 
 struct BatteryProperties {
index c5ead20..0da61ee 100644 (file)
@@ -35,6 +35,8 @@ class ProcessInfoService : public Singleton<ProcessInfoService> {
     ProcessInfoService();
 
     status_t getProcessStatesImpl(size_t length, /*in*/ int32_t* pids, /*out*/ int32_t* states);
+    status_t getProcessStatesScoresImpl(size_t length, /*in*/ int32_t* pids,
+            /*out*/ int32_t* states, /*out*/ int32_t *scores);
     void updateBinderLocked();
 
     static const int BINDER_ATTEMPT_LIMIT = 5;
@@ -55,6 +57,21 @@ public:
                 /*out*/ states);
     }
 
+    /**
+     * For each PID in the given "pids" input array, write the current process state
+     * for that process into the "states" output array, or
+     * ActivityManager.PROCESS_STATE_NONEXISTENT * to indicate that no process with the given PID
+     * exists. OoM scores will also be written in the "scores" output array.
+     * Please also note that clients calling this method need to have
+     * "GET_PROCESS_STATE_AND_OOM_SCORE" permission.
+     *
+     * Returns NO_ERROR if this operation was successful, or a negative error code otherwise.
+     */
+    static status_t getProcessStatesScoresFromPids(size_t length, /*in*/ int32_t* pids,
+            /*out*/ int32_t* states, /*out*/ int32_t *scores) {
+        return ProcessInfoService::getInstance().getProcessStatesScoresImpl(
+                length, /*in*/ pids, /*out*/ states, /*out*/ scores);
+    }
 };
 
 // ----------------------------------------------------------------------
index ab676cc..55637a9 100644 (file)
@@ -17,9 +17,6 @@
 #ifndef ANDROID_GUI_BUFFERITEM_H
 #define ANDROID_GUI_BUFFERITEM_H
 
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
 #include <ui/FenceTime.h>
 #include <ui/Rect.h>
 #include <ui/Region.h>
index f8ded74..4a49f53 100644 (file)
@@ -172,7 +172,9 @@ public:
     void setFilteringEnabled(bool enabled);
 
     // getCurrentBuffer returns the buffer associated with the current image.
-    sp<GraphicBuffer> getCurrentBuffer() const;
+    // When outSlot is not nullptr, the current buffer slot index is also
+    // returned.
+    sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr) const;
 
     // getCurrentTextureTarget returns the texture target of the current
     // texture as returned by updateTexImage().
index b19a1ac..54c9829 100644 (file)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
-#define ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
+#ifndef ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
+#define ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
 
 #include <stdint.h>
 #include <sys/types.h>
 #include <utils/Errors.h>
 
 namespace android {
-// ---------------------------------------------------------------------------
 
 class GraphicBuffer;
 
+/*
+ * Concrete implementation of the IGraphicBufferAlloc interface.
+ *
+ * This can create GraphicBuffer instance across processes. This is mainly used
+ * by surfaceflinger.
+ */
+
 class GraphicBufferAlloc : public BnGraphicBufferAlloc {
 public:
     GraphicBufferAlloc();
     virtual ~GraphicBufferAlloc();
     virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
             uint32_t height, PixelFormat format, uint32_t layerCount,
-            uint32_t usage, std::string requestorName,
-            status_t* error) override;
+            uint64_t producerUsage, uint64_t consumerUsage,
+            std::string requestorName, status_t* error) override;
 };
 
 
-// ---------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
 
-#endif // ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
+#endif // ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
index 2a7690a..1e578cc 100644 (file)
@@ -38,14 +38,29 @@ public:
     /* Create a new GraphicBuffer for the client to use.
      */
     virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
-            PixelFormat format, uint32_t layerCount, uint32_t usage,
-            std::string requestorName, status_t* error) = 0;
+            PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
+            uint64_t consumerUsage, std::string requestorName,
+            status_t* error) = 0;
 
     sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
             PixelFormat format, uint32_t layerCount, uint32_t usage,
             status_t* error) {
-        return createGraphicBuffer(w, h, format, layerCount, usage, "<Unknown>",
-                error);
+        return createGraphicBuffer(w, h, format, layerCount, usage,
+                usage, "<Unknown>", error);
+    }
+
+    sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
+            PixelFormat format, uint32_t layerCount, uint32_t usage,
+            std::string requestorName, status_t* error) {
+        return createGraphicBuffer(w, h, format, layerCount, usage,
+                usage, requestorName, error);
+    }
+
+    sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
+            PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
+            uint64_t consumerUsage, status_t* error) {
+        return createGraphicBuffer(w, h, format, layerCount, producerUsage,
+                consumerUsage, "<Unknown>", error);
     }
 };
 
index 8af4d46..9870ba0 100644 (file)
@@ -28,9 +28,7 @@
 #include <binder/IInterface.h>
 
 #include <ui/FrameStats.h>
-
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/ISurfaceComposerClient.h>
+#include <ui/PixelFormat.h>
 
 #include <vector>
 
@@ -43,7 +41,9 @@ struct DisplayInfo;
 struct DisplayStatInfo;
 class HdrCapabilities;
 class IDisplayEventConnection;
-class IMemoryHeap;
+class IGraphicBufferAlloc;
+class IGraphicBufferProducer;
+class ISurfaceComposerClient;
 class Rect;
 enum class FrameEvent;
 
index d05d930..a3c2bfa 100644 (file)
 #define ANDROID_GUI_SURFACE_H
 
 #include <gui/IGraphicBufferProducer.h>
-#include <gui/BufferQueue.h>
+#include <gui/BufferQueueDefs.h>
 
 #include <ui/ANativeObjectBase.h>
 #include <ui/Region.h>
 
-#include <binder/Parcelable.h>
-
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
 #include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <utils/KeyedVector.h>
 
 struct ANativeWindow_Buffer;
 
@@ -259,7 +257,7 @@ public:
     virtual int attachBuffer(ANativeWindowBuffer*);
 
 protected:
-    enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };
+    enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS };
     enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
 
     void querySupportedTimestampsLocked() const;
@@ -418,43 +416,6 @@ protected:
     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 (file)
index 0000000..cc64fd4
--- /dev/null
@@ -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
index ff2f9bf..50bd742 100644 (file)
@@ -28,7 +28,6 @@ namespace android {
 
 // ---------------------------------------------------------------------------
 
-class IMemoryHeap;
 class ISurfaceComposer;
 
 // ---------------------------------------------------------------------------
index 64dacd7..640e29c 100644 (file)
@@ -88,8 +88,6 @@ public:
 
     std::shared_ptr<Descriptor> createDescriptor();
 
-    gralloc1_error_t getStride(buffer_handle_t buffer, uint32_t* outStride);
-
     gralloc1_error_t allocate(
             const std::vector<std::shared_ptr<const Descriptor>>& descriptors,
             std::vector<buffer_handle_t>* outBuffers);
@@ -102,6 +100,19 @@ public:
 
     gralloc1_error_t release(buffer_handle_t buffer);
 
+    gralloc1_error_t getDimensions(buffer_handle_t buffer,
+            uint32_t* outWidth, uint32_t* outHeight);
+    gralloc1_error_t getFormat(buffer_handle_t buffer,
+            int32_t* outFormat);
+    gralloc1_error_t getLayerCount(buffer_handle_t buffer,
+            uint32_t* outLayerCount);
+    gralloc1_error_t getProducerUsage(buffer_handle_t buffer,
+            uint64_t* outProducerUsage);
+    gralloc1_error_t getConsumerUsage(buffer_handle_t buffer,
+            uint64_t* outConsumerUsage);
+    gralloc1_error_t getBackingStore(buffer_handle_t buffer,
+            uint64_t* outBackingStore);
+    gralloc1_error_t getStride(buffer_handle_t buffer, uint32_t* outStride);
     gralloc1_error_t getNumFlexPlanes(buffer_handle_t buffer,
             uint32_t* outNumPlanes);
 
index 2508ce9..fcd2245 100644 (file)
@@ -325,7 +325,7 @@ private:
         auto usage = GRALLOC1_CONSUMER_USAGE_NONE;
         auto error = callBufferFunction(device, bufferHandle,
                 &Buffer::getConsumerUsage, &usage);
-        if (error != GRALLOC1_ERROR_NONE) {
+        if (error == GRALLOC1_ERROR_NONE) {
             *outUsage = static_cast<uint64_t>(usage);
         }
         return error;
@@ -336,7 +336,7 @@ private:
         auto usage = GRALLOC1_PRODUCER_USAGE_NONE;
         auto error = callBufferFunction(device, bufferHandle,
                 &Buffer::getProducerUsage, &usage);
-        if (error != GRALLOC1_ERROR_NONE) {
+        if (error == GRALLOC1_ERROR_NONE) {
             *outUsage = static_cast<uint64_t>(usage);
         }
         return error;
index f533dfb..5a23b68 100644 (file)
@@ -45,17 +45,23 @@ public:
     Error retain(buffer_handle_t handle) const;
     void release(buffer_handle_t handle) const;
 
+    Error getDimensions(buffer_handle_t handle,
+            uint32_t* outWidth, uint32_t* outHeight) const;
+    Error getFormat(buffer_handle_t handle, int32_t* outFormat) const;
+    Error getLayerCount(buffer_handle_t handle, uint32_t* outLayerCount) const;
+    Error getProducerUsage(buffer_handle_t handle,
+            uint64_t* outProducerUsage) const;
+    Error getConsumerUsage(buffer_handle_t handle,
+            uint64_t* outConsumerUsage) const;
+    Error getBackingStore(buffer_handle_t handle,
+            uint64_t* outBackingStore) const;
     Error getStride(buffer_handle_t handle, uint32_t* outStride) const;
 
-    Error lock(buffer_handle_t handle,
-            uint64_t producerUsageMask,
-            uint64_t consumerUsageMask,
-            const IMapper::Rect& accessRegion,
+    Error lock(buffer_handle_t handle, uint64_t producerUsage,
+            uint64_t consumerUsage, const IMapper::Rect& accessRegion,
             int acquireFence, void** outData) const;
-    Error lock(buffer_handle_t handle,
-            uint64_t producerUsageMask,
-            uint64_t consumerUsageMask,
-            const IMapper::Rect& accessRegion,
+    Error lock(buffer_handle_t handle, uint64_t producerUsage,
+            uint64_t consumerUsage, const IMapper::Rect& accessRegion,
             int acquireFence, FlexLayout* outLayout) const;
     int unlock(buffer_handle_t handle) const;
 
index 1bbcee2..759c9ec 100644 (file)
@@ -76,16 +76,22 @@ public:
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
             uint32_t inUsage, std::string requestorName = "<Unknown>");
 
-    // creates w * h buffer with a layer count
+    // creates w * h buffer with a layer count using gralloc1
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
-            uint32_t inLayerCount, uint32_t inUsage,
-            std::string requestorName = "<Unknown>");
+            uint32_t inLayerCount, uint64_t inProducerUsage,
+            uint64_t inConsumerUsage, std::string requestorName = "<Unknown>");
 
     // create a buffer from an existing handle
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
             uint32_t inLayerCount, uint32_t inUsage, uint32_t inStride,
             native_handle_t* inHandle, bool keepOwnership);
 
+    // create a buffer from an existing handle using gralloc1
+    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
+            uint32_t inLayerCount, uint32_t inProducerUsage,
+            uint32_t inConsumerUsage, uint32_t inStride,
+            native_handle_t* inHandle, bool keepOwnership);
+
     // create a buffer from an existing ANativeWindowBuffer
     GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership);
 
@@ -122,6 +128,8 @@ public:
     status_t lockAsync(uint32_t inUsage, void** vaddr, int fenceFd);
     status_t lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr,
             int fenceFd);
+    status_t lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage,
+            const Rect& rect, void** vaddr, int fenceFd);
     status_t lockAsyncYCbCr(uint32_t inUsage, android_ycbcr *ycbcr,
             int fenceFd);
     status_t lockAsyncYCbCr(uint32_t inUsage, const Rect& rect,
@@ -166,7 +174,8 @@ private:
     const GraphicBuffer& operator = (const GraphicBuffer& rhs) const;
 
     status_t initSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
-            uint32_t inLayerCount, uint32_t inUsage, std::string requestorName);
+            uint32_t inLayerCount, uint64_t inProducerUsage,
+            uint64_t inConsumerUsage, std::string requestorName);
 
     void free_handle();
 
index 16967d4..2ccc44b 100644 (file)
@@ -65,8 +65,8 @@ public:
     static inline GraphicBufferAllocator& get() { return getInstance(); }
 
     status_t allocate(uint32_t w, uint32_t h, PixelFormat format,
-            uint32_t layerCount, uint32_t usage, buffer_handle_t* handle,
-            uint32_t* stride, uint64_t graphicBufferId,
+            uint32_t layerCount, uint64_t producerUsage, uint64_t consumerUsage,
+            buffer_handle_t* handle, uint32_t* stride, uint64_t graphicBufferId,
             std::string requestorName);
 
     status_t free(buffer_handle_t handle);
@@ -81,7 +81,8 @@ private:
         uint32_t stride;
         PixelFormat format;
         uint32_t layerCount;
-        uint32_t usage;
+        uint64_t producerUsage;
+        uint64_t consumerUsage;
         size_t size;
         std::string requestorName;
     };
index b6de1b2..001769f 100644 (file)
@@ -39,11 +39,32 @@ class GraphicBufferMapper : public Singleton<GraphicBufferMapper>
 public:
     static inline GraphicBufferMapper& get() { return getInstance(); }
 
+    // This may NOT work on devices without a valid Gralloc2::Mapper.
     status_t registerBuffer(buffer_handle_t handle);
+
     status_t registerBuffer(const GraphicBuffer* buffer);
 
     status_t unregisterBuffer(buffer_handle_t handle);
 
+    status_t getDimensions(buffer_handle_t handle,
+            uint32_t* outWidth, uint32_t* outHeight) const;
+
+    status_t getFormat(buffer_handle_t handle, int32_t* outFormat) const;
+
+    status_t getLayerCount(buffer_handle_t handle,
+            uint32_t* outLayerCount) const;
+
+    status_t getProducerUsage(buffer_handle_t handle,
+            uint64_t* outProducerUsage) const;
+
+    status_t getConsumerUsage(buffer_handle_t handle,
+            uint64_t* outConsumerUsage) const;
+
+    status_t getBackingStore(buffer_handle_t handle,
+            uint64_t* outBackingStore) const;
+
+    status_t getStride(buffer_handle_t handle, uint32_t* outStride) const;
+
     status_t lock(buffer_handle_t handle,
             uint32_t usage, const Rect& bounds, void** vaddr);
 
@@ -55,6 +76,10 @@ public:
     status_t lockAsync(buffer_handle_t handle,
             uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd);
 
+    status_t lockAsync(buffer_handle_t handle,
+            uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds,
+            void** vaddr, int fenceFd);
+
     status_t lockAsyncYCbCr(buffer_handle_t handle,
             uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr,
             int fenceFd);
similarity index 94%
rename from include/gui/GraphicsEnv.h
rename to include/ui/GraphicsEnv.h
index 4c7366f..7817076 100644 (file)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_GUI_GRAPHICS_ENV_H
-#define ANDROID_GUI_GRAPHICS_ENV_H 1
+#ifndef ANDROID_UI_GRAPHICS_ENV_H
+#define ANDROID_UI_GRAPHICS_ENV_H 1
 
 #include <string>
 
@@ -56,4 +56,4 @@ private:
  */
 extern "C" android_namespace_t* android_getDriverNamespace();
 
-#endif // ANDROID_GUI_GRAPHICS_ENV_H
+#endif // ANDROID_UI_GRAPHICS_ENV_H
index a7cd5fb..925aa1b 100644 (file)
 #ifndef ANDROID_UI_HDR_CAPABILTIES_H
 #define ANDROID_UI_HDR_CAPABILTIES_H
 
-#include <binder/Parcelable.h>
+#include <stdint.h>
+
+#include <vector>
+
+#include <utils/Flattenable.h>
 
 namespace android {
 
-class HdrCapabilities : public Parcelable
+class HdrCapabilities : public LightFlattenable<HdrCapabilities>
 {
 public:
     HdrCapabilities(const std::vector<int32_t /*android_hdr_t*/>& types,
@@ -32,8 +36,8 @@ public:
         mMinLuminance(minLuminance) {}
 
     // Make this move-constructable and move-assignable
-    HdrCapabilities(HdrCapabilities&& other) = default;
-    HdrCapabilities& operator=(HdrCapabilities&& other) = default;
+    HdrCapabilities(HdrCapabilities&& other);
+    HdrCapabilities& operator=(HdrCapabilities&& other);
 
     HdrCapabilities()
       : mSupportedHdrTypes(),
@@ -41,7 +45,7 @@ public:
         mMaxAverageLuminance(-1.0f),
         mMinLuminance(-1.0f) {}
 
-    virtual ~HdrCapabilities() = default;
+    ~HdrCapabilities();
 
     const std::vector<int32_t /*android_hdr_t*/>& getSupportedHdrTypes() const {
         return mSupportedHdrTypes;
@@ -50,9 +54,11 @@ public:
     float getDesiredMaxAverageLuminance() const { return mMaxAverageLuminance; }
     float getDesiredMinLuminance() const { return mMinLuminance; }
 
-    // Parcelable interface
-    virtual status_t writeToParcel(Parcel* parcel) const override;
-    virtual status_t readFromParcel(const Parcel* parcel) override;
+    // Flattenable protocol
+    bool isFixedSize() const { return false; }
+    size_t getFlattenedSize() const;
+    status_t flatten(void* buffer, size_t size) const;
+    status_t unflatten(void const* buffer, size_t size);
 
 private:
     std::vector<int32_t /*android_hdr_t*/> mSupportedHdrTypes;
index fb28643..8939d9c 100644 (file)
@@ -57,6 +57,40 @@ status_t ProcessInfoService::getProcessStatesImpl(size_t length, /*in*/ int32_t*
     return TIMED_OUT;
 }
 
+status_t ProcessInfoService::getProcessStatesScoresImpl(size_t length,
+        /*in*/ int32_t* pids, /*out*/ int32_t* states,
+        /*out*/ int32_t *scores) {
+    status_t err = NO_ERROR;
+    sp<IProcessInfoService> pis;
+    mProcessInfoLock.lock();
+    pis = mProcessInfoService;
+    mProcessInfoLock.unlock();
+
+    for (int i = 0; i < BINDER_ATTEMPT_LIMIT; i++) {
+
+        if (pis != NULL) {
+            err = pis->getProcessStatesAndOomScoresFromPids(length,
+                    /*in*/ pids, /*out*/ states, /*out*/ scores);
+            if (err == NO_ERROR) return NO_ERROR; // success
+            if (IInterface::asBinder(pis)->isBinderAlive()) return err;
+        }
+        sleep(1);
+
+        mProcessInfoLock.lock();
+        if (pis == mProcessInfoService) {
+            updateBinderLocked();
+        }
+        pis = mProcessInfoService;
+        mProcessInfoLock.unlock();
+    }
+
+    ALOGW("%s: Could not retrieve process states and scores "
+            "from ProcessInfoService after %d retries.", __FUNCTION__,
+            BINDER_ATTEMPT_LIMIT);
+
+    return TIMED_OUT;
+}
+
 void ProcessInfoService::updateBinderLocked() {
     const sp<IServiceManager> sm(defaultServiceManager());
     if (sm != NULL) {
index d42bb82..fe28533 100644 (file)
@@ -319,7 +319,8 @@ static int open_driver()
             fd = -1;
         }
         if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
-            ALOGE("Binder driver protocol does not match user space protocol!");
+          ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
+                vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
             close(fd);
             fd = -1;
         }
index 3815bdc..ddf1072 100644 (file)
@@ -77,7 +77,6 @@ cc_library_shared {
         "FrameTimestamps.cpp",
         "GLConsumer.cpp",
         "GraphicBufferAlloc.cpp",
-        "GraphicsEnv.cpp",
         "GuiConfig.cpp",
         "IDisplayEventConnection.cpp",
         "IGraphicBufferAlloc.cpp",
@@ -97,10 +96,10 @@ cc_library_shared {
         "SurfaceControl.cpp",
         "SurfaceComposerClient.cpp",
         "SyncFeatures.cpp",
+        "view/Surface.cpp",
     ],
 
     shared_libs: [
-        "libnativeloader",
         "libsync",
         "libbinder",
         "libcutils",
index b11a3e5..9532c52 100644 (file)
@@ -930,9 +930,14 @@ uint64_t GLConsumer::getFrameNumber() {
     return mCurrentFrameNumber;
 }
 
-sp<GraphicBuffer> GLConsumer::getCurrentBuffer() const {
+sp<GraphicBuffer> GLConsumer::getCurrentBuffer(int* outSlot) const {
     Mutex::Autolock lock(mMutex);
-    return (mCurrentTextureImage == NULL) ?
+
+    if (outSlot != nullptr) {
+        *outSlot = mCurrentTexture;
+    }
+
+    return (mCurrentTextureImage == nullptr) ?
             NULL : mCurrentTextureImage->graphicBuffer();
 }
 
index 30f5e53..cc7d403 100644 (file)
  ** limitations under the License.
  */
 
-#include <log/log.h>
+#include <gui/GraphicBufferAlloc.h>
 
-#include <ui/GraphicBuffer.h>
+#include <log/log.h>
 
-#include <gui/GraphicBufferAlloc.h>
 
-// ----------------------------------------------------------------------------
 namespace android {
-// ----------------------------------------------------------------------------
 
-GraphicBufferAlloc::GraphicBufferAlloc() {
-}
-
-GraphicBufferAlloc::~GraphicBufferAlloc() {
-}
+GraphicBufferAlloc::GraphicBufferAlloc() = default;
+GraphicBufferAlloc::~GraphicBufferAlloc() = default;
 
 sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
         uint32_t height, PixelFormat format, uint32_t layerCount,
-        uint32_t usage, std::string requestorName, status_t* error) {
+        uint64_t producerUsage, uint64_t consumerUsage,
+        std::string requestorName, status_t* error) {
     sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(
-            width, height, format, layerCount, usage,
+            width, height, format, layerCount, producerUsage, consumerUsage,
             std::move(requestorName)));
     status_t err = graphicBuffer->initCheck();
     *error = err;
@@ -43,15 +38,12 @@ sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
         if (err == NO_MEMORY) {
             GraphicBuffer::dumpAllocationsToSystemLog();
         }
-        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) "
-             "failed (%s), handle=%p",
+        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) failed (%s), handle=%p",
                 width, height, layerCount, strerror(-err),
                 graphicBuffer->handle);
-        return 0;
+        graphicBuffer.clear();
     }
     return graphicBuffer;
 }
 
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
+} // namespace android
index a3d3b74..21a0dd5 100644 (file)
@@ -46,14 +46,16 @@ public:
 
     virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
             uint32_t height, PixelFormat format, uint32_t layerCount,
-            uint32_t usage, std::string requestorName, status_t* error) {
+            uint64_t producerUsage, uint64_t consumerUsage,
+            std::string requestorName, status_t* error) {
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
         data.writeUint32(width);
         data.writeUint32(height);
         data.writeInt32(static_cast<int32_t>(format));
         data.writeUint32(layerCount);
-        data.writeUint32(usage);
+        data.writeUint64(producerUsage);
+        data.writeUint64(consumerUsage);
         if (requestorName.empty()) {
             requestorName += "[PID ";
             requestorName += std::to_string(getpid());
@@ -108,12 +110,14 @@ status_t BnGraphicBufferAlloc::onTransact(
             uint32_t height = data.readUint32();
             PixelFormat format = static_cast<PixelFormat>(data.readInt32());
             uint32_t layerCount = data.readUint32();
-            uint32_t usage = data.readUint32();
+            uint64_t producerUsage = data.readUint64();
+            uint64_t consumerUsage = data.readUint64();
             status_t error = NO_ERROR;
             std::string requestorName;
             data.readUtf8FromUtf16(&requestorName);
             sp<GraphicBuffer> result = createGraphicBuffer(width, height,
-                    format, layerCount, usage, requestorName, &error);
+                    format, layerCount, producerUsage, consumerUsage,
+                    requestorName, &error);
             reply->writeInt32(error);
             if (result != 0) {
                 reply->write(*result);
index 2a327da..06d1261 100644 (file)
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
-#include <gui/BitTube.h>
 #include <gui/IDisplayEventConnection.h>
-#include <gui/ISurfaceComposer.h>
+#include <gui/IGraphicBufferAlloc.h>
 #include <gui/IGraphicBufferProducer.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/ISurfaceComposerClient.h>
 
 #include <private/gui/LayerState.h>
 
@@ -44,8 +45,6 @@
 
 namespace android {
 
-class IDisplayEventConnection;
-
 class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
 {
 public:
@@ -433,7 +432,7 @@ public:
         }
         result = reply.readInt32();
         if (result == NO_ERROR) {
-            result = reply.readParcelable(outCapabilities);
+            result = reply.read(*outCapabilities);
         }
         return result;
     }
@@ -754,7 +753,7 @@ status_t BnSurfaceComposer::onTransact(
             result = getHdrCapabilities(display, &capabilities);
             reply->writeInt32(result);
             if (result == NO_ERROR) {
-                reply->writeParcelable(capabilities);
+                reply->write(capabilities);
             }
             return NO_ERROR;
         }
index 2fd29d5..e2f733a 100644 (file)
@@ -210,6 +210,10 @@ Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersi
             mFlags |= SENSOR_FLAG_WAKE_UP;
         }
         break;
+    case SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT:
+        mStringType = SENSOR_STRING_TYPE_LOW_LATENCY_OFFBODY_DETECT;
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        break;
     case SENSOR_TYPE_WRIST_TILT_GESTURE:
         mStringType = SENSOR_STRING_TYPE_WRIST_TILT_GESTURE;
         mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
index 46eaf28..513b889 100644 (file)
@@ -196,7 +196,8 @@ Sensor const* SensorManager::getDefaultSensor(int type)
         if (type == SENSOR_TYPE_PROXIMITY || type == SENSOR_TYPE_SIGNIFICANT_MOTION ||
             type == SENSOR_TYPE_TILT_DETECTOR || type == SENSOR_TYPE_WAKE_GESTURE ||
             type == SENSOR_TYPE_GLANCE_GESTURE || type == SENSOR_TYPE_PICK_UP_GESTURE ||
-            type == SENSOR_TYPE_WRIST_TILT_GESTURE) {
+            type == SENSOR_TYPE_WRIST_TILT_GESTURE ||
+            type == SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT) {
             wakeUpSensor = true;
         }
         // For now we just return the first sensor of that type we find.
index b250f5d..d285ef0 100644 (file)
@@ -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>
 #include <ui/Region.h>
 #include <ui/DisplayStatInfo.h>
 
+#include <gui/BufferItem.h>
 #include <gui/IProducerListener.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/GLConsumer.h>
-#include <gui/Surface.h>
 
+#include <gui/ISurfaceComposer.h>
 #include <private/gui/ComposerService.h>
 
 namespace android {
@@ -1594,74 +1592,4 @@ status_t Surface::getUniqueId(uint64_t* outId) const {
     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 (file)
index 0000000..5ed3d3b
--- /dev/null
@@ -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
index 4cd0d3a..cfe170d 100644 (file)
@@ -55,6 +55,7 @@ cc_library_shared {
         "GraphicBuffer.cpp",
         "GraphicBufferAllocator.cpp",
         "GraphicBufferMapper.cpp",
+        "GraphicsEnv.cpp",
         "HdrCapabilities.cpp",
         "PixelFormat.cpp",
         "Rect.cpp",
@@ -65,7 +66,7 @@ cc_library_shared {
     shared_libs: [
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.mapper@2.0",
-        "libbinder",
+        "libnativeloader",
         "libcutils",
         "libhardware",
         "libhidlbase",
index 367d1ce..0083f58 100644 (file)
@@ -140,12 +140,6 @@ std::shared_ptr<Descriptor> Device::createDescriptor()
     return descriptor;
 }
 
-gralloc1_error_t Device::getStride(buffer_handle_t buffer, uint32_t* outStride)
-{
-    int32_t intError = mFunctions.getStride(mDevice, buffer, outStride);
-    return static_cast<gralloc1_error_t>(intError);
-}
-
 static inline bool allocationSucceded(gralloc1_error_t error)
 {
     return error == GRALLOC1_ERROR_NONE || error == GRALLOC1_ERROR_NOT_SHARED;
@@ -225,6 +219,99 @@ gralloc1_error_t Device::release(buffer_handle_t buffer)
     return static_cast<gralloc1_error_t>(intError);
 }
 
+gralloc1_error_t Device::getDimensions(buffer_handle_t buffer,
+        uint32_t* outWidth, uint32_t* outHeight)
+{
+    uint32_t width = 0;
+    uint32_t height = 0;
+    int32_t intError = mFunctions.getDimensions(mDevice, buffer, &width,
+            &height);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outWidth = width;
+        *outHeight = height;
+    }
+    return error;
+}
+
+gralloc1_error_t Device::getFormat(buffer_handle_t buffer,
+        int32_t* outFormat)
+{
+    int32_t format = 0;
+    int32_t intError = mFunctions.getFormat(mDevice, buffer, &format);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outFormat = format;
+    }
+    return error;
+}
+
+gralloc1_error_t Device::getLayerCount(buffer_handle_t buffer,
+        uint32_t* outLayerCount)
+{
+    if (hasCapability(GRALLOC1_CAPABILITY_LAYERED_BUFFERS)) {
+        uint32_t layerCount = 0;
+        int32_t intError = mFunctions.getLayerCount(mDevice, buffer,
+                &layerCount);
+        auto error = static_cast<gralloc1_error_t>(intError);
+        if (error == GRALLOC1_ERROR_NONE) {
+            *outLayerCount = layerCount;
+        }
+        return error;
+    } else {
+        // Layered buffers are not supported on this device.
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+}
+
+gralloc1_error_t Device::getProducerUsage(buffer_handle_t buffer,
+        uint64_t* outProducerUsage)
+{
+    uint64_t usage = 0;
+    int32_t intError = mFunctions.getProducerUsage(mDevice, buffer, &usage);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outProducerUsage = usage;
+    }
+    return error;
+}
+
+gralloc1_error_t Device::getConsumerUsage(buffer_handle_t buffer,
+        uint64_t* outConsumerUsage)
+{
+    uint64_t usage = 0;
+    int32_t intError = mFunctions.getConsumerUsage(mDevice, buffer, &usage);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outConsumerUsage = usage;
+    }
+    return error;
+}
+
+gralloc1_error_t Device::getBackingStore(buffer_handle_t buffer,
+        uint64_t* outBackingStore)
+{
+    uint64_t store = 0;
+    int32_t intError = mFunctions.getBackingStore(mDevice, buffer, &store);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outBackingStore = store;
+    }
+    return error;
+}
+
+gralloc1_error_t Device::getStride(buffer_handle_t buffer,
+        uint32_t* outStride)
+{
+    uint32_t stride = 0;
+    int32_t intError = mFunctions.getStride(mDevice, buffer, &stride);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outStride = stride;
+    }
+    return error;
+}
+
 gralloc1_error_t Device::getNumFlexPlanes(buffer_handle_t buffer,
         uint32_t* outNumPlanes)
 {
@@ -244,7 +331,7 @@ gralloc1_error_t Device::lock(buffer_handle_t buffer,
         const sp<Fence>& acquireFence)
 {
     ALOGV("Calling lock(%p)", buffer);
-    return lockHelper(mFunctions.lock.pfn, buffer, producerUsage,
+    return lockHelper(mFunctions.lock, buffer, producerUsage,
             consumerUsage, accessRegion, outData, acquireFence);
 }
 
@@ -256,7 +343,7 @@ gralloc1_error_t Device::lockFlex(buffer_handle_t buffer,
         const sp<Fence>& acquireFence)
 {
     ALOGV("Calling lockFlex(%p)", buffer);
-    return lockHelper(mFunctions.lockFlex.pfn, buffer, producerUsage,
+    return lockHelper(mFunctions.lockFlex, buffer, producerUsage,
             consumerUsage, accessRegion, outData, acquireFence);
 }
 
@@ -268,7 +355,7 @@ gralloc1_error_t Device::lockYCbCr(buffer_handle_t buffer,
         const sp<Fence>& acquireFence)
 {
     ALOGV("Calling lockYCbCr(%p)", buffer);
-    return lockHelper(mFunctions.lockYCbCr.pfn, buffer, producerUsage,
+    return lockHelper(mFunctions.lockYCbCr, buffer, producerUsage,
             consumerUsage, accessRegion, outData, acquireFence);
 }
 
index 7ee01ad..b9e9040 100644 (file)
@@ -51,6 +51,115 @@ void Mapper::release(buffer_handle_t handle) const
             "release(%p) failed with %d", handle, error);
 }
 
+Error Mapper::getDimensions(buffer_handle_t handle,
+        uint32_t* outWidth, uint32_t* outHeight) const
+{
+    Error error = kDefaultError;
+    mMapper->getDimensions(handle,
+            [&](const auto& tmpError, const auto& tmpWidth,
+                    const auto& tmpHeight)
+            {
+                error = tmpError;
+                if (error != Error::NONE) {
+                    return;
+                }
+
+                *outWidth = tmpWidth;
+                *outHeight = tmpHeight;
+            });
+
+    return error;
+}
+
+Error Mapper::getFormat(buffer_handle_t handle, int32_t* outFormat) const
+{
+    Error error = kDefaultError;
+    mMapper->getFormat(handle,
+            [&](const auto& tmpError, const auto& tmpFormat)
+            {
+                error = tmpError;
+                if (error != Error::NONE) {
+                    return;
+                }
+
+                *outFormat = static_cast<int32_t>(tmpFormat);
+            });
+
+    return error;
+}
+
+Error Mapper::getLayerCount(buffer_handle_t handle,
+        uint32_t* outLayerCount) const
+{
+    Error error = kDefaultError;
+    mMapper->getLayerCount(handle,
+            [&](const auto& tmpError, const auto& tmpLayerCount)
+            {
+                error = tmpError;
+                if (error != Error::NONE) {
+                    return;
+                }
+
+                *outLayerCount = tmpLayerCount;
+            });
+
+    return error;
+}
+
+Error Mapper::getProducerUsage(buffer_handle_t handle,
+    uint64_t* outProducerUsage) const
+{
+    Error error = kDefaultError;
+    mMapper->getProducerUsageMask(handle,
+            [&](const auto& tmpError, const auto& tmpProducerUsage)
+            {
+                error = tmpError;
+                if (error != Error::NONE) {
+                    return;
+                }
+
+                *outProducerUsage = tmpProducerUsage;
+            });
+
+    return error;
+}
+
+Error Mapper::getConsumerUsage(buffer_handle_t handle,
+        uint64_t* outConsumerUsage) const
+{
+    Error error = kDefaultError;
+    mMapper->getConsumerUsageMask(handle,
+            [&](const auto& tmpError, const auto& tmpConsumerUsage)
+            {
+                error = tmpError;
+                if (error != Error::NONE) {
+                    return;
+                }
+
+                *outConsumerUsage = tmpConsumerUsage;
+            });
+
+    return error;
+}
+
+Error Mapper::getBackingStore(buffer_handle_t handle,
+        uint64_t* outBackingStore) const
+{
+    Error error = kDefaultError;
+    mMapper->getBackingStore(handle,
+            [&](const auto& tmpError, const auto& tmpStore)
+            {
+                error = tmpError;
+                if (error != Error::NONE) {
+                    return;
+                }
+
+                *outBackingStore = tmpStore;
+            });
+
+    return error;
+}
+
 Error Mapper::getStride(buffer_handle_t handle, uint32_t* outStride) const
 {
     Error error = kDefaultError;
@@ -69,8 +178,8 @@ Error Mapper::getStride(buffer_handle_t handle, uint32_t* outStride) const
 }
 
 Error Mapper::lock(buffer_handle_t handle,
-        uint64_t producerUsageMask,
-        uint64_t consumerUsageMask,
+        uint64_t producerUsage,
+        uint64_t consumerUsage,
         const IMapper::Rect& accessRegion,
         int acquireFence, void** outData) const
 {
@@ -84,7 +193,7 @@ Error Mapper::lock(buffer_handle_t handle,
     }
 
     Error error = kDefaultError;
-    mMapper->lock(handle, producerUsageMask, consumerUsageMask,
+    mMapper->lock(handle, producerUsage, consumerUsage,
             accessRegion, acquireFenceHandle,
             [&](const auto& tmpError, const auto& tmpData)
             {
@@ -104,8 +213,8 @@ Error Mapper::lock(buffer_handle_t handle,
 }
 
 Error Mapper::lock(buffer_handle_t handle,
-        uint64_t producerUsageMask,
-        uint64_t consumerUsageMask,
+        uint64_t producerUsage,
+        uint64_t consumerUsage,
         const IMapper::Rect& accessRegion,
         int acquireFence, FlexLayout* outLayout) const
 {
@@ -119,7 +228,7 @@ Error Mapper::lock(buffer_handle_t handle,
     }
 
     Error error = kDefaultError;
-    mMapper->lockFlex(handle, producerUsageMask, consumerUsageMask,
+    mMapper->lockFlex(handle, producerUsage, consumerUsage,
             accessRegion, acquireFenceHandle,
             [&](const auto& tmpError, const auto& tmpLayout)
             {
index 07164a4..b544426 100644 (file)
@@ -50,8 +50,8 @@ GraphicBuffer::GraphicBuffer()
     height =
     stride =
     format =
-    layerCount =
     usage  = 0;
+    layerCount = 0;
     handle = NULL;
 }
 
@@ -64,16 +64,16 @@ GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
     height =
     stride =
     format =
-    layerCount =
     usage  = 0;
+    layerCount = 0;
     handle = NULL;
-    mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage,
+    mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage, inUsage,
             std::move(requestorName));
 }
 
 GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
-        PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage,
-        std::string requestorName)
+        PixelFormat inFormat, uint32_t inLayerCount, uint64_t producerUsage,
+        uint64_t consumerUsage, std::string requestorName)
     : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
       mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
 {
@@ -81,11 +81,11 @@ GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
     height =
     stride =
     format =
-    layerCount =
     usage  = 0;
+    layerCount = 0;
     handle = NULL;
-    mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage,
-            std::move(requestorName));
+    mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount,
+            producerUsage, consumerUsage, std::move(requestorName));
 }
 
 GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
@@ -104,6 +104,24 @@ GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
     handle = inHandle;
 }
 
+GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
+        PixelFormat inFormat, uint32_t inLayerCount, uint32_t inProducerUsage,
+        uint32_t inConsumerUsage, uint32_t inStride,
+        native_handle_t* inHandle, bool keepOwnership)
+    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
+      mBufferMapper(GraphicBufferMapper::get()),
+      mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
+{
+    width  = static_cast<int>(inWidth);
+    height = static_cast<int>(inHeight);
+    stride = static_cast<int>(inStride);
+    format = inFormat;
+    layerCount = inLayerCount;
+    usage  = static_cast<int>(inConsumerUsage | inProducerUsage);
+    handle = inHandle;
+}
+
+
 GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership)
     : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
       mBufferMapper(GraphicBufferMapper::get()),
@@ -177,7 +195,7 @@ status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight,
         allocator.free(handle);
         handle = 0;
     }
-    return initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage,
+    return initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, inUsage,
             "[Reallocation]");
 }
 
@@ -193,19 +211,20 @@ bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
 }
 
 status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight,
-        PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage,
-        std::string requestorName)
+        PixelFormat inFormat, uint32_t inLayerCount, uint64_t inProducerUsage,
+        uint64_t inConsumerUsage, std::string requestorName)
 {
     GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
     uint32_t outStride = 0;
     status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount,
-            inUsage, &handle, &outStride, mId, std::move(requestorName));
+            inProducerUsage, inConsumerUsage, &handle, &outStride, mId,
+            std::move(requestorName));
     if (err == NO_ERROR) {
         width = static_cast<int>(inWidth);
         height = static_cast<int>(inHeight);
         format = inFormat;
         layerCount = inLayerCount;
-        usage = static_cast<int>(inUsage);
+        usage = static_cast<int>(inProducerUsage | inConsumerUsage);
         stride = static_cast<int>(outStride);
     }
     return err;
@@ -268,6 +287,12 @@ status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd)
 status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect,
         void** vaddr, int fenceFd)
 {
+    return lockAsync(inUsage, inUsage, rect, vaddr, fenceFd);
+}
+
+status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage,
+        uint64_t inConsumerUsage, const Rect& rect, void** vaddr, int fenceFd)
+{
     if (rect.left < 0 || rect.right  > width ||
         rect.top  < 0 || rect.bottom > height) {
         ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
@@ -275,8 +300,8 @@ status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect,
                 width, height);
         return BAD_VALUE;
     }
-    status_t res = getBufferMapper().lockAsync(handle, inUsage, rect, vaddr,
-            fenceFd);
+    status_t res = getBufferMapper().lockAsync(handle, inProducerUsage,
+            inConsumerUsage, rect, vaddr, fenceFd);
     return res;
 }
 
index 07ad4c1..b14110e 100644 (file)
@@ -63,15 +63,19 @@ void GraphicBufferAllocator::dump(String8& result) const
     for (size_t i=0 ; i<c ; i++) {
         const alloc_rec_t& rec(list.valueAt(i));
         if (rec.size) {
-            snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%08x | %s\n",
+            snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64
+                    ", 0x%" PRIx64 " | %s\n",
                     list.keyAt(i), rec.size/1024.0,
                     rec.width, rec.stride, rec.height, rec.layerCount, rec.format,
-                    rec.usage, rec.requestorName.c_str());
+                    rec.producerUsage, rec.consumerUsage,
+                    rec.requestorName.c_str());
         } else {
-            snprintf(buffer, SIZE, "%10p: unknown     | %4u (%4u) x %4u | %4u | %8X | 0x%08x | %s\n",
+            snprintf(buffer, SIZE, "%10p: unknown     | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64
+                    ", 0x%" PRIx64 " | %s\n",
                     list.keyAt(i),
                     rec.width, rec.stride, rec.height, rec.layerCount, rec.format,
-                    rec.usage, rec.requestorName.c_str());
+                    rec.producerUsage, rec.consumerUsage,
+                    rec.requestorName.c_str());
         }
         result.append(buffer);
         total += rec.size;
@@ -102,7 +106,8 @@ class HalBuffer {
 public:
     HalBuffer(const Gralloc2::Allocator* allocator,
             uint32_t width, uint32_t height,
-            PixelFormat format, uint32_t layerCount, uint32_t usage)
+            PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
+            uint64_t consumerUsage)
         : mAllocator(allocator), mBufferValid(false)
     {
         Gralloc2::IAllocatorClient::BufferDescriptorInfo info = {};
@@ -110,14 +115,16 @@ public:
         info.height = height;
         info.format = static_cast<Gralloc2::PixelFormat>(format);
         info.layerCount = layerCount;
-        info.producerUsageMask = usage;
-        info.consumerUsageMask = usage;
+        info.producerUsageMask = producerUsage;
+        info.consumerUsageMask = consumerUsage;
 
         Gralloc2::BufferDescriptor descriptor;
         auto error = mAllocator->createBufferDescriptor(info, &descriptor);
         if (error != Gralloc2::Error::NONE) {
-            ALOGE("Failed to create desc (%u x %u) layerCount %u format %d usage %u: %d",
-                    width, height, layerCount, format, usage, error);
+            ALOGE("Failed to create desc (%u x %u) layerCount %u format %d producerUsage %" PRIx64
+                    " consumerUsage %" PRIx64 ": %d",
+                    width, height, layerCount, format, producerUsage,
+                    consumerUsage, error);
             return;
         }
 
@@ -127,8 +134,10 @@ public:
         }
 
         if (error != Gralloc2::Error::NONE) {
-            ALOGE("Failed to allocate (%u x %u) layerCount %u format %d usage %u: %d",
-                    width, height, layerCount, format, usage, error);
+            ALOGE("Failed to allocate (%u x %u) layerCount %u format %d producerUsage %" PRIx64
+                    " consumerUsage %" PRIx64 ": %d",
+                    width, height, layerCount, format, producerUsage,
+                    consumerUsage, error);
             mAllocator->destroyBufferDescriptor(descriptor);
             return;
         }
@@ -195,9 +204,9 @@ private:
 } // namespace
 
 status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
-        PixelFormat format, uint32_t layerCount, uint32_t usage,
-        buffer_handle_t* handle, uint32_t* stride, uint64_t graphicBufferId,
-        std::string requestorName)
+        PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
+        uint64_t consumerUsage, buffer_handle_t* handle, uint32_t* stride,
+        uint64_t graphicBufferId, std::string requestorName)
 {
     ATRACE_CALL();
 
@@ -210,13 +219,10 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
     if (layerCount < 1)
         layerCount = 1;
 
-    // Filter out any usage bits that should not be passed to the gralloc module
-    usage &= GRALLOC_USAGE_ALLOC_MASK;
-
     gralloc1_error_t error;
     if (mAllocator->valid()) {
         HalBuffer buffer(mAllocator.get(), width, height, format, layerCount,
-                usage);
+                producerUsage, consumerUsage);
         if (!buffer.exportHandle(mMapper, handle, stride)) {
             return NO_MEMORY;
         }
@@ -247,22 +253,26 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
             return BAD_VALUE;
         }
         error = descriptor->setProducerUsage(
-                static_cast<gralloc1_producer_usage_t>(usage));
+                static_cast<gralloc1_producer_usage_t>(producerUsage));
         if (error != GRALLOC1_ERROR_NONE) {
-            ALOGE("Failed to set producer usage to %u: %d", usage, error);
+            ALOGE("Failed to set producer usage to %" PRIx64 ": %d",
+                    producerUsage, error);
             return BAD_VALUE;
         }
         error = descriptor->setConsumerUsage(
-                static_cast<gralloc1_consumer_usage_t>(usage));
+                static_cast<gralloc1_consumer_usage_t>(consumerUsage));
         if (error != GRALLOC1_ERROR_NONE) {
-            ALOGE("Failed to set consumer usage to %u: %d", usage, error);
+            ALOGE("Failed to set consumer usage to %" PRIx64 ": %d",
+                    consumerUsage, error);
             return BAD_VALUE;
         }
 
         error = mDevice->allocate(descriptor, graphicBufferId, handle);
         if (error != GRALLOC1_ERROR_NONE) {
-            ALOGE("Failed to allocate (%u x %u) layerCount %u format %d usage %u: %d",
-                    width, height, layerCount, format, usage, error);
+            ALOGE("Failed to allocate (%u x %u) layerCount %u format %d "
+                    "producerUsage %" PRIx64 " consumerUsage %" PRIx64 ": %d",
+                    width, height, layerCount, format, producerUsage,
+                    consumerUsage, error);
             return NO_MEMORY;
         }
 
@@ -282,7 +292,8 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
         rec.stride = *stride;
         rec.format = format;
         rec.layerCount = layerCount;
-        rec.usage = usage;
+        rec.producerUsage = producerUsage;
+        rec.consumerUsage = consumerUsage;
         rec.size = static_cast<size_t>(height * (*stride) * bpp);
         rec.requestorName = std::move(requestorName);
         list.add(*handle, rec);
index 1ff934b..a3b6e18 100644 (file)
@@ -63,7 +63,14 @@ status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
     if (mMapper->valid()) {
         error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
     } else {
+        // This always returns GRALLOC1_BAD_HANDLE when handle is from a
+        // remote process and mDevice is backed by Gralloc1On0Adapter.
         error = mDevice->retain(handle);
+        if (error == GRALLOC1_ERROR_BAD_HANDLE &&
+                mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+            ALOGE("registerBuffer by handle is not supported with "
+                  "Gralloc1On0Adapter");
+        }
     }
 
     ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
@@ -117,6 +124,140 @@ static inline gralloc1_rect_t asGralloc1Rect(const Rect& rect) {
     return outRect;
 }
 
+
+status_t GraphicBufferMapper::getDimensions(buffer_handle_t handle,
+        uint32_t* outWidth, uint32_t* outHeight) const
+{
+    ATRACE_CALL();
+
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        mMapper->getDimensions(handle, outWidth, outHeight);
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        error = mDevice->getDimensions(handle, outWidth, outHeight);
+    }
+
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getDimensions(%p, ...): failed %d",
+            handle, error);
+
+    return error;
+}
+
+status_t GraphicBufferMapper::getFormat(buffer_handle_t handle,
+        int32_t* outFormat) const
+{
+    ATRACE_CALL();
+
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        mMapper->getFormat(handle, outFormat);
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        error = mDevice->getFormat(handle, outFormat);
+    }
+
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getFormat(%p, ...): failed %d",
+            handle, error);
+
+    return error;
+}
+
+status_t GraphicBufferMapper::getLayerCount(buffer_handle_t handle,
+        uint32_t* outLayerCount) const
+{
+    ATRACE_CALL();
+
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        mMapper->getLayerCount(handle, outLayerCount);
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        error = mDevice->getLayerCount(handle, outLayerCount);
+    }
+
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getLayerCount(%p, ...): failed %d",
+            handle, error);
+
+    return error;
+}
+
+status_t GraphicBufferMapper::getProducerUsage(buffer_handle_t handle,
+        uint64_t* outProducerUsage) const
+{
+    ATRACE_CALL();
+
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        mMapper->getProducerUsage(handle, outProducerUsage);
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        error = mDevice->getProducerUsage(handle, outProducerUsage);
+    }
+
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE,
+            "getProducerUsage(%p, ...): failed %d", handle, error);
+
+    return error;
+}
+
+status_t GraphicBufferMapper::getConsumerUsage(buffer_handle_t handle,
+        uint64_t* outConsumerUsage) const
+{
+    ATRACE_CALL();
+
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        mMapper->getConsumerUsage(handle, outConsumerUsage);
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        error = mDevice->getConsumerUsage(handle, outConsumerUsage);
+    }
+
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE,
+            "getConsumerUsage(%p, ...): failed %d", handle, error);
+
+    return error;
+}
+
+status_t GraphicBufferMapper::getBackingStore(buffer_handle_t handle,
+        uint64_t* outBackingStore) const
+{
+    ATRACE_CALL();
+
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        mMapper->getBackingStore(handle, outBackingStore);
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        error = mDevice->getBackingStore(handle, outBackingStore);
+    }
+
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE,
+            "getBackingStore(%p, ...): failed %d", handle, error);
+
+    return error;
+}
+
+status_t GraphicBufferMapper::getStride(buffer_handle_t handle,
+        uint32_t* outStride) const
+{
+    ATRACE_CALL();
+
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        mMapper->getStride(handle, outStride);
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        error = mDevice->getStride(handle, outStride);
+    }
+
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getStride(%p, ...): failed %d",
+            handle, error);
+
+    return error;
+}
+
 status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
         const Rect& bounds, void** vaddr)
 {
@@ -143,6 +284,13 @@ status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
 status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
         uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
 {
+    return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd);
+}
+
+status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
+        uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds,
+        void** vaddr, int fenceFd)
+{
     ATRACE_CALL();
 
     gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
@@ -151,12 +299,13 @@ status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
         const Gralloc2::IMapper::Rect& accessRect =
             *reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
         error = static_cast<gralloc1_error_t>(mMapper->lock(
-                    handle, usage, usage, accessRect, fenceFd, vaddr));
+                    handle, producerUsage, consumerUsage, accessRect,
+                    fenceFd, vaddr));
     } else {
         sp<Fence> fence = new Fence(fenceFd);
         error = mDevice->lock(handle,
-                static_cast<gralloc1_producer_usage_t>(usage),
-                static_cast<gralloc1_consumer_usage_t>(usage),
+                static_cast<gralloc1_producer_usage_t>(producerUsage),
+                static_cast<gralloc1_consumer_usage_t>(consumerUsage),
                 &accessRegion, vaddr, fence);
     }
 
similarity index 98%
rename from libs/gui/GraphicsEnv.cpp
rename to libs/ui/GraphicsEnv.cpp
index 68f0f98..1d20424 100644 (file)
@@ -16,7 +16,7 @@
 
 //#define LOG_NDEBUG 1
 #define LOG_TAG "GraphicsEnv"
-#include <gui/GraphicsEnv.h>
+#include <ui/GraphicsEnv.h>
 
 #include <mutex>
 
index 511f68a..39adc5e 100644 (file)
 
 #include <ui/HdrCapabilities.h>
 
-#include <binder/Parcel.h>
-
 namespace android {
 
-status_t HdrCapabilities::writeToParcel(Parcel* parcel) const
-{
-    status_t result = parcel->writeInt32Vector(mSupportedHdrTypes);
-    if (result != OK) {
-        return result;
-    }
-    result = parcel->writeFloat(mMaxLuminance);
-    if (result != OK) {
-        return result;
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundefined-reinterpret-cast"
+#endif
+
+HdrCapabilities::~HdrCapabilities() = default;
+HdrCapabilities::HdrCapabilities(HdrCapabilities&& other) = default;
+HdrCapabilities& HdrCapabilities::operator=(HdrCapabilities&& other) = default;
+
+
+size_t HdrCapabilities::getFlattenedSize() const {
+    return  sizeof(mMaxLuminance) +
+            sizeof(mMaxAverageLuminance) +
+            sizeof(mMinLuminance) +
+            sizeof(int32_t) +
+            mSupportedHdrTypes.size() * sizeof(int32_t);
+}
+
+status_t HdrCapabilities::flatten(void* buffer, size_t size) const {
+
+    if (size < getFlattenedSize()) {
+        return NO_MEMORY;
     }
-    result = parcel->writeFloat(mMaxAverageLuminance);
-    if (result != OK) {
-        return result;
+
+    int32_t* const buf = static_cast<int32_t*>(buffer);
+    reinterpret_cast<float&>(buf[0]) = mMaxLuminance;
+    reinterpret_cast<float&>(buf[1]) = mMaxAverageLuminance;
+    reinterpret_cast<float&>(buf[2]) = mMinLuminance;
+    buf[3] = static_cast<int32_t>(mSupportedHdrTypes.size());
+    for (size_t i = 0, c = mSupportedHdrTypes.size(); i < c; ++i) {
+        buf[4 + i] = mSupportedHdrTypes[i];
     }
-    result = parcel->writeFloat(mMinLuminance);
-    return result;
+    return NO_ERROR;
 }
 
-status_t HdrCapabilities::readFromParcel(const Parcel* parcel)
-{
-    status_t result = parcel->readInt32Vector(&mSupportedHdrTypes);
-    if (result != OK) {
-        return result;
+status_t HdrCapabilities::unflatten(void const* buffer, size_t size) {
+
+    size_t minSize = sizeof(mMaxLuminance) +
+                     sizeof(mMaxAverageLuminance) +
+                     sizeof(mMinLuminance) +
+                     sizeof(int32_t);
+
+    if (size < minSize) {
+        return NO_MEMORY;
     }
-    result = parcel->readFloat(&mMaxLuminance);
-    if (result != OK) {
-        return result;
+
+    int32_t const * const buf = static_cast<int32_t const *>(buffer);
+    const size_t itemCount = size_t(buf[3]);
+
+    // check the buffer is large enough
+    if (size < minSize + itemCount * sizeof(int32_t)) {
+        return BAD_VALUE;
     }
-    result = parcel->readFloat(&mMaxAverageLuminance);
-    if (result != OK) {
-        return result;
+
+    mMaxLuminance        = reinterpret_cast<float const&>(buf[0]);
+    mMaxAverageLuminance = reinterpret_cast<float const&>(buf[1]);
+    mMinLuminance        = reinterpret_cast<float const&>(buf[2]);
+    if (itemCount) {
+        mSupportedHdrTypes.reserve(itemCount);
+        for (size_t i = 0; i < itemCount; ++i) {
+            mSupportedHdrTypes[i] = buf[4 + i];
+        }
     }
-    result = parcel->readFloat(&mMinLuminance);
-    return result;
+    return NO_ERROR;
 }
 
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
 } // namespace android
index 6150b35..1c1a5e0 100644 (file)
@@ -205,7 +205,7 @@ struct ViewerParams {
 
 struct DisplayRPC {
   // Service path.
-  static constexpr char kClientPath[] = "system/display/client";
+  static constexpr char kClientPath[] = "system/vr/display/client";
 
   // Op codes.
   enum {
@@ -253,7 +253,7 @@ struct DisplayRPC {
 
 struct DisplayManagerRPC {
   // Service path.
-  static constexpr char kClientPath[] = "system/display/manager";
+  static constexpr char kClientPath[] = "system/vr/display/manager";
 
   // Op codes.
   enum {
@@ -287,7 +287,7 @@ struct ScreenshotData {
 
 struct DisplayScreenshotRPC {
   // Service path.
-  static constexpr char kClientPath[] = "system/display/screenshot";
+  static constexpr char kClientPath[] = "system/vr/display/screenshot";
 
   // Op codes.
   enum {
@@ -314,7 +314,7 @@ struct VSyncSchedInfo {
 
 struct DisplayVSyncRPC {
   // Service path.
-  static constexpr char kClientPath[] = "system/display/vsync";
+  static constexpr char kClientPath[] = "system/vr/display/vsync";
 
   // Op codes.
   enum {
index a0fb313..c928a08 100644 (file)
@@ -26,7 +26,10 @@ int VSyncClient::Wait(int64_t* timestamp_ns) {
           status.GetErrorMessage().c_str());
     return -status.error();
   }
-  *timestamp_ns = status.get();
+
+  if (timestamp_ns != nullptr) {
+    *timestamp_ns = status.get();
+  }
   return 0;
 }
 
index 59029d8..13090ca 100644 (file)
@@ -308,7 +308,7 @@ void DistortionRenderer::EdsShader::load(const char* vertex,
   if (blend_with_previous_layer) {
     // Check for unsupported shader combinations:
     LOG_ALWAYS_FATAL_IF(num_layers != 1);
-    LOG_ALWAYS_FATAL_IF(!use_alpha_vignette);
+    LOG_ALWAYS_FATAL_IF(use_alpha_vignette);
     if (kUseFramebufferReadback)
       frag_builder += "#define BLEND_WITH_PREVIOUS_LAYER\n";
   }
index be78605..0daf2ea 100644 (file)
@@ -19,10 +19,9 @@ include_dirs := \
 
 # Java platform library for the system implementation of the GVR API.
 include $(CLEAR_VARS)
-LOCAL_MODULE := gvr_platform
-LOCAL_MODULE_STEM := com.google.vr.gvr.platform
+LOCAL_MODULE := com.google.vr.gvr.platform
 LOCAL_REQUIRED_MODULES := libgvr_system_loader libgvr_system
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES := $(call all-java-files-under, java)
 include $(BUILD_JAVA_LIBRARY)
 
 # Library to perform dlopen on the actual platform library.
index 5c5cc62..381175c 100644 (file)
@@ -1,32 +1,38 @@
 package com.google.vr.gvr.platform;
 
+import android.os.SystemProperties;
+
 /**
  * Auxiliary class to load the system implementation of the GVR API.
+ * @hide
  */
 public class Loader {
 
-  /**
-   * Opens a shared library containing the system implementation for the GVR
-   * API and returns the handle to it.
-   *
-   * @return A Long object describing the handle returned by dlopen.
-   */
-  public static Long loadLibrary() {
-    // Note: we cannot safely do caller verifications here, so instead we do
-    // them in the service side. This means that private API symbols will be
-    // visible to any app adding the appropriate <uses-library> in their
-    // manifest, but any requests to such APIs will fail if not done from a
-    // trusted package like VrCore.
-    //
-    // Trusted packages are defined by (package name, signature) pairs in within
-    // a system service, and both must match.
-
-    // Load a thin JNI library that runs dlopen on request.
-    System.loadLibrary("gvr_system_loader");
-
-    // Performs dlopen on the library and returns the handle.
-    return nativeLoadLibrary("libgvr_system.so");
-  }
-
-  private static native long nativeLoadLibrary(String library);
+    private static final String VR_MODE_BOOT = "ro.boot.vr";
+
+    /**
+     * Opens a shared library containing the system implementation for the GVR API and returns the
+     * handle to it.
+     *
+     * @return A Long object describing the handle returned by dlopen.
+     */
+    public static Long loadLibrary() {
+        // Note: caller verifications cannot be safely done here. Any app can find and use this API.
+        // Any sensitive functions must have appropriate checks on the service side.
+
+        // Load a thin JNI library that runs dlopen on request.
+        System.loadLibrary("gvr_system_loader");
+
+        // Performs dlopen on the library and returns the handle.
+        return nativeLoadLibrary("libgvr_system.so");
+    }
+
+    /**
+     * Returns true if this device boots directly in VR mode.
+     */
+    public static boolean getVrBoot() {
+        return SystemProperties.getBoolean(VR_MODE_BOOT, false);
+    }
+
+    private static native long nativeLoadLibrary(String library);
 }
index 1d0ba50..bfd5956 100644 (file)
Binary files a/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr.so and b/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr.so differ
index 905ca64..c3012b1 100644 (file)
Binary files a/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr_audio.so and b/libs/vr/libgvr/prebuilt/lib/android_arm/libgvr_audio.so differ
index d62f7ca..6608c25 100644 (file)
Binary files a/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr.so and b/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr.so differ
index e342f6a..b1d7690 100644 (file)
Binary files a/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr_audio.so and b/libs/vr/libgvr/prebuilt/lib/android_arm64/libgvr_audio.so differ
index 8092138..f7f7786 100644 (file)
Binary files a/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr.so and b/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr.so differ
index 3fe5b2c..97aec40 100644 (file)
Binary files a/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr_audio.so and b/libs/vr/libgvr/prebuilt/lib/android_x86/libgvr_audio.so differ
index 3bcf60e..2e2dbc1 100644 (file)
Binary files a/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr.so and b/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr.so differ
index 2f2d834..cd8d0e0 100644 (file)
Binary files a/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr_audio.so and b/libs/vr/libgvr/prebuilt/lib/android_x86_64/libgvr_audio.so differ
index 13147fe..9c1fbd0 100644 (file)
Binary files a/libs/vr/libgvr/prebuilt/lib/common_library.aar and b/libs/vr/libgvr/prebuilt/lib/common_library.aar differ
index fa8a655..5eb6e3d 100644 (file)
@@ -512,7 +512,8 @@ void gvr_distort_to_screen(
 }
 
 bool gvr_is_feature_supported(const gvr_context* /*gvr*/, int32_t feature) {
-  return feature == GVR_FEATURE_ASYNC_REPROJECTION;
+  return feature == GVR_FEATURE_ASYNC_REPROJECTION ||
+      feature == GVR_FEATURE_HEAD_POSE_6DOF;
 }
 
 /////////////////////////////////////////////////////////////////////////////
index 908030e..0616d46 100644 (file)
@@ -7,7 +7,7 @@
 extern "C" {
 #endif
 
-#define DVR_POSE_SERVICE_BASE "system/pose"
+#define DVR_POSE_SERVICE_BASE "system/vr/pose"
 #define DVR_POSE_SERVICE_CLIENT (DVR_POSE_SERVICE_BASE "/client")
 
 enum {
index 7e8b9e5..b2ebd95 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef ANDROID_DVR_SENSOR_IPC_H_
 #define ANDROID_DVR_SENSOR_IPC_H_
 
-#define DVR_SENSOR_SERVICE_BASE "system/sensors"
+#define DVR_SENSOR_SERVICE_BASE "system/vr/sensors"
 
 #define DVR_SENSOR_SERVICE_CLIENT (DVR_SENSOR_SERVICE_BASE "/client")
 
similarity index 79%
rename from services/vr/vr_manager/Android.mk
rename to libs/vr/libvr_manager/Android.mk
index 54b1c1a..e9987f7 100644 (file)
 
 LOCAL_PATH := $(call my-dir)
 
+exported_include_dirs := \
+  $(LOCAL_PATH)/include
+
+include_dirs := \
+  frameworks/native/include/vr/vr_manager \
+  $(exported_include_dirs)
+
 src_files := \
   vr_manager.cpp \
-
-inc_files := \
-  frameworks/native/include/vr/vr_manager
+  trusted_uids.cpp
 
 static_libs := \
   libutils \
@@ -26,13 +31,12 @@ static_libs := \
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(src_files)
-LOCAL_C_INCLUDES := $(inc_files)
+LOCAL_C_INCLUDES := $(include_dirs)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(exported_include_dirs)
 LOCAL_CFLAGS += -Wall
 LOCAL_CFLAGS += -Werror
 LOCAL_CFLAGS += -Wunused
 LOCAL_CFLAGS += -Wunreachable-code
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(inc_files)
-#LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
 LOCAL_STATIC_LIBRARIES := $(static_libs)
 LOCAL_MODULE := libvr_manager
 include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h b/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
new file mode 100644 (file)
index 0000000..4496fbf
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef ANDROID_DVR_TRUSTED_UIDS_H_
+#define ANDROID_DVR_TRUSTED_UIDS_H_
+
+#include <sys/types.h>
+
+namespace android {
+namespace dvr {
+
+/**
+ * Tells if a provided UID can be trusted to access restricted VR APIs.
+ *
+ * UID trust is based on the android.permission.RESTRICTED_VR_ACCESS permission.
+ * AID_SYSTEM and AID_ROOT are automatically trusted by Android.
+ *
+ * UIDs are guaranteed not to be reused until the next reboot even in case
+ * of package reinstall. For performance reasons this method caches results by
+ * default, as otherwise every check would trigger a Java call.
+ *
+ * This function is thread-safe.
+ *
+ * @param uid The uid to check.
+ * @param use_cache If true any cached result for the provided uid will be
+ *     reused. If false this call will reach the Application Manager Service
+ *     in Java to get updated values. Any updates will be stored in the cache.
+ * @return true if the uid is trusted, false if not or if the VR Manager Service
+ *         could not be reached to verify the uid.
+ */
+bool IsTrustedUid(uid_t uid, bool use_cache = true);
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_TRUSTED_UIDS_H_
diff --git a/libs/vr/libvr_manager/trusted_uids.cpp b/libs/vr/libvr_manager/trusted_uids.cpp
new file mode 100644 (file)
index 0000000..4228a05
--- /dev/null
@@ -0,0 +1,51 @@
+#include "private/dvr/trusted_uids.h"
+
+#include <mutex>
+#include <unordered_map>
+
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
+#include <private/android_filesystem_config.h>
+#include <utils/String16.h>
+#include <vr/vr_manager/vr_manager.h>
+
+namespace android {
+namespace dvr {
+
+bool IsTrustedUid(uid_t uid, bool use_cache) {
+  static std::unordered_map<uid_t, bool> uid_cache;
+  static std::mutex uid_cache_mutex;
+
+  // Whitelist requests from the system UID.
+  // These are already whitelisted by the permission service, but it might not
+  // be available if the ActivityManagerService is up during boot.
+  // This ensures the correct result for system services while booting up.
+  if (uid == AID_SYSTEM)
+    return true;
+
+  std::lock_guard<std::mutex> lock(uid_cache_mutex);
+
+  if (use_cache) {
+    auto it = uid_cache.find(uid);
+    if (it != uid_cache.end())
+      return it->second;
+  }
+
+  sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+  if (binder == 0) {
+    ALOGW("Could not access permission service");
+    return false;
+  }
+
+  // Note: we ignore the pid because it's only used to automatically reply
+  // true if the caller is the Activity Manager Service.
+  bool trusted = interface_cast<IPermissionController>(binder)->checkPermission(
+      String16("android.permission.RESTRICTED_VR_ACCESS"), -1, uid);
+
+  // Cache the information for this uid to avoid future Java calls.
+  uid_cache[uid] = trusted;
+  return trusted;
+}
+
+}  // namespace dvr
+}  // namespace android
index 6b5e7cc..1706f30 100644 (file)
@@ -45,6 +45,7 @@ staticLibraries := \
        libperformance \
        libsensor \
        libpdx_default_transport \
+       libvr_manager \
 
 sharedLibraries := \
        android.dvr.composer@1.0 \
@@ -76,11 +77,6 @@ LOCAL_CFLAGS += -DLOG_TAG=\"vr_flinger\"
 LOCAL_CFLAGS += -DTRACE=0
 LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_GRAPHICS
 LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-ifeq ($(TARGET_USES_QCOM_BSP), true)
-    LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
-    LOCAL_C_INCLUDES += hardware/qcom/display/libqdutils
-    LOCAL_SHARED_LIBRARIES += libqdutils
-endif
 LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
 LOCAL_WHOLE_STATIC_LIBRARIES := $(staticLibraries)
 LOCAL_MODULE := libvrflinger
index c464c98..5309acf 100644 (file)
@@ -318,6 +318,10 @@ int DisplayService::UpdateActiveDisplaySurfaces() {
   return hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
 }
 
+void DisplayService::OnHardwareComposerRefresh() {
+  hardware_composer_.OnHardwareComposerRefresh();
+}
+
 void DisplayService::SetDisplayConfigurationUpdateNotifier(
     DisplayConfigurationUpdateNotifier update_notifier) {
   update_notifier_ = update_notifier;
index ebd97de..5de4f1d 100644 (file)
@@ -68,6 +68,8 @@ class DisplayService : public pdx::ServiceBase<DisplayService> {
     }
   }
 
+  void OnHardwareComposerRefresh();
+
  private:
   friend BASE;
   friend DisplaySurface;
index e1729f8..7c821bf 100644 (file)
@@ -381,6 +381,15 @@ void DisplaySurface::OnPostConsumer(
   ATRACE_NAME("DisplaySurface::OnPostConsumer");
   std::lock_guard<std::mutex> autolock(lock_);
 
+  if (!IsVisible()) {
+    ALOGD_IF(TRACE,
+             "DisplaySurface::OnPostConsumer: Discarding buffer_id=%d on "
+             "invisible surface.",
+             consumer->id());
+    consumer->Discard();
+    return;
+  }
+
   if (posted_buffers_.IsFull()) {
     ALOGE("Error: posted buffers full, overwriting");
     posted_buffers_.PopBack();
index e0b592e..e6ed665 100644 (file)
@@ -104,11 +104,10 @@ HardwareComposer::HardwareComposer(Hwc2::Composer* hwc2_hidl)
       display_transform_(HWC_TRANSFORM_NONE),
       display_surfaces_updated_(false),
       hardware_layers_need_update_(false),
-      display_on_(false),
       active_layer_count_(0),
       gpu_layer_(nullptr),
+      post_thread_state_(PostThreadState::kPaused),
       terminate_post_thread_event_fd_(-1),
-      pause_post_thread_(true),
       backlight_brightness_fd_(-1),
       primary_display_vsync_event_fd_(-1),
       primary_display_wait_pp_fd_(-1),
@@ -124,19 +123,17 @@ HardwareComposer::HardwareComposer(Hwc2::Composer* hwc2_hidl)
 }
 
 HardwareComposer::~HardwareComposer(void) {
-  if (!IsSuspended()) {
-    Suspend();
-  }
+  Suspend();
 }
 
 bool HardwareComposer::Resume() {
-  std::lock_guard<std::mutex> autolock(layer_mutex_);
-
-  if (!IsSuspended()) {
-    ALOGE("HardwareComposer::Resume: HardwareComposer is already running.");
+  std::lock_guard<std::mutex> post_thread_lock(post_thread_state_mutex_);
+  if (post_thread_state_ == PostThreadState::kRunning) {
     return false;
   }
 
+  std::lock_guard<std::mutex> layer_lock(layer_mutex_);
+
   int32_t ret = HWC2_ERROR_NONE;
 
   static const uint32_t attributes[] = {
@@ -211,11 +208,15 @@ bool HardwareComposer::Resume() {
     layer->Initialize(hwc2_hidl_.get(), &native_display_metrics_);
   }
 
+#if ENABLE_BACKLIGHT_BRIGHTNESS
+  // TODO(hendrikw): This isn't required at the moment. It's possible that there
+  //                 is another method to access this when needed.
   // Open the backlight brightness control sysfs node.
   backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
   ALOGW_IF(!backlight_brightness_fd_,
            "HardwareComposer: Failed to open backlight brightness control: %s",
            strerror(errno));
+#endif // ENABLE_BACKLIGHT_BRIGHTNESS
 
   // Open the vsync event node for the primary display.
   // TODO(eieio): Move this into a platform-specific class.
@@ -246,39 +247,49 @@ bool HardwareComposer::Resume() {
   pose_client_ = dvrPoseCreate();
   ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
 
-  // Variables used to control the post thread state
-  pause_post_thread_ = false;
-  terminate_post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-
+  terminate_post_thread_event_fd_.Reset(
+      eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
   LOG_ALWAYS_FATAL_IF(
       !terminate_post_thread_event_fd_,
       "HardwareComposer: Failed to create terminate PostThread event fd : %s",
       strerror(errno));
 
+  post_thread_state_ = PostThreadState::kRunning;
+  post_thread_state_cond_var_.notify_all();
+
   // If get_id() is the default thread::id object, it has not been created yet
   if (post_thread_.get_id() == std::thread::id()) {
     post_thread_ = std::thread(&HardwareComposer::PostThread, this);
   } else {
     UpdateDisplayState();
-    thread_pause_semaphore_.notify_one();
   }
 
   return true;
 }
 
 bool HardwareComposer::Suspend() {
-  // Wait for any pending layer operations to finish
-  std::unique_lock<std::mutex> layer_lock(layer_mutex_);
-
-  if (IsSuspended()) {
-    ALOGE("HardwareComposer::Suspend: HardwareComposer is already suspended.");
+  std::unique_lock<std::mutex> post_thread_lock(post_thread_state_mutex_);
+  if (post_thread_state_ == PostThreadState::kPaused) {
     return false;
   }
 
-  PausePostThread();
+  post_thread_state_ = PostThreadState::kPauseRequested;
+
+  int error = eventfd_write(terminate_post_thread_event_fd_.Get(), 1);
+  ALOGE_IF(error,
+           "HardwareComposer::Suspend: could not write post "
+           "thread termination event fd : %d",
+           error);
+
+  post_thread_state_cond_var_.wait(
+      post_thread_lock,
+      [this] { return post_thread_state_ == PostThreadState::kPaused; });
+  terminate_post_thread_event_fd_.Close();
+
+  // Wait for any pending layer operations to finish
+  std::lock_guard<std::mutex> layer_lock(layer_mutex_);
 
   EnableVsync(false);
-  SetPowerMode(HWC_DISPLAY_PRIMARY, HWC2_POWER_MODE_OFF);
 
   backlight_brightness_fd_.Close();
   primary_display_vsync_event_fd_.Close();
@@ -304,19 +315,6 @@ bool HardwareComposer::Suspend() {
   return true;
 }
 
-void HardwareComposer::PausePostThread() {
-  pause_post_thread_ = true;
-
-  int error = eventfd_write(terminate_post_thread_event_fd_.Get(), 1);
-  ALOGE_IF(error,
-           "HardwareComposer::PausePostThread: could not write post "
-           "thread termination event fd : %d",
-           error);
-
-  std::unique_lock<std::mutex> wait_for_thread(thread_pause_mutex_);
-  terminate_post_thread_event_fd_.Close();
-}
-
 DisplayMetrics HardwareComposer::GetHmdDisplayMetrics() const {
   vec2i screen_size(display_metrics_.width, display_metrics_.height);
   DisplayOrientation orientation =
@@ -378,18 +376,6 @@ int32_t HardwareComposer::Present(hwc2_display_t display) {
   return error;
 }
 
-int32_t HardwareComposer::SetPowerMode(hwc2_display_t display,
-                                       hwc2_power_mode_t mode) {
-  if (mode == HWC2_POWER_MODE_OFF) {
-    EnableVsync(false);
-  }
-
-  display_on_ = mode != HWC2_POWER_MODE_OFF;
-
-  return (int32_t)hwc2_hidl_->setPowerMode(
-      display, (Hwc2::IComposerClient::PowerMode)mode);
-}
-
 int32_t HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
                                               hwc2_config_t config,
                                               hwc2_attribute_t attribute,
@@ -552,31 +538,23 @@ void HardwareComposer::UpdateDisplayState() {
   const bool has_display_surfaces = display_surfaces_.size() > 0;
 
   if (has_display_surfaces) {
-    int32_t ret = SetPowerMode(HWC_DISPLAY_PRIMARY, HWC2_POWER_MODE_ON);
-
-    ALOGE_IF(ret, "HardwareComposer: Could not set power mode; ret=%d", ret);
-
     EnableVsync(true);
   }
+
   // TODO(skiazyk): We need to do something about accessing this directly,
   // supposedly there is a backlight service on the way.
   SetBacklightBrightness(255);
 
-  if (!display_on_ && has_display_surfaces) {
-    const int error = ReadVSyncTimestamp(&last_vsync_timestamp_);
-    ALOGE_IF(error < 0,
-             "HardwareComposer::SetDisplaySurfaces: Failed to read vsync "
-             "timestamp: %s",
-             strerror(-error));
-  }
-
   // Trigger target-specific performance mode change.
-  property_set(kDvrPerformanceProperty, display_on_ ? "performance" : "idle");
+  property_set(kDvrPerformanceProperty, has_display_surfaces ? "performance" : "idle");
 }
 
 int HardwareComposer::SetDisplaySurfaces(
     std::vector<std::shared_ptr<DisplaySurface>> surfaces) {
-  std::lock_guard<std::mutex> autolock(layer_mutex_);
+  // The double lock is necessary because we access both the display surfaces
+  // and post_thread_state_.
+  std::lock_guard<std::mutex> post_thread_state_lock(post_thread_state_mutex_);
+  std::lock_guard<std::mutex> layer_lock(layer_mutex_);
 
   ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
         surfaces.size());
@@ -622,7 +600,7 @@ int HardwareComposer::SetDisplaySurfaces(
 
   // TODO(skiazyk): fix this so that it is handled seamlessly with dormant/non-
   // dormant state.
-  if (!IsSuspended()) {
+  if (post_thread_state_ == PostThreadState::kRunning) {
     UpdateDisplayState();
   }
 
@@ -722,7 +700,8 @@ int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
 // Blocks until the next vsync event is signaled by the display driver.
 // TODO(eieio): This is pretty driver specific, this should be moved to a
 // separate class eventually.
-int HardwareComposer::BlockUntilVSync() {
+int HardwareComposer::BlockUntilVSync(/*out*/ bool* suspend_requested) {
+  *suspend_requested = false;
   const int event_fd = primary_display_vsync_event_fd_.Get();
   pollfd pfd[2] = {
       {
@@ -747,6 +726,8 @@ int HardwareComposer::BlockUntilVSync() {
              strerror(error), error);
   } while (ret < 0 && error == EINTR);
 
+  if (ret >= 0 && pfd[1].revents != 0)
+    *suspend_requested = true;
   return ret < 0 ? -error : 0;
 }
 
@@ -769,15 +750,11 @@ int HardwareComposer::WaitForVSync(int64_t* timestamp) {
 
     if (error == -EAGAIN) {
       // Vsync was turned off, wait for the next vsync event.
-      error = BlockUntilVSync();
-      if (error < 0)
+      bool suspend_requested = false;
+      error = BlockUntilVSync(&suspend_requested);
+      if (error < 0 || suspend_requested)
         return error;
 
-      // If a request to pause the post thread was given, exit immediately
-      if (IsSuspended()) {
-        return 0;
-      }
-
       // Try again to get the timestamp for this new vsync interval.
       continue;
     }
@@ -798,14 +775,10 @@ int HardwareComposer::WaitForVSync(int64_t* timestamp) {
 
     if (distance_to_vsync_est > threshold_ns) {
       // Wait for vsync event notification.
-      error = BlockUntilVSync();
-      if (error < 0)
+      bool suspend_requested = false;
+      error = BlockUntilVSync(&suspend_requested);
+      if (error < 0 || suspend_requested)
         return error;
-
-      // Again, exit immediately if the thread was requested to pause
-      if (IsSuspended()) {
-        return 0;
-      }
     } else {
       // Sleep for a short time before retrying.
       std::this_thread::sleep_for(std::chrono::milliseconds(1));
@@ -844,8 +817,6 @@ void HardwareComposer::PostThread() {
   // NOLINTNEXTLINE(runtime/int)
   prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("PostThread"), 0, 0, 0);
 
-  std::unique_lock<std::mutex> thread_lock(thread_pause_mutex_);
-
   // Set the scheduler to SCHED_FIFO with high priority.
   int error = dvrSetSchedulerClass(0, "graphics:high");
   LOG_ALWAYS_FATAL_IF(
@@ -899,12 +870,19 @@ void HardwareComposer::PostThread() {
   while (1) {
     ATRACE_NAME("HardwareComposer::PostThread");
 
-    while (IsSuspended()) {
-      ALOGI("HardwareComposer::PostThread: Post thread pause requested.");
-      thread_pause_semaphore_.wait(thread_lock);
-      // The layers will need to be updated since they were deleted previously
-      display_surfaces_updated_ = true;
-      hardware_layers_need_update_ = true;
+    {
+      std::unique_lock<std::mutex> post_thread_lock(post_thread_state_mutex_);
+      if (post_thread_state_ == PostThreadState::kPauseRequested) {
+        ALOGI("HardwareComposer::PostThread: Post thread pause requested.");
+        post_thread_state_ = PostThreadState::kPaused;
+        post_thread_state_cond_var_.notify_all();
+        post_thread_state_cond_var_.wait(
+            post_thread_lock,
+            [this] { return post_thread_state_ == PostThreadState::kRunning; });
+        // The layers will need to be updated since they were deleted previously
+        display_surfaces_updated_ = true;
+        hardware_layers_need_update_ = true;
+      }
     }
 
     int64_t vsync_timestamp = 0;
@@ -921,7 +899,8 @@ void HardwareComposer::PostThread() {
           strerror(-error));
 
       // Don't bother processing this frame if a pause was requested
-      if (IsSuspended()) {
+      std::lock_guard<std::mutex> post_thread_lock(post_thread_state_mutex_);
+      if (post_thread_state_ == PostThreadState::kPauseRequested) {
         continue;
       }
     }
@@ -1051,7 +1030,7 @@ void HardwareComposer::PostThread() {
 
 bool HardwareComposer::UpdateLayerConfig(
     std::vector<std::shared_ptr<DisplaySurface>>* compositor_surfaces) {
-  std::lock_guard<std::mutex> autolock(layer_mutex_);
+  std::lock_guard<std::mutex> layer_lock(layer_mutex_);
 
   if (!display_surfaces_updated_)
     return false;
@@ -1308,6 +1287,10 @@ void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
   // TODO(eieio): implement display hotplug callbacks.
 }
 
+void HardwareComposer::OnHardwareComposerRefresh() {
+  // TODO(steventhomas): Handle refresh.
+}
+
 void HardwareComposer::SetBacklightBrightness(int brightness) {
   if (backlight_brightness_fd_) {
     std::array<char, 32> text;
@@ -1522,7 +1505,8 @@ void Layer::Prepare() {
 
   if (composition_type_ == HWC2_COMPOSITION_DEVICE) {
     ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
-                                              hardware_composer_layer_, handle,
+                                              hardware_composer_layer_, 0,
+                                              handle,
                                               acquire_fence_fd_.Get());
 
     ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret);
index cfe8c84..b6aa807 100644 (file)
@@ -191,7 +191,6 @@ class HardwareComposer {
 
   bool Suspend();
   bool Resume();
-  bool IsSuspended() const { return pause_post_thread_; }
 
   // Get the HMD display metrics for the current display.
   DisplayMetrics GetHmdDisplayMetrics() const;
@@ -225,9 +224,10 @@ class HardwareComposer {
 
   Compositor* GetCompositor() { return &compositor_; }
 
+  void OnHardwareComposerRefresh();
+
  private:
   int32_t EnableVsync(bool enabled);
-  int32_t SetPowerMode(hwc2_display_t display, hwc2_power_mode_t mode);
 
   class ComposerCallback : public Hwc2::IComposerCallback {
    public:
@@ -263,7 +263,7 @@ class HardwareComposer {
   void PostThread();
 
   int ReadWaitPPState();
-  int BlockUntilVSync();
+  int BlockUntilVSync(/*out*/ bool* suspend_requested);
   int ReadVSyncTimestamp(int64_t* timestamp);
   int WaitForVSync(int64_t* timestamp);
   int SleepUntil(int64_t wakeup_timestamp);
@@ -303,8 +303,6 @@ class HardwareComposer {
 
   void HandlePendingScreenshots();
 
-  void PausePostThread();
-
   // Hardware composer HAL device.
   std::unique_ptr<Hwc2::Composer> hwc2_hidl_;
   sp<ComposerCallback> callbacks_;
@@ -329,9 +327,6 @@ class HardwareComposer {
   bool display_surfaces_updated_;
   bool hardware_layers_need_update_;
 
-  // Cache whether the display was turned on by us
-  bool display_on_; // TODO(hendrikw): The display is always on. Revisit.
-
   // Layer array for handling buffer flow into hardware composer layers.
   // Note that the first array is the actual storage for the layer objects,
   // and the latter is an array of pointers, which can be freely re-arranged
@@ -347,16 +342,35 @@ class HardwareComposer {
   // Handler to hook vsync events outside of this class.
   VSyncCallback vsync_callback_;
 
-  // Thread and condition for managing the layer posting thread. This thread
-  // wakes up a short time before vsync to hand buffers to post processing and
-  // the results to hardware composer.
+  // The layer posting thread. This thread wakes up a short time before vsync to
+  // hand buffers to post processing and the results to hardware composer.
   std::thread post_thread_;
 
+  enum class PostThreadState {
+    // post_thread_state_ starts off paused. When suspending, the control thread
+    // will block until post_thread_state_ == kPaused, indicating the post
+    // thread has completed the transition to paused (most importantly: no more
+    // hardware composer calls).
+    kPaused,
+    // post_thread_state_ is set to kRunning by the control thread (either
+    // surface flinger's main thread or the vr flinger dispatcher thread). The
+    // post thread blocks until post_thread_state_ == kRunning.
+    kRunning,
+    // Set by the control thread to indicate the post thread should pause. The
+    // post thread will change post_thread_state_ from kPauseRequested to
+    // kPaused when it stops.
+    kPauseRequested
+  };
   // Control variables to control the state of the post thread
+  PostThreadState post_thread_state_;
+  // Used to wake the post thread up while it's waiting for vsync, for faster
+  // transition to the paused state.
   pdx::LocalHandle terminate_post_thread_event_fd_;
-  bool pause_post_thread_;
-  std::mutex thread_pause_mutex_;
-  std::condition_variable thread_pause_semaphore_;
+  // post_thread_state_mutex_ should be held before checking or modifying
+  // post_thread_state_.
+  std::mutex post_thread_state_mutex_;
+  // Used to communicate between the control thread and the post thread.
+  std::condition_variable post_thread_state_cond_var_;
 
   // Backlight LED brightness sysfs node.
   pdx::LocalHandle backlight_brightness_fd_;
index 04c8363..17dce96 100644 (file)
@@ -21,6 +21,7 @@ class VrFlinger {
 
   void EnterVrMode();
   void ExitVrMode();
+  void OnHardwareComposerRefresh();
 
  private:
   std::thread displayd_thread_;
index e174943..fd1c582 100644 (file)
@@ -3,7 +3,9 @@
 #include <utils/Trace.h>
 
 #include <pdx/default_transport/service_endpoint.h>
+#include <private/android_filesystem_config.h>
 #include <private/dvr/display_types.h>
+#include <private/dvr/trusted_uids.h>
 
 using android::pdx::Message;
 using android::pdx::MessageInfo;
@@ -40,6 +42,12 @@ int ScreenshotService::OnGetFormat(pdx::Message&) {
 
 ScreenshotData ScreenshotService::OnTakeScreenshot(pdx::Message& message,
                                                    int layer_index) {
+  // Also allow AID_SHELL to support vrscreencap commands.
+  if (message.GetEffectiveUserId() != AID_SHELL &&
+      !IsTrustedUid(message.GetEffectiveUserId())) {
+    REPLY_ERROR_RETURN(message, EACCES, {});
+  }
+
   AddWaiter(std::move(message), layer_index);
   return {};
 }
index 07f36a4..9163e71 100644 (file)
@@ -32,6 +32,9 @@ namespace dvr {
 VrFlinger::VrFlinger() {}
 
 int VrFlinger::Run(Hwc2::Composer* hidl) {
+  if (!hidl)
+    return EINVAL;
+
   std::shared_ptr<android::pdx::Service> service;
 
   ALOGI("Starting up VrFlinger...");
@@ -103,5 +106,13 @@ void VrFlinger::ExitVrMode() {
   }
 }
 
+void VrFlinger::OnHardwareComposerRefresh() {
+  if (display_service_) {
+    display_service_->OnHardwareComposerRefresh();
+  } else {
+    ALOGE("OnHardwareComposerRefresh failed : Display service is not started.");
+  }
+}
+
 }  // namespace dvr
 }  // namespace android
index 60c4b36..865313c 100644 (file)
@@ -108,8 +108,6 @@ cc_library_shared {
     ],
     static_libs: ["libEGL_getProcAddress"],
     ldflags: ["-Wl,--exclude-libs=ALL"],
-
-    required: ["egl.cfg"],
 }
 
 cc_defaults {
index 21e76f5..2f42ab6 100644 (file)
@@ -1,12 +1 @@
 LOCAL_PATH:= $(call my-dir)
-
-# OpenGL drivers config file
-ifneq ($(BOARD_EGL_CFG),)
-include $(CLEAR_VARS)
-LOCAL_MODULE := egl.cfg
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl
-LOCAL_SRC_FILES := ../../../../$(BOARD_EGL_CFG)
-include $(BUILD_PREBUILT)
-endif
index 01d7bbb..b1ca13d 100644 (file)
@@ -31,6 +31,7 @@
 #include <cutils/properties.h>
 #include <log/log.h>
 #include <utils/Trace.h>
+#include <ui/GraphicsEnv.h>
 
 #include <EGL/egl.h>
 
@@ -147,26 +148,11 @@ status_t Loader::driver_t::set(void* hnd, int32_t api)
 // ----------------------------------------------------------------------------
 
 Loader::Loader()
-    : getProcAddress(NULL),
-      mLibGui(nullptr),
-      mGetDriverNamespace(nullptr)
+    : getProcAddress(NULL)
 {
-    // FIXME: See note in GraphicsEnv.h about android_getDriverNamespace().
-    // libgui should already be loaded in any process that uses libEGL, but
-    // if for some reason it isn't, then we're not going to get a driver
-    // namespace anyway, so don't force it to be loaded.
-    mLibGui = dlopen("libgui.so", RTLD_NOLOAD | RTLD_LOCAL | RTLD_LAZY);
-    if (!mLibGui) {
-        ALOGD("failed to load libgui: %s", dlerror());
-        return;
-    }
-    mGetDriverNamespace = reinterpret_cast<decltype(mGetDriverNamespace)>(
-            dlsym(mLibGui, "android_getDriverNamespace"));
 }
 
 Loader::~Loader() {
-    if (mLibGui)
-        dlclose(mLibGui);
 }
 
 static void* load_wrapper(const char* path) {
@@ -483,11 +469,9 @@ void *Loader::load_driver(const char* kind,
     ATRACE_CALL();
 
     void* dso = nullptr;
-    if (mGetDriverNamespace) {
-        android_namespace_t* ns = mGetDriverNamespace();
-        if (ns) {
-            dso = load_updated_driver(kind, ns);
-        }
+    android_namespace_t* ns = android_getDriverNamespace();
+    if (ns) {
+        dso = load_updated_driver(kind, ns);
     }
     if (!dso) {
         dso = load_system_driver(kind);
index d0435e7..b0743a5 100644 (file)
@@ -25,8 +25,6 @@
 #include <utils/Singleton.h>
 #include <utils/String8.h>
 
-#include <gui/GraphicsEnv.h>
-
 #include <EGL/egl.h>
 
 // ----------------------------------------------------------------------------
@@ -56,9 +54,6 @@ class Loader : public Singleton<Loader>
     
     getProcAddressType getProcAddress;
 
-    void* mLibGui;
-    decltype(android_getDriverNamespace)* mGetDriverNamespace;
-
 public:
     ~Loader();
     
index 42d01b2..ab3ac3a 100644 (file)
@@ -21,7 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <hardware/gralloc.h>
+#include <hardware/gralloc1.h>
 #include <system/window.h>
 
 #include <EGL/egl.h>
@@ -1839,7 +1839,8 @@ EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
 {
     clearError();
 
-    int usage = 0;
+    uint64_t producerUsage = 0;
+    uint64_t consumerUsage = 0;
     uint32_t width = 0;
     uint32_t height = 0;
     uint32_t format = 0;
@@ -1872,13 +1873,13 @@ EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
                 GET_NONNEGATIVE_VALUE(EGL_LAYER_COUNT_ANDROID, layer_count);
                 case EGL_NATIVE_BUFFER_USAGE_ANDROID:
                     if (value & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID) {
-                        usage |= GRALLOC_USAGE_PROTECTED;
+                        producerUsage |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
                     }
                     if (value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID) {
-                        usage |= GRALLOC_USAGE_HW_RENDER;
+                        producerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
                     }
                     if (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID) {
-                        usage |= GRALLOC_USAGE_HW_TEXTURE;
+                        consumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
                     }
                     break;
                 default:
@@ -1946,8 +1947,10 @@ EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
     CHECK_ERROR_CONDITION("Unable to write format");
     err = data.writeUint32(layer_count);
     CHECK_ERROR_CONDITION("Unable to write layer count");
-     err = data.writeUint32(usage);
-    CHECK_ERROR_CONDITION("Unable to write usage");
+    err = data.writeUint64(producerUsage);
+    CHECK_ERROR_CONDITION("Unable to write producer usage");
+    err = data.writeUint64(consumerUsage);
+    CHECK_ERROR_CONDITION("Unable to write consumer usage");
     err = data.writeUtf8AsUtf16(
             std::string("[eglCreateNativeClientBufferANDROID pid ") +
             std::to_string(getpid()) + ']');
@@ -1964,12 +1967,15 @@ EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
     err = gBuffer->initCheck();
     if (err != NO_ERROR) {
         ALOGE("Unable to create native buffer "
-                "{ w=%u, h=%u, f=%u, u=%#x, lc=%u}: %#x", width, height, format,
-                usage, layer_count, err);
+                "{ w=%u, h=%u, f=%u, pu=%" PRIx64 " cu=%" PRIx64 ", lc=%u} %#x",
+                width, height, format, producerUsage, consumerUsage,
+                layer_count, err);
         goto error_condition;
     }
-    ALOGV("Created new native buffer %p { w=%u, h=%u, f=%u, u=%#x, lc=%u}",
-            gBuffer, width, height, format, usage, layer_count);
+    ALOGV("Created new native buffer %p { w=%u, h=%u, f=%u, pu=%" PRIx64
+          " cu=%" PRIx64 ", lc=%u}",
+            gBuffer, width, height, format, producerUsage, consumerUsage,
+            layer_count);
     return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer());
 
 #undef CHECK_ERROR_CONDITION
index 2b9c38e..1cd40b3 100644 (file)
 
 #include <EGL/egl.h>
 #include <gui/Surface.h>
-
+#include <gui/IConsumerListener.h>
+#include <gui/IProducerListener.h>
+#include <gui/IGraphicBufferConsumer.h>
+#include <gui/BufferQueue.h>
 
 namespace android {
 
index 3b0b4e9..47edc4b 100644 (file)
@@ -33,6 +33,8 @@ enum {
     PAUSE      = IBinder::FIRST_CALL_TRANSACTION + 1,
     STOP       = IBinder::FIRST_CALL_TRANSACTION + 2,
     SET_VOLUME = IBinder::FIRST_CALL_TRANSACTION + 3,
+    SET_PAN    = IBinder::FIRST_CALL_TRANSACTION + 4,
+    SET_START_DELAY_MS = IBinder::FIRST_CALL_TRANSACTION + 5,
 };
 
 class BpPlayer : public BpInterface<IPlayer>
@@ -71,6 +73,21 @@ public:
         data.writeFloat(vol);
         remote()->transact(SET_VOLUME, data, &reply);
     }
+
+    virtual void setPan(float pan)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IPlayer::getInterfaceDescriptor());
+        data.writeFloat(pan);
+        remote()->transact(SET_PAN, data, &reply);
+    }
+
+    virtual void setStartDelayMs(int32_t delayMs) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IPlayer::getInterfaceDescriptor());
+        data.writeInt32(delayMs);
+        remote()->transact(SET_START_DELAY_MS, data, &reply);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(Player, "android.media.IPlayer");
@@ -100,7 +117,17 @@ status_t BnPlayer::onTransact(
             CHECK_INTERFACE(IPlayer, data, reply);
             setVolume(data.readFloat());
             return NO_ERROR;
-        }
+        } break;
+        case SET_PAN: {
+            CHECK_INTERFACE(IPlayer, data, reply);
+            setPan(data.readFloat());
+            return NO_ERROR;
+        } break;
+        case SET_START_DELAY_MS: {
+            CHECK_INTERFACE(IPlayer, data, reply);
+            setStartDelayMs(data.readInt32());
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
index c41630a..d61f26f 100644 (file)
@@ -10,6 +10,7 @@ LOCAL_SRC_FILES:= \
     OrientationSensor.cpp \
     RecentEventLogger.cpp \
     RotationVectorSensor.cpp \
+    SensorDevice.cpp \
     SensorDirectConnection.cpp \
     SensorEventConnection.cpp \
     SensorFusion.cpp \
@@ -25,13 +26,6 @@ LOCAL_CFLAGS += -Wall -Werror -Wextra
 
 LOCAL_CFLAGS += -fvisibility=hidden
 
-ifeq ($(ENABLE_TREBLE), true)
-LOCAL_SRC_FILES += SensorDeviceTreble.cpp
-LOCAL_CFLAGS += -DENABLE_TREBLE=1
-else
-LOCAL_SRC_FILES += SensorDevice.cpp
-endif
-
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     libhardware \
@@ -42,10 +36,6 @@ LOCAL_SHARED_LIBRARIES := \
     libui \
     libgui \
     libcrypto \
-
-ifeq ($(ENABLE_TREBLE), true)
-
-LOCAL_SHARED_LIBRARIES += \
     libbase \
     libhidlbase \
     libhidltransport \
@@ -55,8 +45,6 @@ LOCAL_SHARED_LIBRARIES += \
 LOCAL_STATIC_LIBRARIES := \
     android.hardware.sensors@1.0-convert
 
-endif  # ENABLE_TREBLE
-
 LOCAL_MODULE:= libsensorservice
 
 include $(BUILD_SHARED_LIBRARY)
index de0321d..3edd50b 100644 (file)
  * limitations under the License.
  */
 
+#include <inttypes.h>
+#include <math.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <android-base/logging.h>
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/Singleton.h>
 
 #include "SensorDevice.h"
 #include "SensorService.h"
 
+#include <sensors/convert.h>
 
-#include <binder/BinderService.h>
-#include <binder/Parcel.h>
-#include <binder/IServiceManager.h>
-#include <cutils/ashmem.h>
-#include <hardware/sensors.h>
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/Singleton.h>
+using android::hardware::hidl_vec;
 
-#include <inttypes.h>
-#include <math.h>
-#include <sys/mman.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <sstream>
-#include <unistd.h>
+using namespace android::hardware::sensors::V1_0;
+using namespace android::hardware::sensors::V1_0::implementation;
 
 namespace android {
 // ---------------------------------------------------------------------------
 
 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
 
-SensorDevice::SensorDevice()
-    :  mSensorDevice(0),
-       mSensorModule(0) {
-    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
-            (hw_module_t const**)&mSensorModule);
+static status_t StatusFromResult(Result result) {
+    switch (result) {
+        case Result::OK:
+            return OK;
+        case Result::BAD_VALUE:
+            return BAD_VALUE;
+        case Result::PERMISSION_DENIED:
+            return PERMISSION_DENIED;
+        case Result::INVALID_OPERATION:
+            return INVALID_OPERATION;
+        case Result::NO_MEMORY:
+            return NO_MEMORY;
+    }
+}
 
-    ALOGE_IF(err, "couldn't load %s module (%s)",
-            SENSORS_HARDWARE_MODULE_ID, strerror(-err));
+SensorDevice::SensorDevice() {
+    mSensors = ISensors::getService();
 
-    if (mSensorModule) {
-        err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
+    if (mSensors == NULL) {
+        return;
+    }
 
-        ALOGE_IF(err, "couldn't open device for module %s (%s)",
-                SENSORS_HARDWARE_MODULE_ID, strerror(-err));
+    mSensors->getSensorsList(
+            [&](const auto &list) {
+                const size_t count = list.size();
 
-        if (mSensorDevice) {
+                mActivationCount.setCapacity(count);
+                Info model;
+                for (size_t i=0 ; i < count; i++) {
+                    sensor_t sensor;
+                    convertToSensor(list[i], &sensor);
+                    mSensorList.push_back(sensor);
 
-            sensor_t const* list;
-            ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
+                    mActivationCount.add(list[i].sensorHandle, model);
 
-            if (mSensorDevice->common.version < SENSORS_DEVICE_API_VERSION_1_3) {
-                ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3, ignoring sensors reported by this device");
-                count = 0;
-            }
+                    mSensors->activate(list[i].sensorHandle, 0 /* enabled */);
+                }
+            });
 
-            mActivationCount.setCapacity(count);
-            Info model;
-            for (size_t i=0 ; i<size_t(count) ; i++) {
-                mActivationCount.add(list[i].handle, model);
-                mSensorDevice->activate(
-                        reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
-                        list[i].handle, 0);
-            }
-        }
-    }
+    mIsDirectReportSupported =
+           (mSensors->unregisterDirectChannel(-1) != Result::INVALID_OPERATION);
 }
 
 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
     if (connected) {
         Info model;
         mActivationCount.add(handle, model);
-        mSensorDevice->activate(
-                reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, 0);
+        mSensors->activate(handle, 0 /* enabled */);
     } else {
         mActivationCount.removeItem(handle);
     }
 }
 
 std::string SensorDevice::dump() const {
-    if (!mSensorModule) return "HAL not initialized\n";
+    if (mSensors == NULL) return "HAL not initialized\n";
 
     String8 result;
-    sensor_t const* list;
-    int count = mSensorModule->get_sensors_list(mSensorModule, &list);
-
-    result.appendFormat("HAL: %s (%s), version %#010x\n",
-                        mSensorModule->common.name,
-                        mSensorModule->common.author,
-                        getHalDeviceVersion());
-    result.appendFormat("Total %d h/w sensors, %zu running:\n", count, mActivationCount.size());
+    mSensors->getSensorsList([&](const auto &list) {
+            const size_t count = list.size();
+
+            result.appendFormat(
+                "Total %zu h/w sensors, %zu running:\n",
+                count,
+                mActivationCount.size());
+
+            Mutex::Autolock _l(mLock);
+            for (size_t i = 0 ; i < count ; i++) {
+                const Info& info = mActivationCount.valueFor(
+                    list[i].sensorHandle);
+
+                if (info.batchParams.isEmpty()) continue;
+                result.appendFormat(
+                    "0x%08x) active-count = %zu; ",
+                    list[i].sensorHandle,
+                    info.batchParams.size());
+
+                result.append("sampling_period(ms) = {");
+                for (size_t j = 0; j < info.batchParams.size(); j++) {
+                    const BatchParams& params = info.batchParams.valueAt(j);
+                    result.appendFormat(
+                        "%.1f%s",
+                        params.batchDelay / 1e6f,
+                        j < info.batchParams.size() - 1 ? ", " : "");
+                }
+                result.appendFormat(
+                        "}, selected = %.1f ms; ",
+                        info.bestBatchParams.batchDelay / 1e6f);
+
+                result.append("batching_period(ms) = {");
+                for (size_t j = 0; j < info.batchParams.size(); j++) {
+                    BatchParams params = info.batchParams.valueAt(j);
+
+                    result.appendFormat(
+                            "%.1f%s",
+                            params.batchTimeout / 1e6f,
+                            j < info.batchParams.size() - 1 ? ", " : "");
+                }
 
-    Mutex::Autolock _l(mLock);
-    for (int i = 0 ; i < count ; i++) {
-        const Info& info = mActivationCount.valueFor(list[i].handle);
-        if (info.batchParams.isEmpty()) continue;
-        result.appendFormat("0x%08x) active-count = %zu; ", list[i].handle,
-                            info.batchParams.size());
-
-        result.append("sampling_period(ms) = {");
-        for (size_t j = 0; j < info.batchParams.size(); j++) {
-            const BatchParams& params = info.batchParams.valueAt(j);
-            result.appendFormat("%.1f%s", params.batchDelay / 1e6f,
-                                j < info.batchParams.size() - 1 ? ", " : "");
-        }
-        result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f);
+                result.appendFormat(
+                        "}, selected = %.1f ms\n",
+                        info.bestBatchParams.batchTimeout / 1e6f);
+            }
+        });
 
-        result.append("batching_period(ms) = {");
-        for (size_t j = 0; j < info.batchParams.size(); j++) {
-            BatchParams params = info.batchParams.valueAt(j);
-            result.appendFormat("%.1f%s", params.batchTimeout / 1e6f,
-                                j < info.batchParams.size() - 1 ? ", " : "");
-        }
-        result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
-    }
     return result.string();
 }
 
 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
-    if (!mSensorModule) return NO_INIT;
-    ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
-    return count;
+    *list = &mSensorList[0];
+
+    return mSensorList.size();
 }
 
 status_t SensorDevice::initCheck() const {
-    return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
+    return mSensors != NULL ? NO_ERROR : NO_INIT;
 }
 
 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
-    if (!mSensorDevice) return NO_INIT;
-    ssize_t c;
-    do {
-        c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
-                                buffer, count);
-    } while (c == -EINTR);
-    return c;
+    if (mSensors == NULL) return NO_INIT;
+
+    ssize_t err;
+
+    mSensors->poll(
+            count,
+            [&](auto result,
+                const auto &events,
+                const auto &dynamicSensorsAdded) {
+                if (result == Result::OK) {
+                    convertToSensorEvents(events, dynamicSensorsAdded, buffer);
+                    err = (ssize_t)events.size();
+                } else {
+                    err = StatusFromResult(result);
+                }
+            });
+
+    return err;
 }
 
 void SensorDevice::autoDisable(void *ident, int handle) {
@@ -155,7 +184,8 @@ void SensorDevice::autoDisable(void *ident, int handle) {
 }
 
 status_t SensorDevice::activate(void* ident, int handle, int enabled) {
-    if (!mSensorDevice) return NO_INIT;
+    if (mSensors == NULL) return NO_INIT;
+
     status_t err(NO_ERROR);
     bool actuateHardware = false;
 
@@ -187,24 +217,30 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) {
     } else {
         ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
 
+        // If a connected dynamic sensor is deactivated, remove it from the
+        // dictionary.
+        auto it = mConnectedDynamicSensors.find(handle);
+        if (it != mConnectedDynamicSensors.end()) {
+            delete it->second;
+            mConnectedDynamicSensors.erase(it);
+        }
+
         if (info.removeBatchParamsForIdent(ident) >= 0) {
             if (info.numActiveClients() == 0) {
                 // This is the last connection, we need to de-activate the underlying h/w sensor.
                 actuateHardware = true;
             } else {
-                const int halVersion = getHalDeviceVersion();
-                if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
-                    // Call batch for this sensor with the previously calculated best effort
-                    // batch_rate and timeout. One of the apps has unregistered for sensor
-                    // events, and the best effort batch parameters might have changed.
-                    ALOGD_IF(DEBUG_CONNECTIONS,
-                             "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
-                             info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
-                             info.bestBatchParams.batchTimeout);
-                    mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
-                                         info.bestBatchParams.batchDelay,
-                                         info.bestBatchParams.batchTimeout);
-                }
+                // Call batch for this sensor with the previously calculated best effort
+                // batch_rate and timeout. One of the apps has unregistered for sensor
+                // events, and the best effort batch parameters might have changed.
+                ALOGD_IF(DEBUG_CONNECTIONS,
+                         "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
+                         info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
+                         info.bestBatchParams.batchTimeout);
+                mSensors->batch(
+                        handle,
+                        info.bestBatchParams.batchDelay,
+                        info.bestBatchParams.batchTimeout);
             }
         } else {
             // sensor wasn't enabled for this ident
@@ -218,8 +254,7 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) {
     if (actuateHardware) {
         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
                  enabled);
-        err = mSensorDevice->activate(
-                reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
+        err = StatusFromResult(mSensors->activate(handle, enabled));
         ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
                  strerror(-err));
 
@@ -229,31 +264,21 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) {
         }
     }
 
-    // On older devices which do not support batch, call setDelay().
-    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.numActiveClients() > 0) {
-        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
-                 info.bestBatchParams.batchDelay);
-        mSensorDevice->setDelay(
-                reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
-                handle, info.bestBatchParams.batchDelay);
-    }
     return err;
 }
 
-status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
-                             int64_t maxBatchReportLatencyNs) {
-    if (!mSensorDevice) return NO_INIT;
+status_t SensorDevice::batch(
+        void* ident,
+        int handle,
+        int flags,
+        int64_t samplingPeriodNs,
+        int64_t maxBatchReportLatencyNs) {
+    if (mSensors == NULL) return NO_INIT;
 
     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
     }
 
-    const int halVersion = getHalDeviceVersion();
-    if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 && maxBatchReportLatencyNs != 0) {
-        // Batch is not supported on older devices return invalid operation.
-        return INVALID_OPERATION;
-    }
-
     ALOGD_IF(DEBUG_CONNECTIONS,
              "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
              ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
@@ -282,21 +307,17 @@ status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplin
     status_t err(NO_ERROR);
     // If the min period or min timeout has changed since the last batch call, call batch.
     if (prevBestBatchParams != info.bestBatchParams) {
-        if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
-            ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
-                     info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
-                     info.bestBatchParams.batchTimeout);
-            err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
-                                       info.bestBatchParams.batchDelay,
-                                       info.bestBatchParams.batchTimeout);
-        } else {
-            // For older devices which do not support batch, call setDelay() after activate() is
-            // called. Some older devices may not support calling setDelay before activate(), so
-            // call setDelay in SensorDevice::activate() method.
-        }
+        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
+                 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
+                 info.bestBatchParams.batchTimeout);
+        err = StatusFromResult(
+                mSensors->batch(
+                    handle,
+                    info.bestBatchParams.batchDelay,
+                    info.bestBatchParams.batchTimeout));
         if (err != NO_ERROR) {
             ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
-                  mSensorDevice, handle,
+                  mSensors.get(), handle,
                   info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
                   info.bestBatchParams.batchTimeout, strerror(-err));
             info.removeBatchParamsForIdent(ident);
@@ -306,7 +327,7 @@ status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplin
 }
 
 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
-    if (!mSensorDevice) return NO_INIT;
+    if (mSensors == NULL) return NO_INIT;
     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
     }
@@ -325,22 +346,20 @@ status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodN
     BatchParams& params = info.batchParams.editValueAt(index);
     params.batchDelay = samplingPeriodNs;
     info.selectBatchParams();
-    return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
-                                   handle, info.bestBatchParams.batchDelay);
+
+    return StatusFromResult(
+            mSensors->batch(handle, info.bestBatchParams.batchDelay, 0));
 }
 
 int SensorDevice::getHalDeviceVersion() const {
-    if (!mSensorDevice) return -1;
-    return mSensorDevice->common.version;
+    if (mSensors == NULL) return -1;
+    return SENSORS_DEVICE_API_VERSION_1_4;
 }
 
 status_t SensorDevice::flush(void* ident, int handle) {
-    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
-        return INVALID_OPERATION;
-    }
     if (isClientDisabled(ident)) return INVALID_OPERATION;
     ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
-    return mSensorDevice->flush(mSensorDevice, handle);
+    return StatusFromResult(mSensors->flush(handle));
 }
 
 bool SensorDevice::isClientDisabled(void* ident) {
@@ -356,7 +375,6 @@ void SensorDevice::enableAllSensors() {
     Mutex::Autolock _l(mLock);
     mDisabledClients.clear();
     ALOGI("cleared mDisabledClients");
-    const int halVersion = getHalDeviceVersion();
     for (size_t i = 0; i< mActivationCount.size(); ++i) {
         Info& info = mActivationCount.editValueAt(i);
         if (info.batchParams.isEmpty()) continue;
@@ -364,42 +382,32 @@ void SensorDevice::enableAllSensors() {
         const int sensor_handle = mActivationCount.keyAt(i);
         ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
                    sensor_handle);
-        status_t err(NO_ERROR);
-        if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) {
-            err = mSensorDevice->batch(mSensorDevice, sensor_handle,
-                 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
-                 info.bestBatchParams.batchTimeout);
-            ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
-        }
+        status_t err = StatusFromResult(
+                mSensors->batch(
+                    sensor_handle,
+                    info.bestBatchParams.batchDelay,
+                    info.bestBatchParams.batchTimeout));
+        ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
 
         if (err == NO_ERROR) {
-            err = mSensorDevice->activate(
-                    reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
-                    sensor_handle, 1);
+            err = StatusFromResult(
+                    mSensors->activate(sensor_handle, 1 /* enabled */));
             ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
         }
-
-        if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0) {
-             err = mSensorDevice->setDelay(
-                    reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
-                    sensor_handle, info.bestBatchParams.batchDelay);
-             ALOGE_IF(err, "Error calling setDelay sensor %d (%s)", sensor_handle, strerror(-err));
-        }
     }
 }
 
 void SensorDevice::disableAllSensors() {
     Mutex::Autolock _l(mLock);
-    for (size_t i = 0; i< mActivationCount.size(); ++i) {
+   for (size_t i = 0; i< mActivationCount.size(); ++i) {
         const Info& info = mActivationCount.valueAt(i);
         // Check if this sensor has been activated previously and disable it.
         if (info.batchParams.size() > 0) {
            const int sensor_handle = mActivationCount.keyAt(i);
            ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
                    sensor_handle);
-           mSensorDevice->activate(
-                   reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
-                   sensor_handle, 0);
+           mSensors->activate(sensor_handle, 0 /* enabled */);
+
            // Add all the connections that were registered for this sensor to the disabled
            // clients list.
            for (size_t j = 0; j < info.batchParams.size(); ++j) {
@@ -410,25 +418,27 @@ void SensorDevice::disableAllSensors() {
     }
 }
 
-status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) {
-      ALOGD_IF(DEBUG_CONNECTIONS,
-              "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
-               injected_sensor_event->sensor,
-               injected_sensor_event->timestamp, injected_sensor_event->data[0],
-               injected_sensor_event->data[1], injected_sensor_event->data[2],
-               injected_sensor_event->data[3], injected_sensor_event->data[4],
-               injected_sensor_event->data[5]);
-      if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
-          return INVALID_OPERATION;
-      }
-      return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event);
+status_t SensorDevice::injectSensorData(
+        const sensors_event_t *injected_sensor_event) {
+    ALOGD_IF(DEBUG_CONNECTIONS,
+            "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
+            injected_sensor_event->sensor,
+            injected_sensor_event->timestamp, injected_sensor_event->data[0],
+            injected_sensor_event->data[1], injected_sensor_event->data[2],
+            injected_sensor_event->data[3], injected_sensor_event->data[4],
+            injected_sensor_event->data[5]);
+
+    Event ev;
+    convertFromSensorEvent(*injected_sensor_event, &ev);
+
+    return StatusFromResult(mSensors->injectSensorData(ev));
 }
 
 status_t SensorDevice::setMode(uint32_t mode) {
-     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
-          return INVALID_OPERATION;
-     }
-     return mSensorModule->set_operation_mode(mode);
+
+     return StatusFromResult(
+             mSensors->setOperationMode(
+                 static_cast<hardware::sensors::V1_0::OperationMode>(mode)));
 }
 
 // ---------------------------------------------------------------------------
@@ -491,44 +501,139 @@ void SensorDevice::notifyConnectionDestroyed(void* ident) {
 }
 
 int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
+    Mutex::Autolock _l(mLock);
 
-    if (!isDirectReportSupported()) {
-        return INVALID_OPERATION;
+    SharedMemType type;
+    switch (memory->type) {
+        case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
+            type = SharedMemType::ASHMEM;
+            break;
+        case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
+            type = SharedMemType::GRALLOC;
+            break;
+        default:
+            return BAD_VALUE;
     }
 
-    Mutex::Autolock _l(mLock);
-
-    int32_t channelHandle = mSensorDevice->register_direct_channel(
-            mSensorDevice, memory, -1 /*channel_handle*/);
-    return channelHandle;
+    SharedMemFormat format;
+    if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
+        return BAD_VALUE;
+    }
+    format = SharedMemFormat::SENSORS_EVENT;
+
+    SharedMemInfo mem = {
+        .type = type,
+        .format = format,
+        .size = static_cast<uint32_t>(memory->size),
+        .memoryHandle = memory->handle,
+    };
+
+    int32_t ret;
+    mSensors->registerDirectChannel(mem,
+            [&ret](auto result, auto channelHandle) {
+                if (result == Result::OK) {
+                    ret = channelHandle;
+                } else {
+                    ret = StatusFromResult(result);
+                }
+            });
+    return ret;
 }
 
 void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
     Mutex::Autolock _l(mLock);
-
-    mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle);
+    mSensors->unregisterDirectChannel(channelHandle);
 }
 
-int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, int32_t channelHandle,
-        const struct sensors_direct_cfg_t *config) {
+int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
+        int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
+    Mutex::Autolock _l(mLock);
 
-    if (!isDirectReportSupported()) {
-        return INVALID_OPERATION;
+    RateLevel rate;
+    switch(config->rate_level) {
+        case SENSOR_DIRECT_RATE_STOP:
+            rate = RateLevel::STOP;
+            break;
+        case SENSOR_DIRECT_RATE_NORMAL:
+            rate = RateLevel::NORMAL;
+            break;
+        case SENSOR_DIRECT_RATE_FAST:
+            rate = RateLevel::FAST;
+            break;
+        case SENSOR_DIRECT_RATE_VERY_FAST:
+            rate = RateLevel::VERY_FAST;
+            break;
+        default:
+            return BAD_VALUE;
     }
 
-    Mutex::Autolock _l(mLock);
+    int32_t ret;
+    mSensors->configDirectReport(sensorHandle, channelHandle, rate,
+            [&ret, rate] (auto result, auto token) {
+                if (rate == RateLevel::STOP) {
+                    ret = StatusFromResult(result);
+                } else {
+                    if (result == Result::OK) {
+                        ret = token;
+                    } else {
+                        ret = StatusFromResult(result);
+                    }
+                }
+            });
 
-    int32_t ret = mSensorDevice->config_direct_report(
-            mSensorDevice, sensorHandle, channelHandle, config);
-    ALOGE_IF(ret < 0, "SensorDevice::configureDirectChannel ret %d", ret);
     return ret;
 }
 
 bool SensorDevice::isDirectReportSupported() const {
-    bool ret = mSensorDevice->register_direct_channel != nullptr
-            && mSensorDevice->config_direct_report != nullptr;
-    return ret;
+    return mIsDirectReportSupported;
+}
+
+void SensorDevice::convertToSensorEvent(
+        const Event &src, sensors_event_t *dst) {
+    ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
+            src, dst);
+
+    if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
+        const DynamicSensorInfo &dyn = src.u.dynamic;
+
+        dst->dynamic_sensor_meta.connected = dyn.connected;
+        dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
+        if (dyn.connected) {
+            auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
+            CHECK(it != mConnectedDynamicSensors.end());
+
+            dst->dynamic_sensor_meta.sensor = it->second;
+
+            memcpy(dst->dynamic_sensor_meta.uuid,
+                   dyn.uuid.data(),
+                   sizeof(dst->dynamic_sensor_meta.uuid));
+        }
+    }
 }
+
+void SensorDevice::convertToSensorEvents(
+        const hidl_vec<Event> &src,
+        const hidl_vec<SensorInfo> &dynamicSensorsAdded,
+        sensors_event_t *dst) {
+    // Allocate a sensor_t structure for each dynamic sensor added and insert
+    // it into the dictionary of connected dynamic sensors keyed by handle.
+    for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
+        const SensorInfo &info = dynamicSensorsAdded[i];
+
+        auto it = mConnectedDynamicSensors.find(info.sensorHandle);
+        CHECK(it == mConnectedDynamicSensors.end());
+
+        sensor_t *sensor = new sensor_t;
+        convertToSensor(info, sensor);
+
+        mConnectedDynamicSensors.insert(
+                std::make_pair(sensor->handle, sensor));
+    }
+
+    for (size_t i = 0; i < src.size(); ++i) {
+        convertToSensorEvent(src[i], &dst[i]);
+    }
+}
+
 // ---------------------------------------------------------------------------
 }; // namespace android
-
index 7dd256a..7f95429 100644 (file)
 #include "SensorServiceUtils.h"
 
 #include <gui/Sensor.h>
+#include <stdint.h>
+#include <sys/types.h>
 #include <utils/KeyedVector.h>
 #include <utils/Singleton.h>
 #include <utils/String8.h>
 
-#include <stdint.h>
-#include <sys/types.h>
 #include <string>
-
-#ifdef ENABLE_TREBLE
 #include <map>
 
 #include "android/hardware/sensors/1.0/ISensors.h"
-#endif
 
 // ---------------------------------------------------------------------------
 
@@ -76,14 +73,10 @@ public:
     virtual std::string dump() const;
 private:
     friend class Singleton<SensorDevice>;
-#ifdef ENABLE_TREBLE
+
     sp<android::hardware::sensors::V1_0::ISensors> mSensors;
     Vector<sensor_t> mSensorList;
     std::map<int32_t, sensor_t*> mConnectedDynamicSensors;
-#else
-    sensors_poll_device_1_t* mSensorDevice;
-    struct sensors_module_t* mSensorModule;
-#endif
 
     static const nsecs_t MINIMUM_EVENTS_PERIOD =   1000000; // 1000 Hz
     mutable Mutex mLock; // protect mActivationCount[].batchParams
@@ -138,7 +131,6 @@ private:
     bool isClientDisabled(void* ident);
     bool isClientDisabledLocked(void* ident);
 
-#ifdef ENABLE_TREBLE
     using Event = hardware::sensors::V1_0::Event;
     using SensorInfo = hardware::sensors::V1_0::SensorInfo;
 
@@ -150,7 +142,6 @@ private:
             sensors_event_t *dst);
 
     bool mIsDirectReportSupported;
-#endif  // ENABLE_TREBLE
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorDeviceTreble.cpp b/services/sensorservice/SensorDeviceTreble.cpp
deleted file mode 100644 (file)
index 3edd50b..0000000
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- * 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.
- */
-
-#include <inttypes.h>
-#include <math.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <android-base/logging.h>
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/Singleton.h>
-
-#include "SensorDevice.h"
-#include "SensorService.h"
-
-#include <sensors/convert.h>
-
-using android::hardware::hidl_vec;
-
-using namespace android::hardware::sensors::V1_0;
-using namespace android::hardware::sensors::V1_0::implementation;
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
-
-static status_t StatusFromResult(Result result) {
-    switch (result) {
-        case Result::OK:
-            return OK;
-        case Result::BAD_VALUE:
-            return BAD_VALUE;
-        case Result::PERMISSION_DENIED:
-            return PERMISSION_DENIED;
-        case Result::INVALID_OPERATION:
-            return INVALID_OPERATION;
-        case Result::NO_MEMORY:
-            return NO_MEMORY;
-    }
-}
-
-SensorDevice::SensorDevice() {
-    mSensors = ISensors::getService();
-
-    if (mSensors == NULL) {
-        return;
-    }
-
-    mSensors->getSensorsList(
-            [&](const auto &list) {
-                const size_t count = list.size();
-
-                mActivationCount.setCapacity(count);
-                Info model;
-                for (size_t i=0 ; i < count; i++) {
-                    sensor_t sensor;
-                    convertToSensor(list[i], &sensor);
-                    mSensorList.push_back(sensor);
-
-                    mActivationCount.add(list[i].sensorHandle, model);
-
-                    mSensors->activate(list[i].sensorHandle, 0 /* enabled */);
-                }
-            });
-
-    mIsDirectReportSupported =
-           (mSensors->unregisterDirectChannel(-1) != Result::INVALID_OPERATION);
-}
-
-void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
-    if (connected) {
-        Info model;
-        mActivationCount.add(handle, model);
-        mSensors->activate(handle, 0 /* enabled */);
-    } else {
-        mActivationCount.removeItem(handle);
-    }
-}
-
-std::string SensorDevice::dump() const {
-    if (mSensors == NULL) return "HAL not initialized\n";
-
-    String8 result;
-    mSensors->getSensorsList([&](const auto &list) {
-            const size_t count = list.size();
-
-            result.appendFormat(
-                "Total %zu h/w sensors, %zu running:\n",
-                count,
-                mActivationCount.size());
-
-            Mutex::Autolock _l(mLock);
-            for (size_t i = 0 ; i < count ; i++) {
-                const Info& info = mActivationCount.valueFor(
-                    list[i].sensorHandle);
-
-                if (info.batchParams.isEmpty()) continue;
-                result.appendFormat(
-                    "0x%08x) active-count = %zu; ",
-                    list[i].sensorHandle,
-                    info.batchParams.size());
-
-                result.append("sampling_period(ms) = {");
-                for (size_t j = 0; j < info.batchParams.size(); j++) {
-                    const BatchParams& params = info.batchParams.valueAt(j);
-                    result.appendFormat(
-                        "%.1f%s",
-                        params.batchDelay / 1e6f,
-                        j < info.batchParams.size() - 1 ? ", " : "");
-                }
-                result.appendFormat(
-                        "}, selected = %.1f ms; ",
-                        info.bestBatchParams.batchDelay / 1e6f);
-
-                result.append("batching_period(ms) = {");
-                for (size_t j = 0; j < info.batchParams.size(); j++) {
-                    BatchParams params = info.batchParams.valueAt(j);
-
-                    result.appendFormat(
-                            "%.1f%s",
-                            params.batchTimeout / 1e6f,
-                            j < info.batchParams.size() - 1 ? ", " : "");
-                }
-
-                result.appendFormat(
-                        "}, selected = %.1f ms\n",
-                        info.bestBatchParams.batchTimeout / 1e6f);
-            }
-        });
-
-    return result.string();
-}
-
-ssize_t SensorDevice::getSensorList(sensor_t const** list) {
-    *list = &mSensorList[0];
-
-    return mSensorList.size();
-}
-
-status_t SensorDevice::initCheck() const {
-    return mSensors != NULL ? NO_ERROR : NO_INIT;
-}
-
-ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
-    if (mSensors == NULL) return NO_INIT;
-
-    ssize_t err;
-
-    mSensors->poll(
-            count,
-            [&](auto result,
-                const auto &events,
-                const auto &dynamicSensorsAdded) {
-                if (result == Result::OK) {
-                    convertToSensorEvents(events, dynamicSensorsAdded, buffer);
-                    err = (ssize_t)events.size();
-                } else {
-                    err = StatusFromResult(result);
-                }
-            });
-
-    return err;
-}
-
-void SensorDevice::autoDisable(void *ident, int handle) {
-    Info& info( mActivationCount.editValueFor(handle) );
-    Mutex::Autolock _l(mLock);
-    info.removeBatchParamsForIdent(ident);
-}
-
-status_t SensorDevice::activate(void* ident, int handle, int enabled) {
-    if (mSensors == NULL) return NO_INIT;
-
-    status_t err(NO_ERROR);
-    bool actuateHardware = false;
-
-    Mutex::Autolock _l(mLock);
-    Info& info( mActivationCount.editValueFor(handle) );
-
-    ALOGD_IF(DEBUG_CONNECTIONS,
-             "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
-             ident, handle, enabled, info.batchParams.size());
-
-    if (enabled) {
-        ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
-
-        if (isClientDisabledLocked(ident)) {
-            ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
-                    ident, handle);
-            return INVALID_OPERATION;
-        }
-
-        if (info.batchParams.indexOfKey(ident) >= 0) {
-          if (info.numActiveClients() == 1) {
-              // This is the first connection, we need to activate the underlying h/w sensor.
-              actuateHardware = true;
-          }
-        } else {
-            // Log error. Every activate call should be preceded by a batch() call.
-            ALOGE("\t >>>ERROR: activate called without batch");
-        }
-    } else {
-        ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
-
-        // If a connected dynamic sensor is deactivated, remove it from the
-        // dictionary.
-        auto it = mConnectedDynamicSensors.find(handle);
-        if (it != mConnectedDynamicSensors.end()) {
-            delete it->second;
-            mConnectedDynamicSensors.erase(it);
-        }
-
-        if (info.removeBatchParamsForIdent(ident) >= 0) {
-            if (info.numActiveClients() == 0) {
-                // This is the last connection, we need to de-activate the underlying h/w sensor.
-                actuateHardware = true;
-            } else {
-                // Call batch for this sensor with the previously calculated best effort
-                // batch_rate and timeout. One of the apps has unregistered for sensor
-                // events, and the best effort batch parameters might have changed.
-                ALOGD_IF(DEBUG_CONNECTIONS,
-                         "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
-                         info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
-                         info.bestBatchParams.batchTimeout);
-                mSensors->batch(
-                        handle,
-                        info.bestBatchParams.batchDelay,
-                        info.bestBatchParams.batchTimeout);
-            }
-        } else {
-            // sensor wasn't enabled for this ident
-        }
-
-        if (isClientDisabledLocked(ident)) {
-            return NO_ERROR;
-        }
-    }
-
-    if (actuateHardware) {
-        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
-                 enabled);
-        err = StatusFromResult(mSensors->activate(handle, enabled));
-        ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
-                 strerror(-err));
-
-        if (err != NO_ERROR && enabled) {
-            // Failure when enabling the sensor. Clean up on failure.
-            info.removeBatchParamsForIdent(ident);
-        }
-    }
-
-    return err;
-}
-
-status_t SensorDevice::batch(
-        void* ident,
-        int handle,
-        int flags,
-        int64_t samplingPeriodNs,
-        int64_t maxBatchReportLatencyNs) {
-    if (mSensors == NULL) return NO_INIT;
-
-    if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
-        samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
-    }
-
-    ALOGD_IF(DEBUG_CONNECTIONS,
-             "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
-             ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
-
-    Mutex::Autolock _l(mLock);
-    Info& info(mActivationCount.editValueFor(handle));
-
-    if (info.batchParams.indexOfKey(ident) < 0) {
-        BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
-        info.batchParams.add(ident, params);
-    } else {
-        // A batch has already been called with this ident. Update the batch parameters.
-        info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
-    }
-
-    BatchParams prevBestBatchParams = info.bestBatchParams;
-    // Find the minimum of all timeouts and batch_rates for this sensor.
-    info.selectBatchParams();
-
-    ALOGD_IF(DEBUG_CONNECTIONS,
-             "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
-             " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
-             prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
-             prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
-
-    status_t err(NO_ERROR);
-    // If the min period or min timeout has changed since the last batch call, call batch.
-    if (prevBestBatchParams != info.bestBatchParams) {
-        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
-                 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
-                 info.bestBatchParams.batchTimeout);
-        err = StatusFromResult(
-                mSensors->batch(
-                    handle,
-                    info.bestBatchParams.batchDelay,
-                    info.bestBatchParams.batchTimeout));
-        if (err != NO_ERROR) {
-            ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
-                  mSensors.get(), handle,
-                  info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
-                  info.bestBatchParams.batchTimeout, strerror(-err));
-            info.removeBatchParamsForIdent(ident);
-        }
-    }
-    return err;
-}
-
-status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
-    if (mSensors == NULL) return NO_INIT;
-    if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
-        samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
-    }
-    Mutex::Autolock _l(mLock);
-    if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
-    Info& info( mActivationCount.editValueFor(handle) );
-    // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
-    // Calling setDelay() in batch mode is an invalid operation.
-    if (info.bestBatchParams.batchTimeout != 0) {
-      return INVALID_OPERATION;
-    }
-    ssize_t index = info.batchParams.indexOfKey(ident);
-    if (index < 0) {
-        return BAD_INDEX;
-    }
-    BatchParams& params = info.batchParams.editValueAt(index);
-    params.batchDelay = samplingPeriodNs;
-    info.selectBatchParams();
-
-    return StatusFromResult(
-            mSensors->batch(handle, info.bestBatchParams.batchDelay, 0));
-}
-
-int SensorDevice::getHalDeviceVersion() const {
-    if (mSensors == NULL) return -1;
-    return SENSORS_DEVICE_API_VERSION_1_4;
-}
-
-status_t SensorDevice::flush(void* ident, int handle) {
-    if (isClientDisabled(ident)) return INVALID_OPERATION;
-    ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
-    return StatusFromResult(mSensors->flush(handle));
-}
-
-bool SensorDevice::isClientDisabled(void* ident) {
-    Mutex::Autolock _l(mLock);
-    return isClientDisabledLocked(ident);
-}
-
-bool SensorDevice::isClientDisabledLocked(void* ident) {
-    return mDisabledClients.indexOf(ident) >= 0;
-}
-
-void SensorDevice::enableAllSensors() {
-    Mutex::Autolock _l(mLock);
-    mDisabledClients.clear();
-    ALOGI("cleared mDisabledClients");
-    for (size_t i = 0; i< mActivationCount.size(); ++i) {
-        Info& info = mActivationCount.editValueAt(i);
-        if (info.batchParams.isEmpty()) continue;
-        info.selectBatchParams();
-        const int sensor_handle = mActivationCount.keyAt(i);
-        ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
-                   sensor_handle);
-        status_t err = StatusFromResult(
-                mSensors->batch(
-                    sensor_handle,
-                    info.bestBatchParams.batchDelay,
-                    info.bestBatchParams.batchTimeout));
-        ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
-
-        if (err == NO_ERROR) {
-            err = StatusFromResult(
-                    mSensors->activate(sensor_handle, 1 /* enabled */));
-            ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
-        }
-    }
-}
-
-void SensorDevice::disableAllSensors() {
-    Mutex::Autolock _l(mLock);
-   for (size_t i = 0; i< mActivationCount.size(); ++i) {
-        const Info& info = mActivationCount.valueAt(i);
-        // Check if this sensor has been activated previously and disable it.
-        if (info.batchParams.size() > 0) {
-           const int sensor_handle = mActivationCount.keyAt(i);
-           ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
-                   sensor_handle);
-           mSensors->activate(sensor_handle, 0 /* enabled */);
-
-           // Add all the connections that were registered for this sensor to the disabled
-           // clients list.
-           for (size_t j = 0; j < info.batchParams.size(); ++j) {
-               mDisabledClients.add(info.batchParams.keyAt(j));
-               ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
-           }
-        }
-    }
-}
-
-status_t SensorDevice::injectSensorData(
-        const sensors_event_t *injected_sensor_event) {
-    ALOGD_IF(DEBUG_CONNECTIONS,
-            "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
-            injected_sensor_event->sensor,
-            injected_sensor_event->timestamp, injected_sensor_event->data[0],
-            injected_sensor_event->data[1], injected_sensor_event->data[2],
-            injected_sensor_event->data[3], injected_sensor_event->data[4],
-            injected_sensor_event->data[5]);
-
-    Event ev;
-    convertFromSensorEvent(*injected_sensor_event, &ev);
-
-    return StatusFromResult(mSensors->injectSensorData(ev));
-}
-
-status_t SensorDevice::setMode(uint32_t mode) {
-
-     return StatusFromResult(
-             mSensors->setOperationMode(
-                 static_cast<hardware::sensors::V1_0::OperationMode>(mode)));
-}
-
-// ---------------------------------------------------------------------------
-
-int SensorDevice::Info::numActiveClients() {
-    SensorDevice& device(SensorDevice::getInstance());
-    int num = 0;
-    for (size_t i = 0; i < batchParams.size(); ++i) {
-        if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
-            ++num;
-        }
-    }
-    return num;
-}
-
-status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
-                                                    int64_t samplingPeriodNs,
-                                                    int64_t maxBatchReportLatencyNs) {
-    ssize_t index = batchParams.indexOfKey(ident);
-    if (index < 0) {
-        ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
-              ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
-        return BAD_INDEX;
-    }
-    BatchParams& params = batchParams.editValueAt(index);
-    params.flags = flags;
-    params.batchDelay = samplingPeriodNs;
-    params.batchTimeout = maxBatchReportLatencyNs;
-    return NO_ERROR;
-}
-
-void SensorDevice::Info::selectBatchParams() {
-    BatchParams bestParams(0, -1, -1);
-    SensorDevice& device(SensorDevice::getInstance());
-
-    for (size_t i = 0; i < batchParams.size(); ++i) {
-        if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
-        BatchParams params = batchParams.valueAt(i);
-        if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
-            bestParams.batchDelay = params.batchDelay;
-        }
-        if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
-            bestParams.batchTimeout = params.batchTimeout;
-        }
-    }
-    bestBatchParams = bestParams;
-}
-
-ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
-    ssize_t idx = batchParams.removeItem(ident);
-    if (idx >= 0) {
-        selectBatchParams();
-    }
-    return idx;
-}
-
-void SensorDevice::notifyConnectionDestroyed(void* ident) {
-    Mutex::Autolock _l(mLock);
-    mDisabledClients.remove(ident);
-}
-
-int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
-    Mutex::Autolock _l(mLock);
-
-    SharedMemType type;
-    switch (memory->type) {
-        case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
-            type = SharedMemType::ASHMEM;
-            break;
-        case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
-            type = SharedMemType::GRALLOC;
-            break;
-        default:
-            return BAD_VALUE;
-    }
-
-    SharedMemFormat format;
-    if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
-        return BAD_VALUE;
-    }
-    format = SharedMemFormat::SENSORS_EVENT;
-
-    SharedMemInfo mem = {
-        .type = type,
-        .format = format,
-        .size = static_cast<uint32_t>(memory->size),
-        .memoryHandle = memory->handle,
-    };
-
-    int32_t ret;
-    mSensors->registerDirectChannel(mem,
-            [&ret](auto result, auto channelHandle) {
-                if (result == Result::OK) {
-                    ret = channelHandle;
-                } else {
-                    ret = StatusFromResult(result);
-                }
-            });
-    return ret;
-}
-
-void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
-    Mutex::Autolock _l(mLock);
-    mSensors->unregisterDirectChannel(channelHandle);
-}
-
-int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
-        int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
-    Mutex::Autolock _l(mLock);
-
-    RateLevel rate;
-    switch(config->rate_level) {
-        case SENSOR_DIRECT_RATE_STOP:
-            rate = RateLevel::STOP;
-            break;
-        case SENSOR_DIRECT_RATE_NORMAL:
-            rate = RateLevel::NORMAL;
-            break;
-        case SENSOR_DIRECT_RATE_FAST:
-            rate = RateLevel::FAST;
-            break;
-        case SENSOR_DIRECT_RATE_VERY_FAST:
-            rate = RateLevel::VERY_FAST;
-            break;
-        default:
-            return BAD_VALUE;
-    }
-
-    int32_t ret;
-    mSensors->configDirectReport(sensorHandle, channelHandle, rate,
-            [&ret, rate] (auto result, auto token) {
-                if (rate == RateLevel::STOP) {
-                    ret = StatusFromResult(result);
-                } else {
-                    if (result == Result::OK) {
-                        ret = token;
-                    } else {
-                        ret = StatusFromResult(result);
-                    }
-                }
-            });
-
-    return ret;
-}
-
-bool SensorDevice::isDirectReportSupported() const {
-    return mIsDirectReportSupported;
-}
-
-void SensorDevice::convertToSensorEvent(
-        const Event &src, sensors_event_t *dst) {
-    ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
-            src, dst);
-
-    if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
-        const DynamicSensorInfo &dyn = src.u.dynamic;
-
-        dst->dynamic_sensor_meta.connected = dyn.connected;
-        dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
-        if (dyn.connected) {
-            auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
-            CHECK(it != mConnectedDynamicSensors.end());
-
-            dst->dynamic_sensor_meta.sensor = it->second;
-
-            memcpy(dst->dynamic_sensor_meta.uuid,
-                   dyn.uuid.data(),
-                   sizeof(dst->dynamic_sensor_meta.uuid));
-        }
-    }
-}
-
-void SensorDevice::convertToSensorEvents(
-        const hidl_vec<Event> &src,
-        const hidl_vec<SensorInfo> &dynamicSensorsAdded,
-        sensors_event_t *dst) {
-    // Allocate a sensor_t structure for each dynamic sensor added and insert
-    // it into the dictionary of connected dynamic sensors keyed by handle.
-    for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
-        const SensorInfo &info = dynamicSensorsAdded[i];
-
-        auto it = mConnectedDynamicSensors.find(info.sensorHandle);
-        CHECK(it == mConnectedDynamicSensors.end());
-
-        sensor_t *sensor = new sensor_t;
-        convertToSensor(info, sensor);
-
-        mConnectedDynamicSensors.insert(
-                std::make_pair(sensor->handle, sensor));
-    }
-
-    for (size_t i = 0; i < src.size(); ++i) {
-        convertToSensorEvent(src[i], &dst[i]);
-    }
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
index 662f320..b096e1c 100644 (file)
@@ -189,13 +189,16 @@ bool SensorService::SensorDirectConnection::isEquivalent(const sensors_direct_me
                 if (fstat(fd1, &s1) < 0 || fstat(fd2, &s2) < 0 || s1.st_ino == s2.st_ino) {
                     ret = true;
                 }
+                break;
             }
             case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
                 LOG_FATAL("%s: Implement GRALLOC or remove", __FUNCTION__);
                 ret = true;
+                break;
             default:
                 ALOGE("Unexpected mem type %d", mMem.type);
                 ret = true;
+                break;
         }
     }
     return ret;
index 1996a00..34cd8dd 100644 (file)
@@ -54,6 +54,7 @@ size_t eventSizeBySensorType(int type) {
         case SENSOR_TYPE_STATIONARY_DETECT:
         case SENSOR_TYPE_MOTION_DETECT:
         case SENSOR_TYPE_HEART_BEAT:
+        case SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT:
             return 1;
 
         default:
index 0e05d54..aa8f189 100644 (file)
@@ -49,14 +49,11 @@ LOCAL_C_INCLUDES := \
 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 @@ endif
 
 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 \
index 1bd9616..3e9ef24 100644 (file)
@@ -20,6 +20,7 @@
 #include <android/dvr/composer/1.0/IVrComposerClient.h>
 #include <inttypes.h>
 #include <log/log.h>
+#include <gui/BufferQueue.h>
 
 #include "ComposerHal.h"
 
@@ -123,13 +124,11 @@ void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId)
     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");
@@ -221,9 +220,8 @@ Error Composer::acceptDisplayChanges(Display display)
 
 Error Composer::createLayer(Display display, Layer* outLayer)
 {
-    const uint32_t bufferSlotCount = 1;
     Error error = kDefaultError;
-    mClient->createLayer(display, bufferSlotCount,
+    mClient->createLayer(display, BufferQueue::NUM_BUFFER_SLOTS,
             [&](const auto& tmpError, const auto& tmpLayer) {
                 error = tmpError;
                 if (error != Error::NONE) {
@@ -427,12 +425,13 @@ Error Composer::setActiveConfig(Display display, Config config)
     return unwrapRet(ret);
 }
 
-Error Composer::setClientTarget(Display display, const native_handle_t* target,
+Error Composer::setClientTarget(Display display, uint32_t slot,
+        const native_handle_t* target,
         int acquireFence, Dataspace dataspace,
         const std::vector<IComposerClient::Rect>& damage)
 {
     mWriter.selectDisplay(display);
-    mWriter.setClientTarget(0, target, acquireFence, dataspace, damage);
+    mWriter.setClientTarget(slot, target, acquireFence, dataspace, damage);
     return Error::NONE;
 }
 
@@ -472,7 +471,7 @@ Error Composer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
 
 Error Composer::setClientTargetSlotCount(Display display)
 {
-    const uint32_t bufferSlotCount = 1;
+    const uint32_t bufferSlotCount = BufferQueue::NUM_BUFFER_SLOTS;
     auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
     return unwrapRet(ret);
 }
@@ -503,11 +502,11 @@ Error Composer::setCursorPosition(Display display, Layer layer,
 }
 
 Error Composer::setLayerBuffer(Display display, Layer layer,
-        const native_handle_t* buffer, int acquireFence)
+        uint32_t slot, const native_handle_t* buffer, int acquireFence)
 {
     mWriter.selectDisplay(display);
     mWriter.selectLayer(layer);
-    mWriter.setLayerBuffer(0, buffer, acquireFence);
+    mWriter.setLayerBuffer(slot, buffer, acquireFence);
     return Error::NONE;
 }
 
@@ -621,8 +620,7 @@ Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z)
 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);
index 329d787..18af9dd 100644 (file)
@@ -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 @@ private:
 // 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 @@ public:
     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);
@@ -172,7 +172,14 @@ public:
     Error presentDisplay(Display display, int* outPresentFence);
 
     Error setActiveConfig(Display display, Config config);
-    Error setClientTarget(Display display, const native_handle_t* target,
+
+    /*
+     * The composer caches client targets internally.  When target is nullptr,
+     * the composer uses slot to look up the client target from its cache.
+     * When target is not nullptr, the cache is updated with the new target.
+     */
+    Error setClientTarget(Display display, uint32_t slot,
+            const native_handle_t* target,
             int acquireFence, Dataspace dataspace,
             const std::vector<IComposerClient::Rect>& damage);
     Error setColorMode(Display display, ColorMode mode);
@@ -190,7 +197,8 @@ public:
 
     Error setCursorPosition(Display display, Layer layer,
             int32_t x, int32_t y);
-    Error setLayerBuffer(Display display, Layer layer,
+    /* see setClientTarget for the purpose of slot */
+    Error setLayerBuffer(Display display, Layer layer, uint32_t slot,
             const native_handle_t* buffer, int acquireFence);
     Error setLayerSurfaceDamage(Display display, Layer layer,
             const std::vector<IComposerClient::Rect>& damage);
@@ -240,7 +248,9 @@ private:
     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
index d801bb3..cb08f08 100644 (file)
@@ -25,6 +25,7 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
+class Fence;
 class IGraphicBufferProducer;
 class String8;
 
index 1998edf..d3d0d51 100644 (file)
@@ -100,16 +100,18 @@ status_t FramebufferSurface::prepareFrame(CompositionType /*compositionType*/) {
 
 status_t FramebufferSurface::advanceFrame() {
 #ifdef USE_HWC2
+    uint32_t slot = 0;
     sp<GraphicBuffer> buf;
     sp<Fence> acquireFence(Fence::NO_FENCE);
     android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN;
-    status_t result = nextBuffer(buf, acquireFence, dataspace);
+    status_t result = nextBuffer(slot, buf, acquireFence, dataspace);
     if (result != NO_ERROR) {
         ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
                 strerror(-result), result);
         return result;
     }
-    result = mHwc.setClientTarget(mDisplayType, acquireFence, buf, dataspace);
+    result = mHwc.setClientTarget(mDisplayType, slot,
+            acquireFence, buf, dataspace);
     if (result != NO_ERROR) {
         ALOGE("error posting framebuffer: %d", result);
     }
@@ -123,8 +125,9 @@ status_t FramebufferSurface::advanceFrame() {
 }
 
 #ifdef USE_HWC2
-status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer,
-        sp<Fence>& outFence, android_dataspace_t& outDataspace) {
+status_t FramebufferSurface::nextBuffer(uint32_t& outSlot,
+        sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
+        android_dataspace_t& outDataspace) {
 #else
 status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
 #endif
@@ -133,7 +136,12 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>&
     BufferItem item;
     status_t err = acquireBufferLocked(&item, 0);
     if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
+#ifdef USE_HWC2
+        mHwcBufferCache->getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
+                &outSlot, &outBuffer);
+#else
         outBuffer = mCurrentBuffer;
+#endif
         return NO_ERROR;
     } else if (err != NO_ERROR) {
         ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
@@ -169,9 +177,12 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>&
     mCurrentFence = item.mFence;
 
     outFence = item.mFence;
-    outBuffer = mCurrentBuffer;
 #ifdef USE_HWC2
+    mHwcBufferCache->getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
+            &outSlot, &outBuffer);
     outDataspace = item.mDataSpace;
+#else
+    outBuffer = mCurrentBuffer;
 #endif
     return NO_ERROR;
 }
index 439435a..5eea6b6 100644 (file)
 #ifndef ANDROID_SF_FRAMEBUFFER_SURFACE_H
 #define ANDROID_SF_FRAMEBUFFER_SURFACE_H
 
+#include "DisplaySurface.h"
+
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <gui/ConsumerBase.h>
 
-#include "DisplaySurface.h"
+#include <memory>
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -31,6 +33,7 @@ namespace android {
 class Rect;
 class String8;
 class HWComposer;
+class HWComposerBufferCache;
 
 // ---------------------------------------------------------------------------
 
@@ -68,8 +71,8 @@ private:
     // BufferQueue and releases the previously latched buffer to the
     // BufferQueue.  The new buffer is returned in the 'buffer' argument.
 #ifdef USE_HWC2
-    status_t nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
-            android_dataspace_t& outDataspace);
+    status_t nextBuffer(uint32_t& outSlot, sp<GraphicBuffer>& outBuffer,
+            sp<Fence>& outFence, android_dataspace_t& outDataspace);
 #else
     status_t nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence);
 #endif
@@ -93,6 +96,9 @@ private:
     HWComposer& mHwc;
 
 #ifdef USE_HWC2
+    std::unique_ptr<HWComposerBufferCache> mHwcBufferCache =
+        std::make_unique<HWComposerBufferCache>();
+
     // Previous buffer to release after getting an updated retire fence
     bool mHasPendingRelease;
     int mPreviousBufferSlot;
index 6ff5ea1..a25e8a1 100644 (file)
@@ -135,8 +135,8 @@ Device::Device(hwc2_device_t* device)
     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(),
@@ -962,17 +962,18 @@ Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
     return static_cast<Error>(intError);
 }
 
-Error Display::setClientTarget(buffer_handle_t target,
+Error Display::setClientTarget(uint32_t slot, buffer_handle_t target,
         const sp<Fence>& acquireFence, android_dataspace_t dataspace)
 {
     // TODO: Properly encode client target surface damage
     int32_t fenceFd = acquireFence->dup();
 #ifdef BYPASS_IHWC
+    (void) slot;
     int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
             fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
 #else
-    auto intError = mDevice.mComposer->setClientTarget(mId, target, fenceFd,
-            static_cast<Hwc2::Dataspace>(dataspace),
+    auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
+            fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
             std::vector<Hwc2::IComposerClient::Rect>());
 #endif
     return static_cast<Error>(intError);
@@ -1195,16 +1196,17 @@ Error Layer::setCursorPosition(int32_t x, int32_t y)
     return static_cast<Error>(intError);
 }
 
-Error Layer::setBuffer(buffer_handle_t buffer,
+Error Layer::setBuffer(uint32_t slot, buffer_handle_t buffer,
         const sp<Fence>& acquireFence)
 {
     int32_t fenceFd = acquireFence->dup();
 #ifdef BYPASS_IHWC
+    (void) slot;
     int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
             mId, buffer, fenceFd);
 #else
     auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
-            mId, buffer, fenceFd);
+            mId, slot, buffer, fenceFd);
 #endif
     return static_cast<Error>(intError);
 }
index 256b05d..93eb999 100644 (file)
@@ -67,7 +67,10 @@ public:
 #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 @@ public:
 
     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
 
@@ -322,7 +331,7 @@ public:
     [[clang::warn_unused_result]] Error setActiveConfig(
             const std::shared_ptr<const Config>& config);
     [[clang::warn_unused_result]] Error setClientTarget(
-            buffer_handle_t target,
+            uint32_t slot, buffer_handle_t target,
             const android::sp<android::Fence>& acquireFence,
             android_dataspace_t dataspace);
     [[clang::warn_unused_result]] Error setColorMode(android_color_mode_t mode);
@@ -384,7 +393,8 @@ public:
     hwc2_layer_t getId() const { return mId; }
 
     [[clang::warn_unused_result]] Error setCursorPosition(int32_t x, int32_t y);
-    [[clang::warn_unused_result]] Error setBuffer(buffer_handle_t buffer,
+    [[clang::warn_unused_result]] Error setBuffer(uint32_t slot,
+            buffer_handle_t buffer,
             const android::sp<android::Fence>& acquireFence);
     [[clang::warn_unused_result]] Error setSurfaceDamage(
             const android::Region& damage);
index 37de7a2..a6171f5 100644 (file)
@@ -1298,6 +1298,7 @@ bool HWC2On1Adapter::Display::prepare()
         auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
         hwc1Layer.releaseFenceFd = -1;
         hwc1Layer.acquireFenceFd = -1;
+        ALOGV("Applying states for layer %" PRIu64 " ", layer->getId());
         layer->applyState(hwc1Layer, applyAllState);
     }
 
@@ -2009,8 +2010,8 @@ HWC2On1Adapter::Layer::Layer(Display& display)
     mZ(0),
     mReleaseFence(),
     mHwc1Id(0),
-    mHasUnsupportedDataspace(false),
-    mHasUnsupportedPlaneAlpha(false) {}
+    mHasUnsupportedPlaneAlpha(false),
+    mHasUnsupportedBackgroundColor(false) {}
 
 bool HWC2On1Adapter::SortLayersByZ::operator()(
         const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs)
@@ -2070,9 +2071,8 @@ Error HWC2On1Adapter::Layer::setCompositionType(Composition type)
     return Error::None;
 }
 
-Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t dataspace)
+Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t)
 {
-    mHasUnsupportedDataspace = (dataspace != HAL_DATASPACE_UNKNOWN);
     return Error::None;
 }
 
@@ -2318,8 +2318,13 @@ void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer,
     // HWC1 never supports color transforms or dataspaces and only sometimes
     // supports plane alpha (depending on the version). These require us to drop
     // some or all layers to client composition.
-    if (mHasUnsupportedDataspace || mHasUnsupportedPlaneAlpha ||
-            mDisplay.hasColorTransform() || mHasUnsupportedBackgroundColor) {
+    ALOGV("applyCompositionType");
+    ALOGV("mHasUnsupportedPlaneAlpha = %d", mHasUnsupportedPlaneAlpha);
+    ALOGV("mDisplay.hasColorTransform() = %d", mDisplay.hasColorTransform());
+    ALOGV("mHasUnsupportedBackgroundColor = %d", mHasUnsupportedBackgroundColor);
+
+    if (mHasUnsupportedPlaneAlpha || mDisplay.hasColorTransform() ||
+        mHasUnsupportedBackgroundColor) {
         hwc1Layer.compositionType = HWC_FRAMEBUFFER;
         hwc1Layer.flags = HWC_SKIP_LAYER;
         return;
@@ -2462,7 +2467,7 @@ bool HWC2On1Adapter::prepareAllDisplays()
         }
     }
 
-    if (mHwc1DisplayMap.count(0) == 0) {
+    if (mHwc1DisplayMap.count(HWC_DISPLAY_PRIMARY) == 0) {
         ALOGE("prepareAllDisplays: Unable to find primary HWC1 display");
         return false;
     }
index 9abdc38..df33ec3 100644 (file)
@@ -605,7 +605,6 @@ private:
             DeferredFence mReleaseFence;
 
             size_t mHwc1Id;
-            bool mHasUnsupportedDataspace;
             bool mHasUnsupportedPlaneAlpha;
             bool mHasUnsupportedBackgroundColor;
     };
index 7914770..4a281d4 100644 (file)
@@ -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,9 +60,8 @@ namespace android {
 
 // ---------------------------------------------------------------------------
 
-HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
-    : mFlinger(flinger),
-      mAdapter(),
+HWComposer::HWComposer(bool useVrComposer)
+    : mAdapter(),
       mHwcDevice(),
       mDisplayData(2),
       mFreeDisplaySlots(),
@@ -76,7 +76,7 @@ HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
         mVSyncCounts[i] = 0;
     }
 
-    loadHwcModule();
+    loadHwcModule(useVrComposer);
 }
 
 HWComposer::~HWComposer() {}
@@ -105,11 +105,13 @@ void HWComposer::setEventHandler(EventHandler* handler)
 }
 
 // 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 +144,7 @@ void HWComposer::loadHwcModule()
                 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();
@@ -208,7 +210,7 @@ void HWComposer::hotplug(const std::shared_ptr<HWC2::Display>& display,
 }
 
 void HWComposer::invalidate(const std::shared_ptr<HWC2::Display>& /*display*/) {
-    mFlinger->repaintEverything();
+    mEventHandler->onInvalidateReceived(this);
 }
 
 void HWComposer::vsync(const std::shared_ptr<HWC2::Display>& display,
@@ -254,7 +256,7 @@ void HWComposer::vsync(const std::shared_ptr<HWC2::Display>& display,
     snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
     ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
 
-    mEventHandler->onVSyncReceived(disp, timestamp);
+    mEventHandler->onVSyncReceived(this, disp, timestamp);
 }
 
 status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
@@ -444,7 +446,7 @@ void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) {
     }
 }
 
-status_t HWComposer::setClientTarget(int32_t displayId,
+status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot,
         const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
         android_dataspace_t dataspace) {
     if (!isValidDisplay(displayId)) {
@@ -457,7 +459,8 @@ status_t HWComposer::setClientTarget(int32_t displayId,
     if ((target != nullptr) && target->getNativeBuffer()) {
         handle = target->getNativeBuffer()->handle;
     }
-    auto error = hwcDisplay->setClientTarget(handle, acquireFence, dataspace);
+    auto error = hwcDisplay->setClientTarget(slot, handle,
+            acquireFence, dataspace);
     if (error != HWC2::Error::None) {
         ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
                 to_string(error).c_str(), static_cast<int32_t>(error));
@@ -866,6 +869,14 @@ static String8 getFormatStr(PixelFormat format) {
 }
 */
 
+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
@@ -894,5 +905,41 @@ void HWComposer::DisplayData::reset() {
     *this = DisplayData();
 }
 
+void HWComposerBufferCache::clear()
+{
+    mBuffers.clear();
+}
+
+void HWComposerBufferCache::getHwcBuffer(int slot,
+        const sp<GraphicBuffer>& buffer,
+        uint32_t* outSlot, sp<GraphicBuffer>* outBuffer)
+{
+#ifdef BYPASS_IHWC
+    *outSlot = slot;
+    *outBuffer = buffer;
+#else
+    if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) {
+        // default to slot 0
+        slot = 0;
+    }
+
+    if (static_cast<size_t>(slot) >= mBuffers.size()) {
+        mBuffers.resize(slot + 1);
+    }
+
+    *outSlot = slot;
+
+    if (mBuffers[slot] == buffer) {
+        // already cached in HWC, skip sending the buffer
+        *outBuffer = nullptr;
+    } else {
+        *outBuffer = buffer;
+
+        // update cache
+        mBuffers[slot] = buffer;
+    }
+#endif
+}
+
 // ---------------------------------------------------------------------------
 }; // namespace android
index 2713505..0713709 100644 (file)
@@ -26,6 +26,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <gui/BufferQueue.h>
+
 #include <ui/Fence.h>
 
 #include <utils/BitSet.h>
@@ -62,20 +64,24 @@ class HWC2On1Adapter;
 class NativeHandle;
 class Region;
 class String8;
-class SurfaceFlinger;
 
 class HWComposer
 {
 public:
     class EventHandler {
         friend class HWComposer;
-        virtual void onVSyncReceived(int32_t disp, nsecs_t timestamp) = 0;
+        virtual void onVSyncReceived(
+            HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
         virtual void onHotplugReceived(int32_t disp, bool connected) = 0;
+        virtual void onInvalidateReceived(HWComposer* composer) = 0;
     protected:
         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(bool useVrComposer);
 
     ~HWComposer();
 
@@ -94,7 +100,8 @@ public:
     // Asks the HAL what it can do
     status_t prepare(DisplayDevice& displayDevice);
 
-    status_t setClientTarget(int32_t displayId, const sp<Fence>& acquireFence,
+    status_t setClientTarget(int32_t displayId, uint32_t slot,
+            const sp<Fence>& acquireFence,
             const sp<GraphicBuffer>& target, android_dataspace_t dataspace);
 
     // Present layers to the display and read releaseFences.
@@ -162,13 +169,16 @@ public:
 
     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);
@@ -202,7 +212,6 @@ private:
         HWC2::Vsync vsyncEnabled;
     };
 
-    sp<SurfaceFlinger>              mFlinger;
     std::unique_ptr<HWC2On1Adapter> mAdapter;
     std::unique_ptr<HWC2::Device>   mHwcDevice;
     std::vector<DisplayData>        mDisplayData;
@@ -224,6 +233,19 @@ private:
     mutable Mutex mVsyncLock;
 };
 
+class HWComposerBufferCache {
+public:
+    void clear();
+
+    void getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer,
+            uint32_t* outSlot, sp<GraphicBuffer>* outBuffer);
+
+private:
+    // a vector as we expect "slot" to be in the range of [0, 63] (that is,
+    // less than BufferQueue::NUM_BUFFER_SLOTS).
+    std::vector<sp<GraphicBuffer>> mBuffers;
+};
+
 // ---------------------------------------------------------------------------
 }; // namespace android
 
index cc5578d..0bfc56e 100644 (file)
@@ -277,7 +277,7 @@ void HWComposer::hook_hotplug(const struct hwc_procs* procs, int disp,
 }
 
 void HWComposer::invalidate() {
-    mFlinger->repaintEverything();
+    mEventHandler.onInvalidateReceived(this);
 }
 
 void HWComposer::vsync(int disp, int64_t timestamp) {
@@ -302,7 +302,7 @@ void HWComposer::vsync(int disp, int64_t timestamp) {
         snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
         ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
 
-        mEventHandler.onVSyncReceived(disp, timestamp);
+        mEventHandler.onVSyncReceived(this, disp, timestamp);
     }
 }
 
@@ -1318,7 +1318,7 @@ bool HWComposer::VSyncThread::threadLoop() {
     } while (err<0 && errno == EINTR);
 
     if (err == 0) {
-        mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
+        mHwc.mEventHandler.onVSyncReceived(&mHwc, 0, next_vsync);
     }
 
     return true;
index bca25ac..a94bc1e 100644 (file)
@@ -62,8 +62,10 @@ class HWComposer
 public:
     class EventHandler {
         friend class HWComposer;
-        virtual void onVSyncReceived(int disp, nsecs_t timestamp) = 0;
+        virtual void onVSyncReceived(
+            HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
         virtual void onHotplugReceived(int disp, bool connected) = 0;
+        virtual void onInvalidateReceived(HWComposer* composer) = 0;
     protected:
         virtual ~EventHandler() {}
     };
index 6a98f03..5f3c388 100644 (file)
@@ -221,9 +221,14 @@ status_t VirtualDisplaySurface::advanceFrame() {
     status_t result = NO_ERROR;
     if (fbBuffer != NULL) {
 #ifdef USE_HWC2
+        uint32_t hwcSlot = 0;
+        sp<GraphicBuffer> hwcBuffer;
+        mHwcBufferCache->getHwcBuffer(mFbProducerSlot, fbBuffer,
+                &hwcSlot, &hwcBuffer);
+
         // TODO: Correctly propagate the dataspace from GL composition
-        result = mHwc.setClientTarget(mDisplayId, mFbFence, fbBuffer,
-                HAL_DATASPACE_UNKNOWN);
+        result = mHwc.setClientTarget(mDisplayId, hwcSlot, mFbFence,
+                hwcBuffer, HAL_DATASPACE_UNKNOWN);
 #else
         result = mHwc.fbPost(mDisplayId, mFbFence, fbBuffer);
 #endif
index d37dc0a..2636667 100644 (file)
 #ifndef ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
 #define ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
 
+#include "DisplaySurface.h"
+
 #include <gui/ConsumerBase.h>
 #include <gui/IGraphicBufferProducer.h>
 
-#include "DisplaySurface.h"
+#include <memory>
 
 // ---------------------------------------------------------------------------
 namespace android {
 // ---------------------------------------------------------------------------
 
 class HWComposer;
+class HWComposerBufferCache;
 class IProducerListener;
 
 /* This DisplaySurface implementation supports virtual displays, where GLES
@@ -250,6 +253,11 @@ private:
     static const char* dbgSourceStr(Source s);
 
     bool mMustRecompose;
+
+#ifdef USE_HWC2
+    std::unique_ptr<HWComposerBufferCache> mHwcBufferCache =
+        std::make_unique<HWComposerBufferCache>();
+#endif
 };
 
 // ---------------------------------------------------------------------------
index 41fb48c..a854aec 100644 (file)
@@ -274,6 +274,16 @@ void Layer::onFrameReplaced(const BufferItem& item) {
     }
 }
 
+void Layer::onBuffersReleased() {
+#ifdef USE_HWC2
+    Mutex::Autolock lock(mHwcBufferCacheMutex);
+
+    for (auto info : mHwcBufferCaches) {
+        info.second.clear();
+    }
+#endif
+}
+
 void Layer::onSidebandStreamChanged() {
     if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
         // mSidebandStreamChanged was false
@@ -421,7 +431,9 @@ Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
     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();
@@ -840,8 +852,22 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
               static_cast<int32_t>(error));
     }
 
+    uint32_t hwcSlot = 0;
+    buffer_handle_t hwcHandle = nullptr;
+    {
+        Mutex::Autolock lock(mHwcBufferCacheMutex);
+
+        auto& hwcBufferCache = mHwcBufferCaches[hwcId];
+        sp<GraphicBuffer> hwcBuffer;
+        hwcBufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer,
+                &hwcSlot, &hwcBuffer);
+        if (hwcBuffer != nullptr) {
+            hwcHandle = hwcBuffer->handle;
+        }
+    }
+
     auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
-    error = hwcLayer->setBuffer(mActiveBuffer->handle, acquireFence);
+    error = hwcLayer->setBuffer(hwcSlot, hwcHandle, acquireFence);
     if (error != HWC2::Error::None) {
         ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
                 mActiveBuffer->handle, to_string(error).c_str(),
@@ -2091,7 +2117,8 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime)
     }
 
     // update the active buffer
-    mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
+    mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(
+            &mActiveBufferSlot);
     if (mActiveBuffer == NULL) {
         // this can only happen if the very first buffer was rejected.
         return outDirtyRegion;
index c09b8d9..8227dae 100644 (file)
@@ -376,13 +376,20 @@ public:
 #ifdef USE_HWC2
     // -----------------------------------------------------------------------
 
+    void eraseHwcLayer(int32_t hwcId) {
+        mHwcLayers.erase(hwcId);
+
+        Mutex::Autolock lock(mHwcBufferCacheMutex);
+        mHwcBufferCaches.erase(hwcId);
+    }
+
     bool hasHwcLayer(int32_t hwcId) {
         if (mHwcLayers.count(hwcId) == 0) {
             return false;
         }
         if (mHwcLayers[hwcId].layer->isAbandoned()) {
             ALOGI("Erasing abandoned layer %s on %d", mName.string(), hwcId);
-            mHwcLayers.erase(hwcId);
+            eraseHwcLayer(hwcId);
             return false;
         }
         return true;
@@ -398,11 +405,18 @@ public:
     void setHwcLayer(int32_t hwcId, std::shared_ptr<HWC2::Layer>&& layer) {
         if (layer) {
             mHwcLayers[hwcId].layer = layer;
+
+            Mutex::Autolock lock(mHwcBufferCacheMutex);
+            mHwcBufferCaches[hwcId] = HWComposerBufferCache();
         } else {
-            mHwcLayers.erase(hwcId);
+            eraseHwcLayer(hwcId);
         }
     }
 
+    void clearHwcLayers() {
+        mHwcLayers.clear();
+    }
+
 #endif
     // -----------------------------------------------------------------------
 
@@ -489,6 +503,7 @@ private:
     // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
     virtual void onFrameAvailable(const BufferItem& item) override;
     virtual void onFrameReplaced(const BufferItem& item) override;
+    virtual void onBuffersReleased() override;
     virtual void onSidebandStreamChanged() override;
 
     void commitTransaction(const State& stateToCommit);
@@ -642,6 +657,7 @@ private:
     FenceTimeline mReleaseTimeline;
 
     // main thread
+    int mActiveBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
     sp<GraphicBuffer> mActiveBuffer;
     sp<NativeHandle> mSidebandStream;
     Rect mCurrentCrop;
@@ -681,6 +697,12 @@ private:
         gfx::FloatRect sourceCrop;
     };
     std::unordered_map<int32_t, HWCInfo> mHwcLayers;
+
+    // We need one HWComposerBufferCache for each HWC display.  We cannot have
+    // HWComposerBufferCache in HWCInfo because HWCInfo can only be accessed
+    // from the main thread.
+    Mutex mHwcBufferCacheMutex;
+    std::unordered_map<int32_t, HWComposerBufferCache> mHwcBufferCaches;
 #else
     bool mIsGlesComposition;
 #endif
index 70bd7be..d2dddba 100644 (file)
@@ -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 @@ SurfaceFlinger::SurfaceFlinger()
         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 @@ SurfaceFlinger::SurfaceFlinger()
         mFrameBuckets(),
         mTotalTime(0),
         mLastSwapTime(0),
-        mNumLayers(0)
+        mNumLayers(0),
+        mEnterVrMode(false)
 {
     ALOGI("SurfaceFlinger is starting");
 
@@ -208,12 +215,12 @@ SurfaceFlinger::SurfaceFlinger()
     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 @@ SurfaceFlinger::~SurfaceFlinger()
     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 @@ void SurfaceFlinger::bootFinished()
     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 @@ void SurfaceFlinger::init() {
     // 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);
@@ -1078,7 +1102,14 @@ void SurfaceFlinger::resyncWithRateLimit() {
     }
 }
 
-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
@@ -1109,7 +1140,13 @@ void SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
         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;
@@ -1138,16 +1175,99 @@ void SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
     }
 }
 
+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() ==
@@ -1832,16 +1952,10 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                                 "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));
@@ -2344,6 +2458,7 @@ bool SurfaceFlinger::doComposeSurfaces(
                 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 &&
index 743d58b..f52bd2d 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef ANDROID_SURFACE_FLINGER_H
 #define ANDROID_SURFACE_FLINGER_H
 
+#include <memory>
 #include <stdint.h>
 #include <sys/types.h>
 
@@ -85,6 +86,11 @@ class RenderEngine;
 class EventControlThread;
 class VSyncSource;
 class InjectVSyncSource;
+class VrStateCallbacks;
+
+namespace dvr {
+class VrFlinger;
+} // namespace dvr
 
 // ---------------------------------------------------------------------------
 
@@ -160,6 +166,7 @@ private:
     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.
@@ -244,8 +251,9 @@ private:
     /* ------------------------------------------------------------------------
      * HWComposer::EventHandler interface
      */
-    virtual void onVSyncReceived(int type, nsecs_t timestamp);
+    virtual void onVSyncReceived(HWComposer* composer, int type, nsecs_t timestamp);
     virtual void onHotplugReceived(int disp, bool connected);
+    virtual void onInvalidateReceived(HWComposer* composer);
 
     /* ------------------------------------------------------------------------
      * Message handling
@@ -468,6 +476,19 @@ private:
     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
      */
@@ -489,8 +510,13 @@ private:
     // 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;
@@ -503,6 +529,10 @@ private:
     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;
@@ -540,7 +570,7 @@ private:
     bool mPropagateBackpressure = true;
 #endif
     SurfaceInterceptor mInterceptor;
-    bool mUseHwcVirtualDisplays = true;
+    bool mUseHwcVirtualDisplays = false;
 
     // Restrict layers to use two buffers in their bufferqueues.
     bool mLayerTripleBufferingDisabled = false;
@@ -620,6 +650,12 @@ private:
     // 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
index 029937a..942af13 100644 (file)
@@ -235,6 +235,19 @@ void SurfaceFlingerConsumer::setContentsChangedListener(
     mContentsChangedListener = listener;
 }
 
+void SurfaceFlingerConsumer::onBuffersReleased() {
+    sp<ContentsChangedListener> listener;
+    {   // scope for the lock
+        Mutex::Autolock lock(mMutex);
+        ALOG_ASSERT(mFrameAvailableListener.unsafe_get() == mContentsChangedListener.unsafe_get());
+        listener = mContentsChangedListener.promote();
+    }
+
+    if (listener != NULL) {
+        listener->onBuffersReleased();
+    }
+}
+
 void SurfaceFlingerConsumer::onSidebandStreamChanged() {
     sp<ContentsChangedListener> listener;
     {   // scope for the lock
index d3f0070..7713ed2 100644 (file)
@@ -33,6 +33,7 @@ public:
     static const status_t BUFFER_REJECTED = UNKNOWN_ERROR + 8;
 
     struct ContentsChangedListener: public FrameAvailableListener {
+        virtual void onBuffersReleased() = 0;
         virtual void onSidebandStreamChanged() = 0;
     };
 
@@ -89,6 +90,7 @@ public:
             FrameEventHistoryDelta* outDelta) override;
 
 private:
+    virtual void onBuffersReleased();
     virtual void onSidebandStreamChanged();
 
     wp<ContentsChangedListener> mContentsChangedListener;
index 7fcc41a..477eb27 100644 (file)
@@ -188,12 +188,12 @@ SurfaceFlinger::SurfaceFlinger()
     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");
 }
 
@@ -1018,7 +1018,8 @@ void SurfaceFlinger::resyncWithRateLimit() {
     }
 }
 
-void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
+void SurfaceFlinger::onVSyncReceived(HWComposer* /*composer*/, int type,
+                                     nsecs_t timestamp) {
     bool needsHwVsync = false;
 
     { // Scope for the lock
@@ -1063,6 +1064,10 @@ void SurfaceFlinger::onHotplugReceived(int type, bool connected) {
     }
 }
 
+void SurfaceFlinger::onInvalidateReceived(HWComposer* /*composer*/) {
+    repaintEverything();
+}
+
 void SurfaceFlinger::eventControl(int disp, int event, int enabled) {
     ATRACE_CALL();
     getHwComposer().eventControl(disp, event, enabled);
diff --git a/services/surfaceflinger/VrStateCallbacks.cpp b/services/surfaceflinger/VrStateCallbacks.cpp
new file mode 100644 (file)
index 0000000..a924def
--- /dev/null
@@ -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 (file)
index 0000000..4e655d3
--- /dev/null
@@ -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
index 36d8400..e213bd6 100644 (file)
@@ -46,21 +46,10 @@ sharedLibraries := \
 cFlags := -DLOG_TAG=\"sensord\" \
           -DTRACE=0
 
-ifeq ($(TARGET_USES_QCOM_BSP), true)
-ifneq ($(TARGET_QCOM_DISPLAY_VARIANT),)
-    platform := .
-else
-    platform := $(TARGET_BOARD_PLATFORM)
-endif
-    cFlags += -DQCOM_B_FAMILY \
-              -DQCOM_BSP
-endif
-
 include $(CLEAR_VARS)
 # Don't strip symbols so we see stack traces in logcat.
 LOCAL_STRIP_MODULE := false
 LOCAL_SRC_FILES := $(sourceFiles)
-PLATFORM := $(platform)
 LOCAL_CFLAGS := $(cFlags)
 LOCAL_STATIC_LIBRARIES := $(staticLibraries)
 LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
similarity index 75%
rename from services/vr/vr_window_manager/Android.mk_disable
rename to services/vr/vr_window_manager/Android.mk
index 9a6f752..85f8e1f 100644 (file)
 
 LOCAL_PATH := $(call my-dir)
 
+binder_src := \
+  vr_window_manager_binder.cpp \
+  aidl/android/service/vr/IVrWindowManager.aidl
+
+static_libs := \
+  libcutils
+
+shared_libs := \
+  libbase \
+  libbinder \
+  libutils
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(binder_src)
+LOCAL_STATIC_LIBRARIES := $(static_libs)
+LOCAL_SHARED_LIBRARIES := $(shared_libs)
+LOCAL_CPPFLAGS += -std=c++11
+LOCAL_CFLAGS += -DLOG_TAG=\"VrWindowManager\"
+LOCAL_LDLIBS := -llog
+LOCAL_MODULE := libvrwm_binder
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_STATIC_LIBRARY)
+
+
 native_src := \
   application.cpp \
   controller_mesh.cpp \
@@ -76,7 +100,6 @@ shared_libs := \
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(src)
-LOCAL_C_INCLUDES := hardware/qcom/display/msm8996/libgralloc
 LOCAL_STATIC_LIBRARIES := $(static_libs)
 LOCAL_SHARED_LIBRARIES := $(shared_libs)
 LOCAL_SHARED_LIBRARIES += libgvr
@@ -87,14 +110,14 @@ LOCAL_CFLAGS += -DLOG_TAG=\"VrWindowManager\"
 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)
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(native_src)
-LOCAL_C_INCLUDES := hardware/qcom/display/msm8996/libgralloc
-LOCAL_STATIC_LIBRARIES := $(static_libs)
+LOCAL_STATIC_LIBRARIES := $(static_libs) libvrwm_binder
 LOCAL_SHARED_LIBRARIES := $(shared_libs)
 LOCAL_SHARED_LIBRARIES += libgvr
 LOCAL_STATIC_LIBRARIES += libgvr_ext
@@ -104,6 +127,7 @@ LOCAL_CFLAGS += -DLOG_TAG=\"VrWindowManager\"
 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)
 
@@ -125,4 +149,29 @@ LOCAL_STATIC_JAVA_LIBRARIES := libprotobuf-java-nano
 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)
+
+
+cmd_src := \
+  vr_wm_ctl.cpp \
+  aidl/android/service/vr/IVrWindowManager.aidl
+
+static_libs := \
+  libcutils
+
+shared_libs := \
+  libbase \
+  libbinder \
+  libutils
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(cmd_src)
+LOCAL_STATIC_LIBRARIES := $(static_libs)
+LOCAL_SHARED_LIBRARIES := $(shared_libs)
+LOCAL_CPPFLAGS += -std=c++11
+LOCAL_CFLAGS += -DLOG_TAG=\"vrwmctl\"
+LOCAL_LDLIBS := -llog
+LOCAL_MODULE := vr_wm_ctl
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_EXECUTABLE)
index 5cc4b5c..d5008a3 100644 (file)
@@ -27,7 +27,7 @@
     <service android:name=".VrWindowManagerService" />
     <receiver android:name="com.google.vr.windowmanager.BootCompletedReceiver">
       <intent-filter>
-        <action android:name="android.intent.action.BOOT_COMPLETED" />
+        <!-- action android:name="android.intent.action.BOOT_COMPLETED" / -->
       </intent-filter>
     </receiver>
   </application>
diff --git a/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl b/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl
new file mode 100644 (file)
index 0000000..b5dbb8b
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * 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.
+ */
+
+package android.service.vr;
+
+/** @hide */
+interface IVrWindowManager {
+    const String SERVICE_NAME = "vr_window_manager";
+    void connectController(in FileDescriptor fd) = 0;
+    void disconnectController() = 1;
+    void enterVrMode() = 2;
+    void exitVrMode() = 3;
+    void setDebugMode(int mode) = 4;
+}
+
index b4568b8..895f25f 100644 (file)
@@ -161,8 +161,10 @@ void Application::ProcessTasks(const std::vector<MainThreadTask>& tasks) {
         }
         break;
       case MainThreadTask::EnteringVrMode:
-        if (!initialized_)
-          AllocateResources();
+        if (!initialized_) {
+          if (AllocateResources())
+            ALOGE("Failed to allocate resources");
+        }
         break;
       case MainThreadTask::ExitingVrMode:
         if (initialized_)
@@ -224,10 +226,8 @@ void Application::DrawFrame() {
     if (fade_value_ > 1.0f)
       fade_value_ = 1.0f;
 
-    quat controller_quat(controller_orientation_.qw, controller_orientation_.qx,
-        controller_orientation_.qy, controller_orientation_.qz);
-    controller_position_ = elbow_model_.Update(
-        delta, last_pose_.GetRotation(), controller_quat, false);
+    controller_position_ = elbow_model_.Update(delta, last_pose_.GetRotation(),
+                                               controller_orientation_, false);
 
     dvrBeginRenderFrameEds(graphics_context_, pose.orientation,
                            pose.translation);
@@ -255,6 +255,61 @@ void Application::DrawFrame() {
 }
 
 void Application::ProcessControllerInput() {
+  if (controller_data_provider_) {
+    shmem_controller_active_ = false;
+    const void* data = controller_data_provider_->LockControllerData();
+    // TODO(kpschoedel): define wire format.
+    if (data) {
+      struct wire_format {
+        uint32_t version;
+        uint32_t timestamph;
+        uint32_t timestampl;
+        uint32_t quat_count;
+        float q[4];
+        uint32_t buttonsh;
+        uint32_t buttonsl;
+      } __attribute__((__aligned__(32)));
+      const wire_format* wire_data = static_cast<const wire_format*>(data);
+      static uint64_t last_timestamp = 0;
+      if (wire_data->version == 1) {
+        shmem_controller_active_ = true;
+        uint64_t timestamp =
+            (((uint64_t)wire_data->timestamph) << 32) | wire_data->timestampl;
+        if (timestamp == last_timestamp) {
+          static uint64_t last_logged_timestamp = 0;
+          if (last_logged_timestamp != last_timestamp) {
+            last_logged_timestamp = last_timestamp;
+            ALOGI("Controller shmem stale T=0x%" PRIX64, last_timestamp);
+          }
+        } else {
+          last_timestamp = timestamp;
+          controller_orientation_ = quat(wire_data->q[3], wire_data->q[0],
+                                         wire_data->q[1], wire_data->q[2]);
+          shmem_controller_buttons_ =
+              (((uint64_t)wire_data->buttonsh) << 32) | wire_data->buttonsl;
+        }
+      } else if (wire_data->version == 0xFEEDFACE) {
+        static bool logged_init = false;
+        if (!logged_init) {
+          logged_init = true;
+          ALOGI("Controller shmem waiting for data");
+        }
+      }
+    }
+    controller_data_provider_->UnlockControllerData();
+    if (shmem_controller_active_) {
+      // TODO(kpschoedel): change to ALOGV or remove.
+      ALOGI("Controller shmem orientation: %f %f %f %f",
+            controller_orientation_.x(), controller_orientation_.y(),
+            controller_orientation_.z(), controller_orientation_.w());
+      if (shmem_controller_buttons_) {
+        ALOGI("Controller shmem buttons: %017" PRIX64,
+            shmem_controller_buttons_);
+      }
+      return;
+    }
+  }
+
   if (!controller_)
     return;
 
@@ -287,8 +342,11 @@ void Application::ProcessControllerInput() {
     controller_connection_state_logged_ = false;
   }
 
-  if (new_api_status == gvr::kControllerApiOk)
-    controller_orientation_ = controller_state_->GetOrientation();
+  if (new_api_status == gvr::kControllerApiOk) {
+    gvr_quatf orientation = controller_state_->GetOrientation();
+    controller_orientation_ =
+        quat(orientation.qw, orientation.qx, orientation.qy, orientation.qz);
+  }
 
   controller_api_status_ = new_api_status;
   controller_connection_state_ = new_connection_state;
index 47a0927..0c6385f 100644 (file)
@@ -11,6 +11,7 @@
 #include <chrono>
 #include <mutex>
 
+#include "controller_data_provider.h"
 #include "elbow_model.h"
 
 struct DvrGraphicsContext;
@@ -32,6 +33,10 @@ class Application {
 
   void DrawFrame();
 
+  void SetControllerDataProvider(ControllerDataProvider* provider) {
+    controller_data_provider_ = provider;
+  }
+
  protected:
   enum class MainThreadTask {
     EnteringVrMode,
@@ -69,9 +74,11 @@ class Application {
   std::unique_ptr<gvr::ControllerState> controller_state_;
   gvr::ControllerApiStatus controller_api_status_;
   gvr::ControllerConnectionState controller_connection_state_;
-  gvr_quatf controller_orientation_;
+  quat controller_orientation_;
+  bool shmem_controller_active_ = false;
   bool controller_api_status_logged_;
   bool controller_connection_state_logged_;
+  uint64_t shmem_controller_buttons_;
 
   bool is_visible_ = false;
   std::chrono::time_point<std::chrono::system_clock> visibility_button_press_;
@@ -93,6 +100,9 @@ class Application {
   jobject app_context_;
   jobject class_loader_;
 
+  // Controller data provider from shared memory buffer.
+  ControllerDataProvider* controller_data_provider_ = nullptr;
+
   Application(const Application&) = delete;
   void operator=(const Application&) = delete;
 };
index 207d456..08c105c 100644 (file)
@@ -2,46 +2,43 @@ subdirs = [
   "1.0",
 ]
 
-//cc_library_shared {
-//  name: "libvrhwc",
-//
-//  srcs: [
-//    "impl/sync_timeline.cpp",
-//    "impl/vr_composer_view.cpp",
-//    "impl/vr_hwc.cpp",
-//    "impl/vr_composer_client.cpp",
-//  ],
-//
-//  static_libs: [
-//    "libhwcomposer-client",
-//  ],
-//
-//  shared_libs: [
-//    "android.dvr.composer@1.0",
-//    "android.hardware.graphics.composer@2.1",
-//    "libbase",
-//    "libcutils",
-//    "libfmq",
-//    "libhardware",
-//    "libhidlbase",
-//    "libhidltransport",
-//    "liblog",
-//    "libsync",
-//    "libui",
-//    "libutils",
-//  ],
-//
-//  export_include_dirs: ["."],
-//
-//  include_dirs: [
-//    // Access to software sync timeline.
-//    "system/core/libsync",
-//
-//    // Access to internal gralloc implementation.
-//    "hardware/qcom/display/msm8996/libgralloc",
-//  ],
-//
-//  cflags: [
-//    "-DLOG_TAG=\"vrhwc\"",
-//  ],
-//}
+cc_library_shared {
+  name: "libvrhwc",
+
+  srcs: [
+    "impl/sync_timeline.cpp",
+    "impl/vr_composer_view.cpp",
+    "impl/vr_hwc.cpp",
+    "impl/vr_composer_client.cpp",
+  ],
+
+  static_libs: [
+    "libhwcomposer-client",
+  ],
+
+  shared_libs: [
+    "android.dvr.composer@1.0",
+    "android.hardware.graphics.composer@2.1",
+    "libbase",
+    "libcutils",
+    "libfmq",
+    "libhardware",
+    "libhidlbase",
+    "libhidltransport",
+    "liblog",
+    "libsync",
+    "libui",
+    "libutils",
+  ],
+
+  export_include_dirs: ["."],
+
+  include_dirs: [
+    // Access to software sync timeline.
+    "system/core/libsync",
+  ],
+
+  cflags: [
+    "-DLOG_TAG=\"vrhwc\"",
+  ],
+}
index 53c7d8e..d7d0e5b 100644 (file)
@@ -15,7 +15,6 @@
  */
 #include "vr_hwc.h"
 
-#include <gralloc_priv.h>
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/GraphicBufferMapper.h>
@@ -44,13 +43,28 @@ const Display kDefaultDisplayId = 1;
 const Config kDefaultConfigId = 1;
 
 sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) {
-  // TODO(dnicoara): Fix this once gralloc1 is available.
-  private_handle_t* private_handle = private_handle_t::dynamicCast(handle);
+  uint32_t width = 0, height = 0, stride = 0, layer_count = 1;
+  uint64_t producer_usage = 0, consumer_usage = 0;
+  int32_t format = 0;
+
+  GraphicBufferMapper& mapper = GraphicBufferMapper::get();
+  if (mapper.getDimensions(handle, &width, &height) ||
+      mapper.getStride(handle, &stride) ||
+      mapper.getFormat(handle, &format) ||
+      mapper.getProducerUsage(handle, &producer_usage) ||
+      mapper.getConsumerUsage(handle, &consumer_usage)) {
+    ALOGE("Failed to read handle properties");
+    return nullptr;
+  }
+
+  // This will only succeed if gralloc has GRALLOC1_CAPABILITY_LAYERED_BUFFERS
+  // capability. Otherwise assume a count of 1.
+  mapper.getLayerCount(handle, &layer_count);
+
   sp<GraphicBuffer> buffer = new GraphicBuffer(
-      private_handle->width, private_handle->height, private_handle->format, 1,
-      GraphicBuffer::USAGE_HW_COMPOSER | GraphicBuffer::USAGE_HW_TEXTURE,
-      private_handle->width, native_handle_clone(handle), true);
-  if (GraphicBufferMapper::get().registerBuffer(buffer.get()) != OK) {
+      width, height, format, layer_count, producer_usage, consumer_usage,
+      stride, native_handle_clone(handle), true);
+  if (mapper.registerBuffer(buffer.get()) != OK) {
     ALOGE("Failed to register buffer");
     return nullptr;
   }
@@ -142,36 +156,53 @@ void HwcDisplay::GetChangedCompositionTypes(
   }
 }
 
-std::vector<ComposerView::ComposerLayer> HwcDisplay::GetFrame() {
-  // Increment the time the fence is signalled every time we get the
-  // presentation frame. This ensures that calling ReleaseFrame() only affects
-  // the current frame.
-  fence_time_++;
-
+Error HwcDisplay::GetFrame(
+    std::vector<ComposerView::ComposerLayer>* out_frames) {
   bool queued_client_target = false;
   std::vector<ComposerView::ComposerLayer> frame;
   for (const auto& layer : layers_) {
     if (layer.composition_type == IComposerClient::Composition::CLIENT) {
-      if (!queued_client_target) {
-        ComposerView::ComposerLayer client_target_layer = {
-            .buffer = buffer_,
-            .fence = fence_.get() ? fence_ : new Fence(-1),
-            .display_frame = {0, 0, static_cast<int32_t>(buffer_->getWidth()),
-              static_cast<int32_t>(buffer_->getHeight())},
-            .crop = {0.0f, 0.0f, static_cast<float>(buffer_->getWidth()),
-              static_cast<float>(buffer_->getHeight())},
-            .blend_mode = IComposerClient::BlendMode::NONE,
-        };
-
-        frame.push_back(client_target_layer);
-        queued_client_target = true;
+      if (queued_client_target)
+        continue;
+
+      if (!buffer_.get()) {
+        ALOGE("Client composition requested but no client target buffer");
+        return Error::BAD_LAYER;
       }
+
+      ComposerView::ComposerLayer client_target_layer = {
+          .buffer = buffer_,
+          .fence = fence_.get() ? fence_ : new Fence(-1),
+          .display_frame = {0, 0, static_cast<int32_t>(buffer_->getWidth()),
+            static_cast<int32_t>(buffer_->getHeight())},
+          .crop = {0.0f, 0.0f, static_cast<float>(buffer_->getWidth()),
+            static_cast<float>(buffer_->getHeight())},
+          .blend_mode = IComposerClient::BlendMode::NONE,
+      };
+
+      frame.push_back(client_target_layer);
+      queued_client_target = true;
     } else {
+      if (!layer.info.buffer.get() || !layer.info.fence.get()) {
+        ALOGE("Layer requested without valid buffer");
+        return Error::BAD_LAYER;
+      }
+
       frame.push_back(layer.info);
     }
   }
 
-  return frame;
+  if (frame.empty()) {
+    ALOGE("Requested frame with no layers");
+    return Error::BAD_LAYER;
+  }
+
+  // Increment the time the fence is signalled every time we get the
+  // presentation frame. This ensures that calling ReleaseFrame() only affects
+  // the current frame.
+  fence_time_++;
+  out_frames->swap(frame);
+  return Error::NONE;
 }
 
 void HwcDisplay::GetReleaseFences(int* present_fence,
@@ -392,7 +423,8 @@ Error VrHwc::setOutputBuffer(Display display, buffer_handle_t buffer,
   base::unique_fd fence(releaseFence);
   if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
 
-  return Error::NONE;
+  ALOGE("Virtual display support not implemented");
+  return Error::UNSUPPORTED;
 }
 
 Error VrHwc::validateDisplay(
@@ -423,7 +455,10 @@ Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence,
   std::vector<ComposerView::ComposerLayer> frame;
   {
     std::lock_guard<std::mutex> guard(mutex_);
-    frame = display_.GetFrame();
+    Error status = display_.GetFrame(&frame);
+    if (status != Error::NONE)
+      return status;
+
     display_.GetReleaseFences(outPresentFence, outLayers, outReleaseFences);
   }
 
index 1de056a..9450097 100644 (file)
@@ -18,7 +18,8 @@
 
 #include <android/hardware/graphics/composer/2.1/IComposer.h>
 #include <ComposerBase.h>
-#include <ui/GraphicBufferMapper.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
 #include <utils/StrongPointer.h>
 
 #include <mutex>
@@ -115,7 +116,7 @@ class HwcDisplay {
       std::vector<Layer>* layer_ids,
       std::vector<IComposerClient::Composition>* composition);
 
-  std::vector<ComposerView::ComposerLayer> GetFrame();
+  Error GetFrame(std::vector<ComposerView::ComposerLayer>* out_frame);
 
   void GetReleaseFences(int* present_fence, std::vector<Layer>* layer_ids,
                         std::vector<int>* fences);
diff --git a/services/vr/vr_window_manager/controller_data_provider.h b/services/vr/vr_window_manager/controller_data_provider.h
new file mode 100644 (file)
index 0000000..bc1450c
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef VR_WINDOW_MANAGER_CONTROLLER_DATA_PROVIDER_H_
+#define VR_WINDOW_MANAGER_CONTROLLER_DATA_PROVIDER_H_
+
+namespace android {
+namespace dvr {
+
+class ControllerDataProvider {
+ public:
+  virtual ~ControllerDataProvider() {}
+  // Returns data pointer or nullptr. If pointer is valid, call to
+  // UnlockControllerData is required.
+  virtual const void* LockControllerData() = 0;
+  virtual void UnlockControllerData() = 0;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // VR_WINDOW_MANAGER_CONTROLLER_DATA_PROVIDER_H_
\ No newline at end of file
index b2edc20..12a76d8 100644 (file)
@@ -1,10 +1,10 @@
 #include "hwc_callback.h"
 
-#include <gralloc_priv.h>
 #include <android-base/unique_fd.h>
 #include <log/log.h>
 #include <private/dvr/native_buffer.h>
 #include <sync/sync.h>
+#include <ui/GraphicBufferMapper.h>
 
 namespace android {
 namespace dvr {
@@ -12,14 +12,28 @@ namespace dvr {
 namespace {
 
 sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) {
-  // TODO(dnicoara): Fix this once gralloc1 is available.
-  private_handle_t* private_handle = private_handle_t::dynamicCast(handle);
+  uint32_t width = 0, height = 0, stride = 0, layer_count = 1;
+  uint64_t producer_usage = 0, consumer_usage = 0;
+  int32_t format = 0;
+
+  GraphicBufferMapper& mapper = GraphicBufferMapper::get();
+  if (mapper.getDimensions(handle, &width, &height) ||
+      mapper.getStride(handle, &stride) ||
+      mapper.getFormat(handle, &format) ||
+      mapper.getProducerUsage(handle, &producer_usage) ||
+      mapper.getConsumerUsage(handle, &consumer_usage)) {
+    ALOGE("Failed to read handle properties");
+    return nullptr;
+  }
+
+  // This will only succeed if gralloc has GRALLOC1_CAPABILITY_LAYERED_BUFFERS
+  // capability. Otherwise assume a count of 1.
+  mapper.getLayerCount(handle, &layer_count);
+
   sp<GraphicBuffer> buffer = new GraphicBuffer(
-      private_handle->width, private_handle->height, private_handle->format, 1,
-      GraphicBuffer::USAGE_HW_COMPOSER | GraphicBuffer::USAGE_HW_TEXTURE |
-      GraphicBuffer::USAGE_HW_2D | GraphicBuffer::USAGE_HW_RENDER,
-      private_handle->width, native_handle_clone(handle), true);
-  if (GraphicBufferMapper::get().registerBuffer(buffer.get()) != OK) {
+      width, height, format, layer_count, producer_usage, consumer_usage,
+      stride, native_handle_clone(handle), true);
+  if (mapper.registerBuffer(buffer.get()) != OK) {
     ALOGE("Failed to register buffer");
     return nullptr;
   }
@@ -79,8 +93,7 @@ Return<void> HwcCallback::onNewFrame(
   }
 
   std::lock_guard<std::mutex> guard(mutex_);
-  if (client_)
-    client_->OnFrame(std::make_unique<Frame>(std::move(hwc_frame)));
+  client_->OnFrame(std::make_unique<Frame>(std::move(hwc_frame)));
 
   return Void();
 }
index 5f777e3..b67a051 100644 (file)
@@ -75,7 +75,6 @@ void RenderThread::RunRenderLoop(
   jobject android_context = env->NewLocalRef(android_context_global_ref_);
 
   int init_result = shell_view_.Initialize(env, android_context, class_loader);
-  init_result += shell_view_.AllocateResources();
   init_result_promise->set_value(init_result);
   if (init_result == 0) {
     while (!quit_)
index ca49db7..29ade64 100644 (file)
@@ -15,6 +15,8 @@ namespace dvr {
 
 namespace {
 
+constexpr float kLayerScaleFactor = 4.0f;
+
 constexpr unsigned int kVRAppLayerCount = 2;
 
 constexpr unsigned int kMaximumPendingFrames = 8;
@@ -105,6 +107,9 @@ mat4 GetScalingMatrix(float width, float height) {
   else
     xscale = ar;
 
+  xscale *= kLayerScaleFactor;
+  yscale *= kLayerScaleFactor;
+
   return mat4(Eigen::Scaling<float>(xscale, yscale, 1.0));
 }
 
@@ -126,7 +131,7 @@ mat4 GetHorizontallyAlignedMatrixFromPose(const Posef& pose) {
   m(3, 0) = 0.0f; m(3, 1) = 0.0f; m(3, 2) = 0.0f; m(3, 3) = 1.0f;
   // clang-format on
 
-  return m;
+  return m * Eigen::AngleAxisf(M_PI * 0.5f, vec3::UnitZ());
 }
 
 // Helper function that applies the crop transform to the texture layer and
@@ -185,25 +190,23 @@ mat4 GetLayerTransform(const TextureLayer& texture_layer, float display_width,
   return layer_transform;
 }
 
-vec3 FromGvrVec3f(const gvr_vec3f& vec3f) {
-  return vec3(vec3f.x, vec3f.y, vec3f.z);
-}
-
-quat FromGvrQuatf(const gvr_quatf& quaternion) {
-  return quat(quaternion.qw, quaternion.qx, quaternion.qy, quaternion.qz);
-}
-
 // Determine if ths frame should be shown or hidden.
-bool CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
-                                        uint32_t vr_app) {
+ViewMode CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
+                                            uint32_t vr_app) {
   auto& layers = frame.layers();
 
   // We assume the first two layers are the VR app.
   if (layers.size() < kVRAppLayerCount)
-    return false;
+    return ViewMode::Hidden;
 
-  if (vr_app != layers[0].appid || layers[0].appid == 0)
-    return false;
+  if (vr_app != layers[0].appid || layers[0].appid == 0 ||
+      layers[1].appid != layers[0].appid) {
+    if (layers[1].appid != layers[0].appid && layers[0].appid) {
+      // This might be a 2D app.
+      return ViewMode::App;
+    }
+    return ViewMode::Hidden;
+  }
 
   // If a non-VR-app, non-skipped layer appears, show.
   size_t index = kVRAppLayerCount;
@@ -219,11 +222,12 @@ bool CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
   // If any non-skipped layers exist now then we show, otherwise hide.
   for (size_t i = index; i < layers.size(); i++) {
     if (!layers[i].should_skip_layer())
-      return true;
+      return ViewMode::VR;
   }
-  return false;
+  return ViewMode::Hidden;
 }
 
+
 }  // namespace
 
 ShellView::ShellView() {
@@ -245,6 +249,10 @@ int ShellView::Initialize(JNIEnv* env, jobject app_context,
   if (!InitializeTouch())
     ALOGE("Failed to initialize virtual touchpad");
 
+  surface_flinger_view_.reset(new SurfaceFlingerView);
+  if (!surface_flinger_view_->Initialize(this))
+    return 1;
+
   return 0;
 }
 
@@ -262,10 +270,6 @@ int ShellView::AllocateResources() {
   if (!program_ || !overlay_program_ || !controller_program_)
     return 1;
 
-  surface_flinger_view_.reset(new SurfaceFlingerView);
-  if (!surface_flinger_view_->Initialize(this))
-    return 1;
-
   reticle_.reset(new Reticle());
   if (!reticle_->Initialize())
     return 1;
@@ -290,43 +294,63 @@ void ShellView::DeallocateResources() {
 }
 
 void ShellView::EnableDebug(bool debug) {
+  ALOGI("EnableDebug(%d)", (int)debug); // XXX TODO delete
   QueueTask(debug ? MainThreadTask::EnableDebugMode
                   : MainThreadTask::DisableDebugMode);
 }
 
 void ShellView::VrMode(bool mode) {
+  ALOGI("VrMode(%d)", (int)mode); // XXX TODO delete
   QueueTask(mode ? MainThreadTask::EnteringVrMode
                  : MainThreadTask::ExitingVrMode);
 }
 
+void ShellView::dumpInternal(String8& result) {
+  result.append("[shell]\n");
+  result.appendFormat("initialized = %s\n", initialized_ ? "true" : "false");
+  result.appendFormat("is_visible = %s\n", is_visible_ ? "true" : "false");
+  result.appendFormat("debug_mode = %s\n\n", debug_mode_ ? "true" : "false");
+}
+
+void ShellView::AdvanceFrame() {
+  if (!pending_frames_.empty()) {
+    // Check if we should advance the frame.
+    auto& frame = pending_frames_.front();
+    if (frame.visibility == ViewMode::Hidden ||
+        frame.frame->Finish() == HwcCallback::FrameStatus::kFinished) {
+      current_frame_ = std::move(frame);
+      pending_frames_.pop_front();
+
+      for(int i = 0; i < skipped_frame_count_ + 1; i++)
+        surface_flinger_view_->ReleaseFrame();
+      skipped_frame_count_ = 0;
+    }
+  }
+}
+
 void ShellView::OnDrawFrame() {
   textures_.clear();
   has_ime_ = false;
 
   {
     std::unique_lock<std::mutex> l(pending_frame_mutex_);
-    if (!pending_frames_.empty()) {
-      // Check if we should advance the frame.
-      auto& frame = pending_frames_.front();
-      if (!frame.visibility ||
-          frame.frame->Finish() == HwcCallback::FrameStatus::kFinished) {
-        current_frame_ = std::move(frame);
-        pending_frames_.pop_front();
-      }
-    }
+    AdvanceFrame();
   }
 
-  if (!debug_mode_ && current_frame_.visibility != is_visible_) {
-    SetVisibility(current_frame_.visibility);
+  bool visible = current_frame_.visibility != ViewMode::Hidden;
+
+  if (!debug_mode_ && visible != is_visible_) {
+    SetVisibility(current_frame_.visibility != ViewMode::Hidden);
   }
 
-  if (!current_frame_.visibility)
+  if (!debug_mode_ && !visible)
     return;
 
   ime_texture_ = TextureLayer();
 
   surface_flinger_view_->GetTextures(*current_frame_.frame.get(), &textures_,
-                                     &ime_texture_, debug_mode_);
+                                     &ime_texture_, debug_mode_,
+                                     current_frame_.visibility == ViewMode::VR);
   has_ime_ = ime_texture_.texture != nullptr;
 }
 
@@ -370,33 +394,40 @@ bool ShellView::OnClick(bool down) {
 }
 
 void ShellView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame) {
-  if (!frame || frame->layers().empty())
-    return;
-
-  bool visibility = debug_mode_ || CalculateVisibilityFromLayerConfig(
-                                       *frame.get(), current_vr_app_);
-  current_vr_app_ = frame->layers().front().appid;
+  ViewMode visibility =
+      CalculateVisibilityFromLayerConfig(*frame.get(), current_vr_app_);
 
-  // If we are not showing the frame there's no need to keep anything around.
-  if (!visibility) {
-    // Hidden, no change so drop it completely
-    if (!current_frame_.visibility)
-      return;
+  if (visibility == ViewMode::Hidden && debug_mode_)
+    visibility = ViewMode::VR;
 
-    frame.reset(nullptr);
-  }
+  if (frame->layers().empty())
+    current_vr_app_ = 0;
+  else
+    current_vr_app_ = frame->layers().front().appid;
 
   std::unique_lock<std::mutex> l(pending_frame_mutex_);
 
   pending_frames_.emplace_back(std::move(frame), visibility);
 
-  if (pending_frames_.size() > kMaximumPendingFrames)
+  if (pending_frames_.size() > kMaximumPendingFrames) {
+    skipped_frame_count_++;
     pending_frames_.pop_front();
+  }
+
+  if (visibility == ViewMode::Hidden &&
+      current_frame_.visibility == ViewMode::Hidden) {
+    // Consume all frames while hidden.
+    while (!pending_frames_.empty())
+      AdvanceFrame();
+  }
 
   // If we are showing ourselves the main thread is not processing anything,
   // so give it a kick.
-  if (visibility && !current_frame_.visibility)
+  if (visibility != ViewMode::Hidden &&
+      current_frame_.visibility == ViewMode::Hidden) {
+    QueueTask(MainThreadTask::EnteringVrMode);
     QueueTask(MainThreadTask::Show);
+  }
 }
 
 bool ShellView::IsHit(const vec3& view_location, const vec3& view_direction,
@@ -573,23 +604,50 @@ void ShellView::DrawReticle(const mat4& perspective, const mat4& eye_matrix,
   vec3 pointer_location = last_pose_.GetPosition();
   quat view_quaternion = last_pose_.GetRotation();
 
-  if (controller_ && controller_api_status_ == gvr::kControllerApiOk) {
-    view_quaternion = FromGvrQuatf(controller_orientation_);
+  bool gvr_api_active =
+      controller_ && controller_api_status_ == gvr::kControllerApiOk;
+
+  if (gvr_api_active || shmem_controller_active_) {
+    view_quaternion = controller_orientation_;
     vec4 controller_location = controller_translate_ * vec4(0, 0, 0, 1);
     pointer_location = vec3(controller_location.x(), controller_location.y(),
                             controller_location.z());
 
-    if (controller_state_->GetButtonDown(gvr::kControllerButtonClick))
-      OnClick(true);
+    if (shmem_controller_active_) {
+      uint64_t buttons = shmem_controller_buttons_;
+      shmem_controller_buttons_ = 0;
+      while (buttons) {
+        switch (buttons & 0xF) {
+          case 0x1:
+            OnClick(false);
+            break;
+          case 0x3:
+            OnTouchpadButton(false, AMOTION_EVENT_BUTTON_BACK);
+            break;
+          case 0x9:
+            OnClick(true);
+            break;
+          case 0xB:
+            OnTouchpadButton(true, AMOTION_EVENT_BUTTON_BACK);
+            break;
+          default:
+            break;
+        }
+        buttons >>= 4;
+      }
+    } else if (controller_) {
+      if (controller_state_->GetButtonDown(gvr::kControllerButtonClick))
+        OnClick(true);
 
-    if (controller_state_->GetButtonUp(gvr::kControllerButtonClick))
-      OnClick(false);
+      if (controller_state_->GetButtonUp(gvr::kControllerButtonClick))
+        OnClick(false);
 
-    if (controller_state_->GetButtonDown(gvr::kControllerButtonApp))
-      OnTouchpadButton(true, AMOTION_EVENT_BUTTON_BACK);
+      if (controller_state_->GetButtonDown(gvr::kControllerButtonApp))
+        OnTouchpadButton(true, AMOTION_EVENT_BUTTON_BACK);
 
-    if (controller_state_->GetButtonUp(gvr::kControllerButtonApp))
-      OnTouchpadButton(false, AMOTION_EVENT_BUTTON_BACK);
+      if (controller_state_->GetButtonUp(gvr::kControllerButtonApp))
+        OnTouchpadButton(false, AMOTION_EVENT_BUTTON_BACK);
+    }
   }
 
   vec3 view_direction = vec3(view_quaternion * vec3(0, 0, -1));
@@ -618,7 +676,7 @@ void ShellView::DrawReticle(const mat4& perspective, const mat4& eye_matrix,
 
 void ShellView::DrawController(const mat4& perspective, const mat4& eye_matrix,
                                const mat4& head_matrix) {
-  if (!controller_)
+  if (!controller_ && !shmem_controller_active_)
     return;
 
   controller_program_->Use();
@@ -628,7 +686,7 @@ void ShellView::DrawController(const mat4& perspective, const mat4& eye_matrix,
       controller_program_->GetProgram(), "uViewProjection");
   glUniformMatrix4fv(view_projection_location, 1, 0, mvp.data());
 
-  quat view_quaternion = FromGvrQuatf(controller_orientation_);
+  quat view_quaternion = controller_orientation_;
   view_quaternion.toRotationMatrix();
 
   vec3 world_pos = last_pose_.GetPosition() + controller_position_;
index 589902e..14ad0f3 100644 (file)
@@ -9,12 +9,21 @@
 
 #include "application.h"
 #include "reticle.h"
+#include "shell_view_binder_interface.h"
 #include "surface_flinger_view.h"
 
 namespace android {
 namespace dvr {
 
-class ShellView : public Application, public HwcCallback::Client {
+enum class ViewMode {
+  Hidden,
+  VR,
+  App,
+};
+
+class ShellView : public Application,
+                  public android::dvr::ShellViewBinderInterface,
+                  public HwcCallback::Client {
  public:
   ShellView();
   virtual ~ShellView();
@@ -25,8 +34,10 @@ class ShellView : public Application, public HwcCallback::Client {
   int AllocateResources() override;
   void DeallocateResources() override;
 
-  void EnableDebug(bool debug);
-  void VrMode(bool mode);
+  // ShellViewBinderInterface:
+  void EnableDebug(bool debug) override;
+  void VrMode(bool mode) override;
+  void dumpInternal(String8& result) override;
 
  protected:
   void DrawEye(EyeType eye, const mat4& perspective, const mat4& eye_matrix,
@@ -57,6 +68,8 @@ class ShellView : public Application, public HwcCallback::Client {
 
   bool OnClick(bool down);
 
+  void AdvanceFrame();
+
   // HwcCallback::Client:
   void OnFrame(std::unique_ptr<HwcCallback::Frame> frame) override;
 
@@ -64,6 +77,9 @@ class ShellView : public Application, public HwcCallback::Client {
   std::unique_ptr<ShaderProgram> overlay_program_;
   std::unique_ptr<ShaderProgram> controller_program_;
 
+  // This starts at -1 so we don't call ReleaseFrame for the first frame.
+  int skipped_frame_count_ = -1;
+
   uint32_t current_vr_app_;
 
   // Used to center the scene when the shell becomes visible.
@@ -92,7 +108,7 @@ class ShellView : public Application, public HwcCallback::Client {
 
   struct PendingFrame {
     PendingFrame() = default;
-    PendingFrame(std::unique_ptr<HwcCallback::Frame>&& frame, bool visibility)
+    PendingFrame(std::unique_ptr<HwcCallback::Frame>&& frame, ViewMode visibility)
         : frame(std::move(frame)), visibility(visibility) {}
     PendingFrame(PendingFrame&& r)
         : frame(std::move(r.frame)), visibility(r.visibility) {}
@@ -103,7 +119,7 @@ class ShellView : public Application, public HwcCallback::Client {
     }
 
     std::unique_ptr<HwcCallback::Frame> frame;
-    bool visibility = false;
+    ViewMode visibility = ViewMode::Hidden;
   };
   std::deque<PendingFrame> pending_frames_;
   std::mutex pending_frame_mutex_;
diff --git a/services/vr/vr_window_manager/shell_view_binder_interface.h b/services/vr/vr_window_manager/shell_view_binder_interface.h
new file mode 100644 (file)
index 0000000..b58e4bd
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef VR_WINDOW_MANAGER_SHELL_VIEWBINDER_INTERFACE_H_
+#define VR_WINDOW_MANAGER_SHELL_VIEWBINDER_INTERFACE_H_
+
+namespace android {
+namespace dvr {
+
+class ShellViewBinderInterface {
+ public:
+  ShellViewBinderInterface() {};
+  virtual ~ShellViewBinderInterface() {};
+
+  virtual void EnableDebug(bool debug) = 0;
+  virtual void VrMode(bool mode) = 0;
+  virtual void dumpInternal(String8& result) = 0;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // VR_WINDOW_MANAGER_SHELL_VIEWBINDER_INTERFACE_H_
index d38fcc0..b15d262 100644 (file)
@@ -38,13 +38,13 @@ bool SurfaceFlingerView::Initialize(HwcCallback::Client *client) {
 bool SurfaceFlingerView::GetTextures(const HwcCallback::Frame& frame,
                                      std::vector<TextureLayer>* texture_layers,
                                      TextureLayer* ime_layer,
-                                     bool debug) const {
+                                     bool debug, bool skip_first_layer) const {
   auto& layers = frame.layers();
   texture_layers->clear();
 
   size_t start = 0;
   // Skip the second layer if it is from the VR app.
-  if (!debug) {
+  if (!debug && skip_first_layer) {
     start = 1;
     if (layers[0].appid && layers[0].appid == layers[1].appid)
       start = 2;
@@ -75,5 +75,9 @@ bool SurfaceFlingerView::GetTextures(const HwcCallback::Frame& frame,
   return true;
 }
 
+void SurfaceFlingerView::ReleaseFrame() {
+  composer_service_->releaseFrame();
+}
+
 }  // namespace dvr
 }  // namespace android
index e079cdb..2e36ec1 100644 (file)
@@ -33,7 +33,10 @@ class SurfaceFlingerView {
 
   bool GetTextures(const HwcCallback::Frame& layers,
                    std::vector<TextureLayer>* texture_layers,
-                   TextureLayer* ime_layer, bool debug) const;
+                   TextureLayer* ime_layer, bool debug,
+                   bool skip_first_layer) const;
+
+  void ReleaseFrame();
 
  private:
   sp<IVrComposerView> composer_service_;
index 736a14f..c51ddee 100644 (file)
@@ -1,23 +1,33 @@
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 
 #include "shell_view.h"
+#include "vr_window_manager_binder.h"
 
 int main(int /* argc */, char** /* argv */) {
+  android::dvr::ShellView app;
+  const int app_status = app.Initialize(nullptr, nullptr, nullptr);
+  LOG_ALWAYS_FATAL_IF(app_status != 0, "failed to initialize: %d", app_status);
+
+  android::service::vr::VrWindowManagerBinder service(app);
+  const int status = service.Initialize();
+  LOG_ALWAYS_FATAL_IF(status != 0, "initialization failed: %d", status);
+
   android::ProcessState::self()->startThreadPool();
 
-  android::dvr::ShellView app;
-  if (app.Initialize(nullptr, nullptr, nullptr)) {
-    ALOGE("Failed to initialize");
-    return 1;
-  }
+  android::sp<android::IServiceManager> sm(android::defaultServiceManager());
+  const android::status_t service_status = sm->addService(
+      android::service::vr::VrWindowManagerBinder::SERVICE_NAME(), &service,
+      false /*allowIsolated*/);
+  LOG_ALWAYS_FATAL_IF(service_status != android::OK, "service not added: %d",
+                      static_cast<int>(service_status));
 
-  if (app.AllocateResources()) {
-    ALOGE("Failed to allocate resources");
-    return 1;
-  }
+  app.SetControllerDataProvider(&service);
 
   while (true)
     app.DrawFrame();
 
+  android::IPCThreadState::self()->joinThreadPool();
   return 0;
 }
diff --git a/services/vr/vr_window_manager/vr_window_manager_binder.cpp b/services/vr/vr_window_manager/vr_window_manager_binder.cpp
new file mode 100644 (file)
index 0000000..c2138b7
--- /dev/null
@@ -0,0 +1,156 @@
+#include "vr_window_manager_binder.h"
+
+#include <inttypes.h>
+#include <sys/mman.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
+#include <binder/Status.h>
+#include <cutils/log.h>
+#include <private/android_filesystem_config.h>
+#include <utils/Errors.h>
+
+namespace android {
+namespace service {
+namespace vr {
+
+namespace {
+const String16 kDumpPermission("android.permission.DUMP");
+const String16 kSendMeControllerInputPermission("TODO");  // TODO(kpschoedel)
+}  // anonymous namespace
+
+constexpr size_t AshmemControllerDataProvider::kRegionLength;
+
+status_t AshmemControllerDataProvider::Connect(const int in_fd) {
+  if (in_fd < 0) {
+    return BAD_VALUE;
+  }
+  if (fd_.get() >= 0) {
+    // The VrCore is dead. Long live the VrCore.
+    Disconnect();
+  }
+  void* const shared_region =
+      ::mmap(nullptr, kRegionLength, PROT_READ, MAP_SHARED, in_fd, 0);
+  if (shared_region == MAP_FAILED) {
+    shared_region_ = nullptr;
+    return NO_MEMORY;
+  }
+
+  errno = 0;
+  const int fd = ::fcntl(in_fd, F_DUPFD_CLOEXEC, 0);
+  if (fd < 0) {
+    ::munmap(shared_region, kRegionLength);
+    return -errno;
+  }
+  fd_.reset(fd);
+  ALOGI("controller connected %d -> %d @ %p", in_fd, fd, shared_region);
+
+  std::lock_guard<std::mutex> guard(mutex_);
+  shared_region_ = shared_region;
+  return OK;
+}
+
+status_t AshmemControllerDataProvider::Disconnect() {
+  if (shared_region_ == nullptr || fd_.get() < 0) {
+    return INVALID_OPERATION;
+  }
+  std::lock_guard<std::mutex> guard(mutex_);
+  ::munmap(shared_region_, kRegionLength);
+  shared_region_ = nullptr;
+  fd_.reset();
+  ALOGI("controller disconnected");
+  return OK;
+}
+
+const void* AshmemControllerDataProvider::LockControllerData() {
+  mutex_.lock();
+  if (!shared_region_) {
+    mutex_.unlock();
+    return nullptr;
+  }
+  return shared_region_;
+}
+
+void AshmemControllerDataProvider::UnlockControllerData() { mutex_.unlock(); }
+
+void AshmemControllerDataProvider::dumpInternal(String8& result) {
+  result.appendFormat("[controller]\nfd = %d\n", fd_.get());
+  if (shared_region_) {
+    int32_t* p = reinterpret_cast<int32_t*>(shared_region_);
+    result.appendFormat("header = ");
+    for (int i = 0; i < 8; ++i) {
+      result.appendFormat("%c 0x%08" PRIX32, i ? ',' : '[', p[i]);
+    }
+    result.appendFormat(" ]\n\n");
+  }
+}
+
+int VrWindowManagerBinder::Initialize() { return 0; }
+
+binder::Status VrWindowManagerBinder::connectController(
+    const ::android::base::unique_fd& in_fd) {
+  // TODO(kpschoedel): check permission
+#if 0
+  int32_t pid, uid;
+  if (!PermissionCache::checkCallingPermission(kSendMeControllerInputPermission,
+                                               &pid, &uid)) {
+    ALOGE("permission denied to pid=%" PRId32 " uid=%" PRId32, pid, uid);
+    return binder::Status::fromStatusT(PERMISSION_DENIED);
+  }
+#endif
+  return binder::Status::fromStatusT(Connect(in_fd.get()));
+}
+
+binder::Status VrWindowManagerBinder::disconnectController() {
+  // TODO(kpschoedel): check permission
+#if 0
+  int32_t pid, uid;
+  if (!PermissionCache::checkCallingPermission(kSendMeControllerInputPermission,
+                                               &pid, &uid)) {
+    ALOGE("permission denied to pid=%" PRId32 " uid=%" PRId32, pid, uid);
+    return binder::Status::fromStatusT(PERMISSION_DENIED);
+  }
+#endif
+  return binder::Status::fromStatusT(Disconnect());
+}
+
+binder::Status VrWindowManagerBinder::enterVrMode() {
+  // TODO(kpschoedel): check permission
+  app_.VrMode(true);
+  return binder::Status::ok();
+}
+
+binder::Status VrWindowManagerBinder::exitVrMode() {
+  // TODO(kpschoedel): check permission
+  app_.VrMode(false);
+  return binder::Status::ok();
+}
+
+binder::Status VrWindowManagerBinder::setDebugMode(int32_t mode) {
+  // TODO(kpschoedel): check permission
+  app_.EnableDebug(static_cast<bool>(mode));
+  return binder::Status::ok();
+}
+
+status_t VrWindowManagerBinder::dump(
+    int fd, const Vector<String16>& args [[gnu::unused]]) {
+  String8 result;
+  const android::IPCThreadState* ipc = android::IPCThreadState::self();
+  const int pid = ipc->getCallingPid();
+  const int uid = ipc->getCallingUid();
+  if ((uid != AID_SHELL) &&
+      !PermissionCache::checkPermission(kDumpPermission, pid, uid)) {
+    result.appendFormat("Permission denial: can't dump " LOG_TAG
+                        " from pid=%d, uid=%d\n",
+                        pid, uid);
+  } else {
+    app_.dumpInternal(result);
+    AshmemControllerDataProvider::dumpInternal(result);
+  }
+  write(fd, result.string(), result.size());
+  return OK;
+}
+
+}  // namespace vr
+}  // namespace service
+}  // namespace android
diff --git a/services/vr/vr_window_manager/vr_window_manager_binder.h b/services/vr/vr_window_manager/vr_window_manager_binder.h
new file mode 100644 (file)
index 0000000..99ca27a
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef VR_WINDOW_MANAGER_VR_WINDOW_MANAGER_BINDER_H_
+#define VR_WINDOW_MANAGER_VR_WINDOW_MANAGER_BINDER_H_
+
+#include <android/service/vr/BnVrWindowManager.h>
+
+#include <mutex>
+
+#include "controller_data_provider.h"
+#include "shell_view_binder_interface.h"
+
+namespace android {
+namespace service {
+namespace vr {
+
+class AshmemControllerDataProvider : public dvr::ControllerDataProvider {
+ public:
+  AshmemControllerDataProvider() {}
+  virtual ~AshmemControllerDataProvider() {}
+
+  status_t Connect(int fd);
+  status_t Disconnect();
+
+  // ControllerDataProvider:
+  const void* LockControllerData() override;
+  void UnlockControllerData() override;
+
+ protected:
+  void dumpInternal(String8& result);
+
+ private:
+  static constexpr size_t kRegionLength = 8192;  // TODO(kpschoedel)
+  ::android::base::unique_fd fd_;
+
+  // Mutex for guarding shared_region_.
+  std::mutex mutex_;
+  void* shared_region_ = nullptr;
+
+  AshmemControllerDataProvider(const AshmemControllerDataProvider&) = delete;
+  void operator=(const AshmemControllerDataProvider&) = delete;
+};
+
+class VrWindowManagerBinder : public BnVrWindowManager,
+                              public AshmemControllerDataProvider {
+ public:
+  VrWindowManagerBinder(android::dvr::ShellViewBinderInterface& app)
+      : app_(app) {}
+  virtual ~VrWindowManagerBinder() {}
+
+  // Must be called before clients can connect.
+  // Returns 0 if initialization is successful.
+  int Initialize();
+  static char const* getServiceName() { return "vr_window_manager"; }
+
+ protected:
+  // Implements IVrWindowManagerBinder.
+  ::android::binder::Status connectController(
+      const ::android::base::unique_fd& fd) override;
+  ::android::binder::Status disconnectController() override;
+  ::android::binder::Status enterVrMode() override;
+  ::android::binder::Status exitVrMode() override;
+  ::android::binder::Status setDebugMode(int32_t mode) override;
+
+  // Implements BBinder::dump().
+  status_t dump(int fd, const Vector<String16>& args) override;
+
+ private:
+  android::dvr::ShellViewBinderInterface& app_;
+
+  VrWindowManagerBinder(const VrWindowManagerBinder&) = delete;
+  void operator=(const VrWindowManagerBinder&) = delete;
+};
+
+}  // namespace vr
+}  // namespace service
+}  // namespace android
+
+#endif  // VR_WINDOW_MANAGER_VR_WINDOW_MANAGER_BINDER_H_
diff --git a/services/vr/vr_window_manager/vr_window_manager_binder_test.cpp b/services/vr/vr_window_manager/vr_window_manager_binder_test.cpp
new file mode 100644 (file)
index 0000000..f43e803
--- /dev/null
@@ -0,0 +1,29 @@
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cutils/log.h>
+
+#include "vr_window_manager_binder.h"
+
+int main() {
+  ALOGI("Starting");
+  android::service::vr::VrWindowManagerBinder service;
+  const int status = service.Initialize();
+  LOG_ALWAYS_FATAL_IF(status != 0, "initialization failed: %d", status);
+
+  signal(SIGPIPE, SIG_IGN);
+  android::sp<android::ProcessState> ps(android::ProcessState::self());
+  ps->setThreadPoolMaxThreadCount(4);
+  ps->startThreadPool();
+  ps->giveThreadPoolName();
+
+  android::sp<android::IServiceManager> sm(android::defaultServiceManager());
+  const android::status_t service_status = sm->addService(
+      android::service::vr::VrWindowManagerBinder::SERVICE_NAME(), &service,
+      false /*allowIsolated*/);
+  LOG_ALWAYS_FATAL_IF(service_status != android::OK, "service not added: %d",
+                      static_cast<int>(service_status));
+
+  android::IPCThreadState::self()->joinThreadPool();
+  return 0;
+}
diff --git a/services/vr/vr_window_manager/vr_wm_ctl.cpp b/services/vr/vr_window_manager/vr_wm_ctl.cpp
new file mode 100644 (file)
index 0000000..c67b2eb
--- /dev/null
@@ -0,0 +1,48 @@
+#include <android/service/vr/BpVrWindowManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <inttypes.h>
+
+void usage() { fprintf(stderr, "usage: vr_wm_ctl [enter|exit|debug N]\n"); }
+
+int report(const android::binder::Status& status) {
+  if (status.isOk()) {
+    fprintf(stderr, "ok\n");
+    return 0;
+  }
+  fprintf(stderr, "failed (%" PRId32 ") %s\n", status.exceptionCode(),
+          status.exceptionMessage().string());
+  return (int)status.exceptionCode();
+}
+
+int main(int argc, char* argv[]) {
+  android::sp<android::IServiceManager> sm(android::defaultServiceManager());
+  if (sm == nullptr) {
+    fprintf(stderr, "service manager not found\n");
+    exit(1);
+  }
+
+  android::sp<android::service::vr::IVrWindowManager> vrwm =
+      android::interface_cast<android::service::vr::IVrWindowManager>(
+          sm->getService(
+              android::service::vr::IVrWindowManager::SERVICE_NAME()));
+  if (vrwm == nullptr) {
+    fprintf(stderr, "service not found\n");
+    exit(1);
+  }
+
+  android::binder::Status status;
+  if ((argc == 2) && (strcmp(argv[1], "enter") == 0)) {
+    exit(report(vrwm->enterVrMode()));
+  } else if ((argc == 2) && (strcmp(argv[1], "exit") == 0)) {
+    exit(report(vrwm->exitVrMode()));
+  } else if ((argc == 3) && (strcmp(argv[1], "debug") == 0)) {
+    exit(report(vrwm->setDebugMode(atoi(argv[2]))));
+  } else {
+    usage();
+    exit(2);
+  }
+
+  return 0;
+}
index 5a67d36..a89fed9 100644 (file)
@@ -2908,14 +2908,20 @@ class VkWin32SurfaceCreateInfoKHR {
     platform.HWND                               hwnd
 }
 
+@internal class Gralloc1Usage {
+    u64                                         consumer
+    u64                                         producer
+}
+
 @extension("VK_ANDROID_native_buffer")
 class VkNativeBufferANDROID {
     VkStructureType                             sType
     const void*                                 pNext
     platform.buffer_handle_t                    handle
-    int                                         stride
-    int                                         format
-    int                                         usage
+    s32                                         stride
+    s32                                         format
+    s32                                         usage
+    Gralloc1Usage                               usage2
 }
 
 @extension("VK_ANDROID_native_buffer")
@@ -5833,21 +5839,24 @@ cmd VkResult vkGetPhysicalDeviceWin32PresentationSupportKHR(
 }
 
 @extension("VK_ANDROID_native_buffer")
+@optional
 cmd VkResult vkGetSwapchainGrallocUsageANDROID(
         VkDevice                                device,
         VkFormat                                format,
         VkImageUsageFlags                       imageUsage,
-        int*                                    grallocUsage) {
+        s32*                                    grallocUsage) {
     return ?
 }
 
 @extension("VK_ANDROID_native_buffer")
+@optional
 cmd VkResult vkGetSwapchainGrallocUsage2ANDROID(
         VkDevice                                device,
         VkFormat                                format,
         VkImageUsageFlags                       imageUsage,
         VkSwapchainImageUsageFlagsANDROID       swapchainImageUsage,
-        int*                                    grallocUsage) {
+        u64*                                    grallocConsumerUsage,
+        u64*                                    grallocProducerUsage) {
     return ?
 }
 
index 009472a..24af950 100644 (file)
@@ -47,19 +47,7 @@ Our goal is to allow layers to be ported with only build-environment changes bet
 
 The +vk_wsi_swapchin+ and +vk_wsi_device_swapchain+ extensions are primarily be implemented by the platform and live in +libvulkan.so+. The +VkSwapchain+ object and all interaction with +ANativeWindow+ will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver's +vkGetDeviceProcAddr+ functions, after passing through any enabled layers.
 
-Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling
-[source,c]
-----
-VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
-    VkDevice            device,
-    VkFormat            format,
-    VkImageUsageFlags   imageUsage,
-    int*                grallocUsage
-);
-----
-The +format+ and +imageUsage+ parameters are taken from the +VkSwapchainCreateInfoKHR+ structure. The driver should fill +*grallocUsage+ with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.
-
-Implementations may further need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on +format+ and +imageUsage+, but also on the intended usage of the swapchain. The additional usage bits are defined as
+Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on +format+ and +imageUsage+, but also on the intended usage of the swapchain. The swapchain usage bits are defined as
 [source,c]
 ----
 typedef enum VkSwapchainImageUsageFlagBitsANDROID {
@@ -69,7 +57,7 @@ typedef enum VkSwapchainImageUsageFlagBitsANDROID {
 typedef VkFlags VkSwapchainImageUsageFlagsANDROID;
 ----
 
-If the driver provides the +vkGetSwapchainGrallocUsage2ANDROID+ function, the platform will use it in preference to +vkGetSwapchainGrallocUsageANDROID+ when translating a requested format, image usage flags, and swapchain image usage flags into gralloc usage flags. +vkGetSwapchainGrallocUsage2ANDROID+ behaves in the same way as +vkGetSwapchainGrallocUsageANDROID+, and is declared as
+Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling
 [source,c]
 ----
 VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
@@ -77,6 +65,19 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
     VkFormat            format,
     VkImageUsageFlags   imageUsage,
     VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
+    uint64_t*           grallocConsumerUsage,
+    uint64_t*           grallocProducerUsage,
+);
+----
+The +format+ and +imageUsage+ parameters are taken from the +VkSwapchainCreateInfoKHR+ structure. The driver should fill +*grallocConsumerUsage+ and +*grallocProducerUsage+ with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.
+
+An older version of this function is deprecated but still supported for backwards compatibility; it will be used if +vkGetSwapchainGrallocUsage2ANDROID+ is not supported:
+[source,c]
+----
+VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
+    VkDevice            device,
+    VkFormat            format,
+    VkImageUsageFlags   imageUsage,
     int*                grallocUsage
 );
 ----
@@ -95,7 +96,11 @@ typedef struct {
 
     // Gralloc format and usage requested when the buffer was allocated.
     int                         format;
-    int                         usage;
+    int                         usage; // deprecated
+    struct {
+        uint64_t                consumer;
+        uint64_t                producer;
+    } usage2;
 } VkNativeBufferANDROID;
 ----
 
@@ -200,3 +205,5 @@ If +image+ was created with +VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID+, then
    * Added VkSwapchainImageUsageFlagBitsANDROID
    * Added vkGetSwapchainGrallocUsage2ANDROID
    * Added VkSwapchainImageCreateInfoANDROID
+. *2017-02-09*
+   * Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
\ No newline at end of file
index 4e74a78..9fecce5 100644 (file)
@@ -730,7 +730,7 @@ asciidoc.install(2);
 /*]]>*/
 </script>
 </head>
-<body class="article">
+<body class="book">
 <div id="header">
 <h1>Vulkan on Android Implementor&#8217;s Guide</h1>
 <span id="revnumber">version 5</span>
@@ -793,20 +793,7 @@ Injected layers, like framerate, social network, or game launcher overlays, whic
 <h2 id="_window_system_integration">2. Window System Integration</h2>
 <div class="sectionbody">
 <div class="paragraph"><p>The <span class="monospaced">vk_wsi_swapchin</span> and <span class="monospaced">vk_wsi_device_swapchain</span> extensions are primarily be implemented by the platform and live in <span class="monospaced">libvulkan.so</span>. The <span class="monospaced">VkSwapchain</span> object and all interaction with <span class="monospaced">ANativeWindow</span> will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver&#8217;s <span class="monospaced">vkGetDeviceProcAddr</span> functions, after passing through any enabled layers.</p></div>
-<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsageANDROID</span></span><span style="color: #990000">(</span>
-    <span style="color: #008080">VkDevice</span>            device<span style="color: #990000">,</span>
-    <span style="color: #008080">VkFormat</span>            format<span style="color: #990000">,</span>
-    <span style="color: #008080">VkImageUsageFlags</span>   imageUsage<span style="color: #990000">,</span>
-    <span style="color: #009900">int</span><span style="color: #990000">*</span>                grallocUsage
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>The <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span> parameters are taken from the <span class="monospaced">VkSwapchainCreateInfoKHR</span> structure. The driver should fill <span class="monospaced">*grallocUsage</span> with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.</p></div>
-<div class="paragraph"><p>Implementations may further need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span>, but also on the intended usage of the swapchain. The additional usage bits are defined as</p></div>
+<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span>, but also on the intended usage of the swapchain. The swapchain usage bits are defined as</p></div>
 <div class="listingblock">
 <div class="content"><!-- Generator: GNU source-highlight 3.1.6
 by Lorenzo Bettini
@@ -817,7 +804,7 @@ http://www.gnu.org/software/src-highlite -->
     VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM <span style="color: #990000">=</span> <span style="color: #993399">0x7FFFFFFF</span>
 <span style="color: #FF0000">}</span> VkSwapchainImageUsageFlagBitsANDROID<span style="color: #990000">;</span>
 <span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="color: #008080">VkFlags</span> VkSwapchainImageUsageFlagsANDROID<span style="color: #990000">;</span></tt></pre></div></div>
-<div class="paragraph"><p>If the driver provides the <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> function, the platform will use it in preference to <span class="monospaced">vkGetSwapchainGrallocUsageANDROID</span> when translating a requested format, image usage flags, and swapchain image usage flags into gralloc usage flags. <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> behaves in the same way as <span class="monospaced">vkGetSwapchainGrallocUsageANDROID</span>, and is declared as</p></div>
+<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling</p></div>
 <div class="listingblock">
 <div class="content"><!-- Generator: GNU source-highlight 3.1.6
 by Lorenzo Bettini
@@ -828,6 +815,20 @@ http://www.gnu.org/software/src-highlite -->
     <span style="color: #008080">VkFormat</span>            format<span style="color: #990000">,</span>
     <span style="color: #008080">VkImageUsageFlags</span>   imageUsage<span style="color: #990000">,</span>
     <span style="color: #008080">VkSwapchainImageUsageFlagsANDROID</span> swapchainImageUsage<span style="color: #990000">,</span>
+    uint64_t<span style="color: #990000">*</span>           grallocConsumerUsage<span style="color: #990000">,</span>
+    uint64_t<span style="color: #990000">*</span>           grallocProducerUsage<span style="color: #990000">,</span>
+<span style="color: #990000">);</span></tt></pre></div></div>
+<div class="paragraph"><p>The <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span> parameters are taken from the <span class="monospaced">VkSwapchainCreateInfoKHR</span> structure. The driver should fill <span class="monospaced">*grallocConsumerUsage</span> and <span class="monospaced">*grallocProducerUsage</span> with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.</p></div>
+<div class="paragraph"><p>An older version of this function is deprecated but still supported for backwards compatibility; it will be used if <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> is not supported:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 3.1.6
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsageANDROID</span></span><span style="color: #990000">(</span>
+    <span style="color: #008080">VkDevice</span>            device<span style="color: #990000">,</span>
+    <span style="color: #008080">VkFormat</span>            format<span style="color: #990000">,</span>
+    <span style="color: #008080">VkImageUsageFlags</span>   imageUsage<span style="color: #990000">,</span>
     <span style="color: #009900">int</span><span style="color: #990000">*</span>                grallocUsage
 <span style="color: #990000">);</span></tt></pre></div></div>
 <div class="paragraph"><p><span class="monospaced">VkNativeBufferANDROID</span> is a <span class="monospaced">vkCreateImage</span> extension structure for creating an image backed by a gralloc buffer. This structure is provided to <span class="monospaced">vkCreateImage</span> in the <span class="monospaced">VkImageCreateInfo</span> structure chain. Calls to <span class="monospaced">vkCreateImage</span> with this structure will happen during the first call to <span class="monospaced">vkGetSwapChainInfoWSI(.. VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)</span>. The WSI implementation will allocate the number of native buffers requested for the swapchain, then create a <span class="monospaced">VkImage</span> for each one.</p></div>
@@ -846,7 +847,11 @@ http://www.gnu.org/software/src-highlite -->
 
     <span style="font-style: italic"><span style="color: #9A1900">// Gralloc format and usage requested when the buffer was allocated.</span></span>
     <span style="color: #009900">int</span>                         format<span style="color: #990000">;</span>
-    <span style="color: #009900">int</span>                         usage<span style="color: #990000">;</span>
+    <span style="color: #009900">int</span>                         usage<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// deprecated</span></span>
+    <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span>
+        <span style="color: #008080">uint64_t</span>                consumer<span style="color: #990000">;</span>
+        <span style="color: #008080">uint64_t</span>                producer<span style="color: #990000">;</span>
+    <span style="color: #FF0000">}</span> usage2<span style="color: #990000">;</span>
 <span style="color: #FF0000">}</span> VkNativeBufferANDROID<span style="color: #990000">;</span></tt></pre></div></div>
 <div class="paragraph"><p>When creating a gralloc-backed image, the <span class="monospaced">VkImageCreateInfo</span> will have:</p></div>
 <div class="listingblock">
@@ -1044,6 +1049,18 @@ Added VkSwapchainImageCreateInfoANDROID
 </li>
 </ul></div>
 </li>
+<li>
+<p>
+<strong>2017-02-09</strong>
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
+</p>
+</li>
+</ul></div>
+</li>
 </ol></div>
 </div>
 </div>
@@ -1052,7 +1069,7 @@ Added VkSwapchainImageCreateInfoANDROID
 <div id="footer">
 <div id="footer-text">
 Version 5<br>
-Last updated 2017-01-12 14:25:30 NZDT
+Last updated 2017-02-09 22:40:30 PST
 </div>
 </div>
 </body>
index db23e79..d7c5a07 100644 (file)
@@ -27,6 +27,16 @@ extern "C" {
 #define VK_ANDROID_native_buffer 1
 
 #define VK_ANDROID_NATIVE_BUFFER_EXTENSION_NUMBER 11
+/* NOTE ON VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 6
+ *
+ * This version of the extension transitions from gralloc0 to gralloc1 usage
+ * flags (int -> 2x uint64_t). The WSI implementation will temporarily continue
+ * to fill out deprecated fields in VkNativeBufferANDROID, and will call the
+ * deprecated vkGetSwapchainGrallocUsageANDROID if the new
+ * vkGetSwapchainGrallocUsage2ANDROID is not supported. This transitionary
+ * backwards-compatibility support is temporary, and will likely be removed in
+ * (along with all gralloc0 support) in a future release.
+ */
 #define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION     6
 #define VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME   "VK_ANDROID_native_buffer"
 
@@ -50,7 +60,12 @@ typedef struct {
 
     // Gralloc format and usage requested when the buffer was allocated.
     int                         format;
-    int                         usage;
+    int                         usage; // DEPRECATED in SPEC_VERSION 6
+    // -- Added in SPEC_VERSION 6 --
+    struct {
+        uint64_t                consumer;
+        uint64_t                producer;
+    } usage2;
 } VkNativeBufferANDROID;
 
 typedef struct {
@@ -60,24 +75,30 @@ typedef struct {
     VkSwapchainImageUsageFlagsANDROID      usage;
 } VkSwapchainImageCreateInfoANDROID;
 
+// -- DEPRECATED in SPEC_VERSION 6 --
 typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsageANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
-typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage2ANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, int* grallocUsage);
+// -- ADDED in SPEC_VERSION 6 --
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage2ANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage, uint64_t* grallocProducerUsage);
 typedef VkResult (VKAPI_PTR *PFN_vkAcquireImageANDROID)(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence);
 typedef VkResult (VKAPI_PTR *PFN_vkQueueSignalReleaseImageANDROID)(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd);
 
 #ifndef VK_NO_PROTOTYPES
+
+// -- DEPRECATED in SPEC_VERSION 6 --
 VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsageANDROID(
     VkDevice            device,
     VkFormat            format,
     VkImageUsageFlags   imageUsage,
     int*                grallocUsage
 );
+// -- ADDED in SPEC_VERSION 6 --
 VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
     VkDevice            device,
     VkFormat            format,
     VkImageUsageFlags   imageUsage,
     VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
-    int*                grallocUsage
+    uint64_t*           grallocConsumerUsage,
+    uint64_t*           grallocProducerUsage
 );
 VKAPI_ATTR VkResult VKAPI_CALL vkAcquireImageANDROID(
     VkDevice            device,
@@ -93,17 +114,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkQueueSignalReleaseImageANDROID(
     VkImage             image,
     int*                pNativeFenceFd
 );
-// -- DEPRECATED --
-VKAPI_ATTR VkResult VKAPI_CALL vkImportNativeFenceANDROID(
-    VkDevice            device,
-    VkSemaphore         semaphore,
-    int                 nativeFenceFd
-);
-VKAPI_ATTR VkResult VKAPI_CALL vkQueueSignalNativeFenceANDROID(
-    VkQueue             queue,
-    int*                pNativeFenceFd
-);
-// ----------------
 #endif
 
 #ifdef __cplusplus
index 746ab4e..524de75 100644 (file)
@@ -69,12 +69,12 @@ cc_library_shared {
         "vulkan_headers",
     ],
     shared_libs: [
-        "libgui",
         "libziparchive",
         "libhardware",
         "libsync",
         "libbase",
         "liblog",
+        "libui",
         "libutils",
         "libcutils",
         "libz",
index 501877c..e3c44d2 100644 (file)
@@ -413,13 +413,14 @@ bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc,
   {{AssertType $ "Function"}}
 
   {{$ext := GetAnnotation $ "extension"}}
-  {{$required := (Macro "IsRequiredFunction" $)}}
   {{if $ext}}
-    INIT_PROC_EXT({{Macro "BaseName" $ext}}, {{$required}}, §
+    INIT_PROC_EXT({{Macro "BaseName" $ext}}, §
   {{else}}
-    INIT_PROC({{$required}}, §
+    INIT_PROC(§
   {{end}}
 
+  {{if GetAnnotation $ "optional"}}false{{else}}true{{end}}, §
+
   {{if (Macro "IsInstanceDispatched" $)}}
     instance, §
   {{else}}
@@ -432,25 +433,6 @@ bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc,
 
 {{/*
 ------------------------------------------------------------------------------
-  Emits true if a function /must/ be resolved. The only time this is not
-  the case is for extension-added functions added in a later revision of the
-  extension, and where we have to cope with drivers written against an older
-  revision.
-------------------------------------------------------------------------------
-*/}}
-{{define "IsRequiredFunction"}}
-  {{AssertType $ "Function"}}
-
-  {{if eq $.Name "vkGetSwapchainGrallocUsage2ANDROID"}}
-    false
-  {{else}}
-    true
-  {{end}}
-{{end}}
-
-
-{{/*
-------------------------------------------------------------------------------
   Emits true if a function is exported and instance-dispatched.
 ------------------------------------------------------------------------------
 */}}
@@ -981,6 +963,8 @@ VK_KHR_shared_presentable_image
     {{else if eq $.Name "vkCreateImage"}}true
     {{else if eq $.Name "vkDestroyImage"}}true
 
+    {{else if eq $.Name "vkGetPhysicalDeviceProperties"}}true
+
     {{end}}
 
     {{$ext := GetAnnotation $ "extension"}}
index 0c2f138..40ba1e5 100644 (file)
@@ -46,7 +46,8 @@ void DebugReportCallbackList::RemoveCallback(
         Node* prev = &head_;
         while (prev && prev->next != node)
             prev = prev->next;
-        prev->next = node->next;
+        if (prev)
+            prev->next = node->next;
     }
 
     allocator.pfnFree(allocator.pUserData, node);
index b34e9be..a23056c 100644 (file)
@@ -28,7 +28,7 @@
 
 #include <android/dlext.h>
 #include <cutils/properties.h>
-#include <gui/GraphicsEnv.h>
+#include <ui/GraphicsEnv.h>
 
 #include "driver.h"
 #include "stubhal.h"
@@ -739,8 +739,10 @@ VkResult EnumerateDeviceExtensionProperties(
     const InstanceData& data = GetData(physicalDevice);
     static const std::array<VkExtensionProperties, 2> loader_extensions = {{
         // WSI extensions
+#if 0 // Remove this "#if 0" once the VK_KHR_incremental_present extension is ratified
         {VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
          VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION},
+#endif
         {VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
          VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION},
     }};
@@ -899,7 +901,29 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice,
 
         return VK_ERROR_INCOMPATIBLE_DRIVER;
     }
+
+    // sanity check ANDROID_native_buffer implementation, whose set of
+    // entrypoints varies according to the spec version.
+    if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
+        !data->driver.GetSwapchainGrallocUsageANDROID &&
+        !data->driver.GetSwapchainGrallocUsage2ANDROID) {
+        ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
+              " must expose at least one of "
+              "vkGetSwapchainGrallocUsageANDROID or "
+              "vkGetSwapchainGrallocUsage2ANDROID");
+
+        data->driver.DestroyDevice(dev, pAllocator);
+        FreeDeviceData(data, data_allocator);
+
+        return VK_ERROR_INCOMPATIBLE_DRIVER;
+    }
+
+    VkPhysicalDeviceProperties properties;
+    instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
+                                                     &properties);
+
     data->driver_device = dev;
+    data->driver_version = properties.driverVersion;
 
     *pDevice = dev;
 
index e058439..5383f59 100644 (file)
@@ -102,6 +102,7 @@ struct DeviceData {
 
     VkDevice driver_device;
     DeviceDriverTable driver;
+    uint32_t driver_version;
 };
 
 bool Debuggable();
index 689a228..951ea6e 100644 (file)
@@ -387,6 +387,7 @@ bool InitDriverTable(VkInstance instance,
     INIT_PROC(true, instance, DestroyInstance);
     INIT_PROC(true, instance, EnumeratePhysicalDevices);
     INIT_PROC(true, instance, GetInstanceProcAddr);
+    INIT_PROC(true, instance, GetPhysicalDeviceProperties);
     INIT_PROC(true, instance, CreateDevice);
     INIT_PROC(true, instance, EnumerateDeviceExtensionProperties);
     INIT_PROC_EXT(EXT_debug_report, true, instance, CreateDebugReportCallbackEXT);
@@ -410,7 +411,7 @@ bool InitDriverTable(VkDevice dev,
     INIT_PROC(true, dev, CreateImage);
     INIT_PROC(true, dev, DestroyImage);
     INIT_PROC(true, dev, AllocateCommandBuffers);
-    INIT_PROC_EXT(ANDROID_native_buffer, true, dev, GetSwapchainGrallocUsageANDROID);
+    INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsageANDROID);
     INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsage2ANDROID);
     INIT_PROC_EXT(ANDROID_native_buffer, true, dev, AcquireImageANDROID);
     INIT_PROC_EXT(ANDROID_native_buffer, true, dev, QueueSignalReleaseImageANDROID);
index 9f3b705..95c70f8 100644 (file)
@@ -60,6 +60,7 @@ struct InstanceDriverTable {
     PFN_vkDestroyInstance DestroyInstance;
     PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
     PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
+    PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
     PFN_vkCreateDevice CreateDevice;
     PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
     PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
index 1afa86c..9630ac9 100644 (file)
@@ -176,9 +176,12 @@ enum { MAX_TIMING_INFOS = 10 };
 enum { MIN_NUM_FRAMES_AGO = 5 };
 
 struct Swapchain {
-    Swapchain(Surface& surface_, uint32_t num_images_)
+    Swapchain(Surface& surface_,
+              uint32_t num_images_,
+              VkPresentModeKHR present_mode)
         : surface(surface_),
           num_images(num_images_),
+          mailbox_mode(present_mode == VK_PRESENT_MODE_MAILBOX_KHR),
           frame_timestamps_enabled(false) {
         ANativeWindow* window = surface.window.get();
         int64_t rdur;
@@ -190,6 +193,7 @@ struct Swapchain {
 
     Surface& surface;
     uint32_t num_images;
+    bool mailbox_mode;
     bool frame_timestamps_enabled;
     uint64_t refresh_duration;
 
@@ -545,8 +549,8 @@ VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice /*pdev*/,
     const VkPresentModeKHR kModes[] = {
         VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR,
         // TODO(chrisforbes): should only expose this if the driver can.
-        VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR,
-        VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR,
+        // VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR,
+        // VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR,
     };
     const uint32_t kNumModes = sizeof(kModes) / sizeof(kModes[0]);
 
@@ -793,13 +797,35 @@ VkResult CreateSwapchainKHR(VkDevice device,
 
     int gralloc_usage = 0;
     if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
-        result = dispatch.GetSwapchainGrallocUsage2ANDROID(
-            device, create_info->imageFormat, create_info->imageUsage,
-            swapchain_image_usage, &gralloc_usage);
+        uint64_t consumer_usage, producer_usage;
+        if (GetData(device).driver_version == 256587285) {
+            // HACK workaround for loader/driver mismatch during transition to
+            // vkGetSwapchainGrallocUsage2ANDROID.
+            typedef VkResult(VKAPI_PTR *
+                             PFN_vkGetSwapchainGrallocUsage2ANDROID_HACK)(
+                VkDevice device, VkFormat format, VkImageUsageFlags imageUsage,
+                uint64_t * grallocConsumerUsage,
+                uint64_t * grallocProducerUsage);
+            auto get_swapchain_gralloc_usage =
+                reinterpret_cast<PFN_vkGetSwapchainGrallocUsage2ANDROID_HACK>(
+                    dispatch.GetSwapchainGrallocUsage2ANDROID);
+            result = get_swapchain_gralloc_usage(
+                device, create_info->imageFormat, create_info->imageUsage,
+                &consumer_usage, &producer_usage);
+        } else {
+            result = dispatch.GetSwapchainGrallocUsage2ANDROID(
+                device, create_info->imageFormat, create_info->imageUsage,
+                swapchain_image_usage, &consumer_usage, &producer_usage);
+        }
         if (result != VK_SUCCESS) {
             ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result);
             return VK_ERROR_INITIALIZATION_FAILED;
         }
+        // TODO: This is the same translation done by Gralloc1On0Adapter.
+        // Remove it once ANativeWindow has been updated to take gralloc1-style
+        // usages.
+        gralloc_usage =
+            static_cast<int>(consumer_usage) | static_cast<int>(producer_usage);
     } else if (dispatch.GetSwapchainGrallocUsageANDROID) {
         result = dispatch.GetSwapchainGrallocUsageANDROID(
             device, create_info->imageFormat, create_info->imageUsage,
@@ -808,8 +834,6 @@ VkResult CreateSwapchainKHR(VkDevice device,
             ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result);
             return VK_ERROR_INITIALIZATION_FAILED;
         }
-    } else {
-        gralloc_usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
     }
     err = native_window_set_usage(surface.window.get(), gralloc_usage);
     if (err != 0) {
@@ -838,7 +862,8 @@ VkResult CreateSwapchainKHR(VkDevice device,
                                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     if (!mem)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
-    Swapchain* swapchain = new (mem) Swapchain(surface, num_images);
+    Swapchain* swapchain =
+        new (mem) Swapchain(surface, num_images, create_info->presentMode);
 
     // -- Dequeue all buffers and create a VkImage for each --
     // Any failures during or after this must cancel the dequeued buffers.
@@ -899,6 +924,12 @@ VkResult CreateSwapchainKHR(VkDevice device,
         image_native_buffer.stride = img.buffer->stride;
         image_native_buffer.format = img.buffer->format;
         image_native_buffer.usage = img.buffer->usage;
+        // TODO: Adjust once ANativeWindowBuffer supports gralloc1-style usage.
+        // For now, this is the same translation Gralloc1On0Adapter does.
+        image_native_buffer.usage2.consumer =
+            static_cast<uint64_t>(img.buffer->usage);
+        image_native_buffer.usage2.producer =
+            static_cast<uint64_t>(img.buffer->usage);
 
         result =
             dispatch.CreateImage(device, &image_create, nullptr, &img.image);
@@ -1134,7 +1165,8 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) {
             *SwapchainFromHandle(present_info->pSwapchains[sc]);
         uint32_t image_idx = present_info->pImageIndices[sc];
         Swapchain::Image& img = swapchain.images[image_idx];
-        const VkPresentRegionKHR* region = (regions) ? &regions[sc] : nullptr;
+        const VkPresentRegionKHR* region =
+            (regions && !swapchain.mailbox_mode) ? &regions[sc] : nullptr;
         const VkPresentTimeGOOGLE* time = (times) ? &times[sc] : nullptr;
         VkResult swapchain_result = VK_SUCCESS;
         VkResult result;
index 55f7f19..e03ee0a 100644 (file)
@@ -906,9 +906,11 @@ VkResult GetSwapchainGrallocUsage2ANDROID(VkDevice,
                                           VkFormat,
                                           VkImageUsageFlags,
                                           VkSwapchainImageUsageFlagsANDROID,
-                                          int* grallocUsage) {
+                                          uint64_t* grallocConsumerUsage,
+                                          uint64_t* grallocProducerUsage) {
     // The null driver never reads or writes the gralloc buffer
-    *grallocUsage = 0;
+    *grallocConsumerUsage = 0;
+    *grallocProducerUsage = 0;
     return VK_SUCCESS;
 }
 
index cfc14dd..d73bf14 100644 (file)
@@ -165,8 +165,8 @@ VKAPI_ATTR void CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRender
 VKAPI_ATTR void CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents);
 VKAPI_ATTR void CmdEndRenderPass(VkCommandBuffer commandBuffer);
 VKAPI_ATTR void CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers);
-VKAPI_ATTR VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
-VKAPI_ATTR VkResult GetSwapchainGrallocUsage2ANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, int* grallocUsage);
+VKAPI_ATTR VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int32_t* grallocUsage);
+VKAPI_ATTR VkResult GetSwapchainGrallocUsage2ANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage, uint64_t* grallocProducerUsage);
 VKAPI_ATTR VkResult AcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence);
 VKAPI_ATTR VkResult QueueSignalReleaseImageANDROID(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd);
 VKAPI_ATTR VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback);