diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp index 26c5b4ac3..7201e77ca 100644 --- a/cmds/atrace/atrace.cpp +++ b/cmds/atrace/atrace.cpp @@ -93,6 +93,7 @@ static const TracingCategory k_categories[] = { { "sched", "CPU Scheduling", 0, { { REQ, "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" }, { REQ, "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" }, + { OPT, "/sys/kernel/debug/tracing/events/sched/sched_blocked_reason/enable" }, } }, { "irq", "IRQ Events", 0, { { REQ, "/sys/kernel/debug/tracing/events/irq/enable" }, diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index 792f0155c..a2e4f4bd5 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -47,6 +47,7 @@ static char screenshot_path[PATH_MAX] = ""; #define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops" +#define RAFT_DIR "/data/misc/raft/" #define TOMBSTONE_DIR "/data/tombstones" #define TOMBSTONE_FILE_PREFIX TOMBSTONE_DIR "/tombstone_" /* Can accomodate a tombstone number up to 9999. */ @@ -261,6 +262,8 @@ static unsigned long logcat_timeout(char *name) { /* End copy from system/core/logd/LogBuffer.cpp */ +static const unsigned long logcat_min_timeout = 40000; /* ms */ + /* dumps the current system state to stdout */ static void dumpstate() { unsigned long timeout; @@ -333,23 +336,25 @@ static void dumpstate() { // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); // calculate timeout timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); - if (timeout < 20000) { - timeout = 20000; + if (timeout < logcat_min_timeout) { + timeout = logcat_min_timeout; } run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", "-d", "*:v", NULL); timeout = logcat_timeout("events"); - if (timeout < 20000) { - timeout = 20000; + if (timeout < logcat_min_timeout) { + timeout = logcat_min_timeout; } run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL); timeout = logcat_timeout("radio"); - if (timeout < 20000) { - timeout = 20000; + if (timeout < logcat_min_timeout) { + timeout = logcat_min_timeout; } run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL); run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); + run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL); + /* show the traces we collected in main(), if that was done */ if (dump_traces_path != NULL) { dump_file("VM TRACES JUST NOW", dump_traces_path); diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp index 322d537ee..09369ce4a 100644 --- a/cmds/installd/commands.cpp +++ b/cmds/installd/commands.cpp @@ -771,24 +771,11 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, dex2oat_compiler_filter_flag, NULL) > 0; char dex2oat_threads_buf[PROPERTY_VALUE_MAX]; - bool have_dex2oat_threads_flag = false; - if (!post_bootcomplete) { - have_dex2oat_threads_flag = property_get("dalvik.vm.boot-dex2oat-threads", - dex2oat_threads_buf, - NULL) > 0; - // If there's no boot property, fall back to the image property. - if (!have_dex2oat_threads_flag) { - have_dex2oat_threads_flag = property_get("dalvik.vm.image-dex2oat-threads", - dex2oat_threads_buf, - NULL) > 0; - } - // If there's neither, fall back to the default property. - } - if (!have_dex2oat_threads_flag) { - have_dex2oat_threads_flag = property_get("dalvik.vm.dex2oat-threads", - dex2oat_threads_buf, - NULL) > 0; - } + bool have_dex2oat_threads_flag = property_get(post_bootcomplete + ? "dalvik.vm.dex2oat-threads" + : "dalvik.vm.boot-dex2oat-threads", + dex2oat_threads_buf, + NULL) > 0; char dex2oat_threads_arg[PROPERTY_VALUE_MAX + 2]; if (have_dex2oat_threads_flag) { sprintf(dex2oat_threads_arg, "-j%s", dex2oat_threads_buf); @@ -1721,7 +1708,8 @@ fail: } static void run_aapt(const char *source_apk, const char *internal_path, - int resapk_fd, int pkgId, int min_sdk_version, const char *common_res_path) + int resapk_fd, int pkgId, int min_sdk_version, + const char *app_res_path, const char *common_res_path) { static const char *AAPT_BIN = "/system/bin/aapt"; static const char *MANIFEST = "/data/app/AndroidManifest.xml"; @@ -1735,40 +1723,48 @@ static void run_aapt(const char *source_apk, const char *internal_path, snprintf(resapk_str, sizeof(resapk_str), "%d", resapk_fd); snprintf(pkgId_str, sizeof(pkgId_str), "%d", pkgId); snprintf(minSdkVersion_str, sizeof(minSdkVersion_str), "%d", min_sdk_version); + bool hasCommonResources = (common_res_path != NULL && common_res_path[0] != '\0'); + bool hasAppResources = (app_res_path != NULL && app_res_path[0] != '\0'); if (hasCommonResources) { execl(AAPT_BIN, AAPT_BIN, "package", - "--min-sdk-version", minSdkVersion_str, - "-M", MANIFEST, - "-S", source_apk, - "-X", internal_path, - "-I", FRAMEWORK_RES, - "-I", common_res_path, - "-r", resapk_str, - "-x", pkgId_str, - "-f", - (char*)NULL); + "--min-sdk-version", minSdkVersion_str, + "-M", MANIFEST, + "-S", source_apk, + "-X", internal_path, + "-I", FRAMEWORK_RES, + "-r", resapk_str, + "-x", pkgId_str, + "-f", + "-I", common_res_path, + hasAppResources ? "-I" : (char*)NULL, + hasAppResources ? app_res_path : (char*) NULL, + (char*)NULL); } else { execl(AAPT_BIN, AAPT_BIN, "package", - "--min-sdk-version", minSdkVersion_str, - "-M", MANIFEST, - "-S", source_apk, - "-X", internal_path, - "-I", FRAMEWORK_RES, - "-r", resapk_str, - "-x", pkgId_str, - "-f", - (char*)NULL); + "--min-sdk-version", minSdkVersion_str, + "-M", MANIFEST, + "-S", source_apk, + "-X", internal_path, + "-I", FRAMEWORK_RES, + "-r", resapk_str, + "-x", pkgId_str, + "-f", + hasAppResources ? "-I" : (char*)NULL, + hasAppResources ? app_res_path : (char*) NULL, + (char*)NULL); } ALOGE("execl(%s) failed: %s\n", AAPT_BIN, strerror(errno)); } int aapt(const char *source_apk, const char *internal_path, const char *out_restable, uid_t uid, - int pkgId, int min_sdk_version, const char *common_res_path) + int pkgId, int min_sdk_version, const char *app_res_path, const char *common_res_path) { - ALOGD("aapt source_apk=%s internal_path=%s out_restable=%s uid=%d, pkgId=%d,min_sdk_version=%d, common_res_path=%s", - source_apk, internal_path, out_restable, uid, pkgId, min_sdk_version, common_res_path); + ALOGD("aapt source_apk=%s internal_path=%s out_restable=%s uid=%d, pkgId=%d,min_sdk_version=%d,\ + app_res_path=%s, common_res_path=%s", + source_apk, internal_path, out_restable, uid, pkgId, min_sdk_version, app_res_path, + common_res_path); static const int PARENT_READ_PIPE = 0; static const int CHILD_WRITE_PIPE = 1; @@ -1828,7 +1824,8 @@ int aapt(const char *source_apk, const char *internal_path, const char *out_rest } } - run_aapt(source_apk, internal_path, resapk_fd, pkgId, min_sdk_version, common_res_path); + run_aapt(source_apk, internal_path, resapk_fd, pkgId, min_sdk_version, app_res_path, + common_res_path); close(resapk_fd); if (pipefd[CHILD_WRITE_PIPE] > 0) { diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp index c92bed020..df159e364 100644 --- a/cmds/installd/installd.cpp +++ b/cmds/installd/installd.cpp @@ -163,12 +163,12 @@ static int do_idmap(char **arg, char reply[REPLY_MAX] __unused) static int do_aapt(char **arg, char reply[REPLY_MAX] __unused) { - return aapt(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]), ""); + return aapt(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]), arg[6], ""); } static int do_aapt_with_common(char **arg, char reply[REPLY_MAX] __unused) { - return aapt(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]), arg[6]); + return aapt(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]), arg[6], arg[7]); } static int do_restorecon_data(char **arg, char reply[REPLY_MAX] __attribute__((unused))) @@ -223,8 +223,8 @@ struct cmdinfo cmds[] = { { "mkuserconfig", 1, do_mk_user_config }, { "rmuser", 2, do_rm_user }, { "idmap", 6, do_idmap }, - { "aapt", 6, do_aapt }, - { "aapt_with_common", 7, do_aapt_with_common }, + { "aapt", 7, do_aapt }, + { "aapt_with_common", 8, do_aapt_with_common }, { "restorecondata", 4, do_restorecon_data }, { "createoatdir", 2, do_create_oat_dir }, { "rmpackagedir", 1, do_rm_package_dir }, diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index 70e5e16c8..b4c5961d3 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -253,7 +253,7 @@ int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int u int idmap(const char *target_path, const char *overlay_path, const char *cache_path, uid_t uid, uint32_t target_hash, uint32_t overlay_hash); int aapt(const char *source_apk, const char *internal_path, const char *out_restable, uid_t uid, - int pkgId, int min_sdk_version, const char *common_res_path); + int pkgId, int min_sdk_version, const char *app_res_path, const char *common_res_path); int restorecon_data(const char *uuid, const char* pkgName, const char* seinfo, uid_t uid); int create_oat_dir(const char* oat_dir, const char *instruction_set); int rm_package_dir(const char* apk_path); diff --git a/include/android/keycodes.h b/include/android/keycodes.h index 15bb78684..421abe547 100644 --- a/include/android/keycodes.h +++ b/include/android/keycodes.h @@ -722,7 +722,22 @@ enum { AKEYCODE_NAVIGATE_PREVIOUS = 260, AKEYCODE_NAVIGATE_NEXT = 261, AKEYCODE_NAVIGATE_IN = 262, - AKEYCODE_NAVIGATE_OUT = 263 + AKEYCODE_NAVIGATE_OUT = 263, + /** Primary stem key for Wear + * Main power/reset button on watch. */ + AKEYCODE_STEM_PRIMARY = 264, + /** Generic stem key 1 for Wear */ + AKEYCODE_STEM_1 = 265, + /** Generic stem key 2 for Wear */ + AKEYCODE_STEM_2 = 266, + /** Generic stem key 3 for Wear */ + AKEYCODE_STEM_3 = 267, + AKEYCODE_MEDIA_SKIP_FORWARD = 272, + AKEYCODE_MEDIA_SKIP_BACKWARD = 273, + AKEYCODE_MEDIA_STEP_FORWARD = 274, + AKEYCODE_MEDIA_STEP_BACKWARD = 275, + /** Put device to sleep unless a wakelock is held. */ + AKEYCODE_SOFT_SLEEP = 276 // NOTE: If you add a new keycode here you must also add it to several other files. // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h index c2ed503f0..c03c0f2d5 100644 --- a/include/input/InputEventLabels.h +++ b/include/input/InputEventLabels.h @@ -303,6 +303,15 @@ static const InputEventLabel KEYCODES[] = { DEFINE_KEYCODE(NAVIGATE_NEXT), DEFINE_KEYCODE(NAVIGATE_IN), DEFINE_KEYCODE(NAVIGATE_OUT), + DEFINE_KEYCODE(STEM_PRIMARY), + DEFINE_KEYCODE(STEM_1), + DEFINE_KEYCODE(STEM_2), + DEFINE_KEYCODE(STEM_3), + DEFINE_KEYCODE(MEDIA_SKIP_FORWARD), + DEFINE_KEYCODE(MEDIA_SKIP_BACKWARD), + DEFINE_KEYCODE(MEDIA_STEP_FORWARD), + DEFINE_KEYCODE(MEDIA_STEP_BACKWARD), + DEFINE_KEYCODE(SOFT_SLEEP), { NULL, 0 } }; diff --git a/include/media/openmax/OMX_Core.h b/include/media/openmax/OMX_Core.h index 521c223b0..f746a69d2 100644 --- a/include/media/openmax/OMX_Core.h +++ b/include/media/openmax/OMX_Core.h @@ -509,7 +509,7 @@ typedef enum OMX_EVENTTYPE OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - /** Event when tunneled decoder has rendered an output + /** Event when tunneled decoder has rendered an output or reached EOS * nData1 must contain the number of timestamps returned * pEventData must point to an array of the OMX_VIDEO_RENDEREVENTTYPE structs containing the * render-timestamps of each frame. Component may batch rendered timestamps using this event, @@ -518,6 +518,10 @@ typedef enum OMX_EVENTTYPE * * If component is doing frame-rate conversion, it must signal the render time of each * converted frame, and must interpolate media timestamps for in-between frames. + * + * When the component reached EOS, it must signal an EOS timestamp using the same mechanism. + * This is in addition to the timestamp of the last rendered frame, and should follow that + * frame. */ OMX_EventOutputRendered = 0x7F000001, OMX_EventMax = 0x7FFFFFFF diff --git a/include/media/openmax/OMX_VideoExt.h b/include/media/openmax/OMX_VideoExt.h index 34c040574..3971bc5cc 100644 --- a/include/media/openmax/OMX_VideoExt.h +++ b/include/media/openmax/OMX_VideoExt.h @@ -203,10 +203,17 @@ typedef struct OMX_VIDEO_SLICESEGMENTSTYPE { OMX_BOOL bEnableLoopFilterAcrossSlices; } OMX_VIDEO_SLICESEGMENTSTYPE; -/** Structure to return timestamps of rendered output frames for tunneled components */ +/** Structure to return timestamps of rendered output frames as well as EOS + * for tunneled components. + */ typedef struct OMX_VIDEO_RENDEREVENTTYPE { OMX_S64 nMediaTimeUs; // timestamp of rendered video frame OMX_S64 nSystemTimeNs; // system monotonic time at the time frame was rendered + // Use INT64_MAX for nMediaTimeUs to signal that the EOS + // has been reached. In this case, nSystemTimeNs MUST be + // the system time when the last frame was rendered. + // This MUST be done in addition to returning (and + // following) the render information for the last frame. } OMX_VIDEO_RENDEREVENTTYPE; #ifdef __cplusplus diff --git a/libs/binder/MemoryHeapIon.cpp b/libs/binder/MemoryHeapIon.cpp index c547395dc..26c556639 100644 --- a/libs/binder/MemoryHeapIon.cpp +++ b/libs/binder/MemoryHeapIon.cpp @@ -116,10 +116,10 @@ MemoryHeapIon::MemoryHeapIon(size_t size, uint32_t flags, flagMask = ion_FlagMask_valid_check(flags); if (heapMask) { - ALOGD("MemoryHeapIon : Allocated with size:%d, heap:0x%X , flag:0x%X", size, heapMask, flagMask); + ALOGD("MemoryHeapIon : Allocated with size:%zu, heap:0x%X , flag:0x%X", size, heapMask, flagMask); fd = ion_alloc(mIonClient, size, 0, heapMask, flagMask); if (fd < 0) { - ALOGE("MemoryHeapIon : ION Reserve memory allocation failed(size[%u]) : %s", size, strerror(errno)); + ALOGE("MemoryHeapIon : ION Reserve memory allocation failed(size[%zu]) : %s", size, strerror(errno)); if (errno == ENOMEM) { // Out of reserve memory. So re-try allocating in system heap ALOGD("MemoryHeapIon : Re-try Allocating in default heap - SYSTEM heap"); fd = ion_alloc(mIonClient, size, 0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC | ION_FLAG_PRESERVE_KMAP); @@ -133,14 +133,14 @@ MemoryHeapIon::MemoryHeapIon(size_t size, uint32_t flags, flags = isReadOnly | heapMask | flagMask; if (fd < 0) { - ALOGE("MemoryHeapIon : ION memory allocation failed(size[%u]) : %s", size, strerror(errno)); + ALOGE("MemoryHeapIon : ION memory allocation failed(size[%zu]) : %s", size, strerror(errno)); } else { flags |= USE_ION_FD; base = ion_map(fd, size, 0); if (base != MAP_FAILED) { init(fd, base, size, flags, NULL); } else { - ALOGE("MemoryHeapIon : ION mmap failed(size[%u], fd[%d]) : %s", size, fd, strerror(errno)); + ALOGE("MemoryHeapIon : ION mmap failed(size[%zu], fd[%d]) : %s", size, fd, strerror(errno)); ion_free(fd); } } @@ -162,14 +162,14 @@ MemoryHeapIon::MemoryHeapIon(int fd, size_t size, uint32_t flags, if (fd >= 0) { dup_fd = dup(fd); if (dup_fd == -1) { - ALOGE("MemoryHeapIon : cannot dup fd (size[%u], fd[%d]) : %s", size, fd, strerror(errno)); + ALOGE("MemoryHeapIon : cannot dup fd (size[%zu], fd[%d]) : %s", size, fd, strerror(errno)); } else { flags |= USE_ION_FD; base = ion_map(dup_fd, size, 0); if (base != MAP_FAILED) { init(dup_fd, base, size, flags, NULL); } else { - ALOGE("MemoryHeapIon : ION mmap failed(size[%u], fd[%d]): %s", size, fd, strerror(errno)); + ALOGE("MemoryHeapIon : ION mmap failed(size[%zu], fd[%d]): %s", size, fd, strerror(errno)); ion_free(dup_fd); } } diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp index b86f4c5d2..c4660bad8 100644 --- a/libs/gui/IGraphicBufferConsumer.cpp +++ b/libs/gui/IGraphicBufferConsumer.cpp @@ -315,7 +315,7 @@ status_t BnGraphicBufferConsumer::onTransact( CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); sp buffer = new GraphicBuffer(); data.read(*buffer.get()); - int slot; + int slot = -1; int result = attachBuffer(&slot, buffer); reply->writeInt32(slot); reply->writeInt32(result); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 8bdbc22ec..1099c84f8 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -402,6 +402,7 @@ status_t BnGraphicBufferProducer::onTransact( QueueBufferOutput* const output = reinterpret_cast( reply->writeInplace(sizeof(QueueBufferOutput))); + memset(output, 0, sizeof(QueueBufferOutput)); status_t result = queueBuffer(buf, input, output); reply->writeInt32(result); return NO_ERROR; diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index c2b74ed57..c1ddba1e4 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -39,6 +39,11 @@ LOCAL_SRC_FILES := \ DisplayUtils.cpp LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" + +ifeq ($(TARGET_BUILD_VARIANT),userdebug) +LOCAL_CFLAGS += -DDEBUG_CONT_DUMPSYS +endif + LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES ifeq ($(TARGET_BOARD_PLATFORM),omap4) @@ -141,6 +146,10 @@ LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--e LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CPPFLAGS := -std=c++11 +ifneq ($(ENABLE_CPUSETS),) + LOCAL_CFLAGS += -DENABLE_CPUSETS +endif + LOCAL_SRC_FILES := \ main_surfaceflinger.cpp diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index 1e4f907da..5fd2136e2 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -19,6 +19,7 @@ #include "HWComposer.h" #include +#include // --------------------------------------------------------------------------- namespace android { @@ -30,6 +31,10 @@ static const bool sForceHwcCopy = true; static const bool sForceHwcCopy = false; #endif +#ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS +#define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2) +#endif + #define VDS_LOGE(msg, ...) ALOGE("[%s] " msg, \ mDisplayName.string(), ##__VA_ARGS__) #define VDS_LOGW_IF(cond, msg, ...) ALOGW_IF(cond, "[%s] " msg, \ @@ -64,6 +69,7 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId, { mSource[SOURCE_SINK] = sink; mSource[SOURCE_SCRATCH] = bqProducer; + sp surface(new Surface(bqProducer, false)); resetPerFrameState(); @@ -92,7 +98,9 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId, mConsumer->setConsumerName(ConsumerBase::mName); mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER); mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight); - mConsumer->setDefaultMaxBufferCount(2); + mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS); + + surface->allocateBuffers(); } VirtualDisplaySurface::~VirtualDisplaySurface() { diff --git a/services/surfaceflinger/DisplayUtils.cpp b/services/surfaceflinger/DisplayUtils.cpp index 96daeacc9..a07e69eda 100644 --- a/services/surfaceflinger/DisplayUtils.cpp +++ b/services/surfaceflinger/DisplayUtils.cpp @@ -174,9 +174,15 @@ bool DisplayUtils::canAllocateHwcDisplayIdForVDS(int usage) { // on AOSP builds with QTI_BSP disabled, we should allocate hwc display id for virtual display int flag_mask = 0xffffffff; -#if QTI_BSP +#ifdef QTI_BSP +#ifdef FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS // Reserve hardware acceleration for WFD use-case flag_mask = GRALLOC_USAGE_PRIVATE_WFD; +#else + // Don't allocate HWC display unless we force HWC copy, otherwise + // incompatible buffers are sent to the media stack + flag_mask = 0; +#endif #endif return (usage & flag_mask); diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp b/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp index 3579abb4b..96d4b1d1e 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp +++ b/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp @@ -28,6 +28,7 @@ #include "ExSurfaceFlinger.h" #include "ExLayer.h" +#include #include #ifdef QTI_BSP #include @@ -138,6 +139,18 @@ bool ExSurfaceFlinger::updateLayerVisibleNonTransparentRegion( layer->setVisibleNonTransparentRegion(visibleNonTransRegion); return true; } + + if (mDisableExtAnimation) { + /* Remove screenShotSurface from secondary displays when ext animation disabled */ + const int screenShotLen = strlen("ScreenshotSurface"); + if (dpy && !strncmp(layer->getName(), "ScreenshotSurface", screenShotLen) ) { + Region visibleNonTransRegion; + visibleNonTransRegion.set(Rect(0, 0)); + layer->setVisibleNonTransparentRegion(visibleNonTransRegion); + return true; + } + } + return false; } @@ -181,7 +194,8 @@ bool ExSurfaceFlinger::canDrawLayerinScreenShot( && !layer->isProtected() && !(!dispType && (layer->isExtOnly() || (isExtendedMode() && layer->isYuvLayer()))) - && layer->isVisible() ){ + && !(layer->isIntOnly() && dispType) + && layer->isVisible()){ return true; } return false; @@ -253,4 +267,110 @@ void ExSurfaceFlinger::drawWormHoleIfRequired(HWComposer::LayerListIterator& cur } } +#ifdef DEBUG_CONT_DUMPSYS +status_t ExSurfaceFlinger::dump(int fd, const Vector& args) { + // Format: adb shell dumpsys SurfaceFlinger --file --no-limit + size_t numArgs = args.size(); + status_t err = NO_ERROR; + + if (!numArgs || (args[0] != String16("--file"))) { + return SurfaceFlinger::dump(fd, args); + } + + Mutex::Autolock _l(mFileDump.lock); + + // Same command is used to start and end dump. + mFileDump.running = !mFileDump.running; + + if (mFileDump.running) { + // Create an empty file or erase existing file. + std::fstream fs; + fs.open(mFileDump.name, std::ios::out); + if (!fs) { + mFileDump.running = false; + err = UNKNOWN_ERROR; + } else { + mFileDump.position = 0; + if (numArgs >= 2 && (args[1] == String16("--nolimit"))) { + mFileDump.noLimit = true; + } else { + mFileDump.noLimit = false; + } + } + } + + String8 result; + result += mFileDump.running ? "Start" : "End"; + result += mFileDump.noLimit ? " unlimited" : " fixed limit"; + result += " dumpsys to file : "; + result += mFileDump.name; + result += "\n"; + + write(fd, result.string(), result.size()); + + return NO_ERROR; +} + +void ExSurfaceFlinger::dumpDrawCycle(bool prePrepare) { + Mutex::Autolock _l(mFileDump.lock); + + // User might stop dump collection in middle of prepare & commit. + // Collect dumpsys again after commit and replace. + if (!mFileDump.running && !mFileDump.replaceAfterCommit) { + return; + } + + Vector args; + size_t index = 0; + String8 dumpsys; + + dumpAllLocked(args, index, dumpsys); + + char timeStamp[32]; + char dataSize[32]; + char hms[32]; + long millis; + struct timeval tv; + struct tm *ptm; + + gettimeofday(&tv, NULL); + ptm = localtime(&tv.tv_sec); + strftime (hms, sizeof (hms), "%H:%M:%S", ptm); + millis = tv.tv_usec / 1000; + snprintf(timeStamp, sizeof(timeStamp), "Timestamp: %s.%03ld", hms, millis); + snprintf(dataSize, sizeof(dataSize), "Size: %8zu", dumpsys.size()); + + std::fstream fs; + fs.open(mFileDump.name, std::ios::in | std::ios::out); + if (!fs) { + ALOGE("Failed to open %s file for dumpsys", mFileDump.name); + return; + } + + // Format: + // | start code | after commit? | time stamp | dump size | dump data | + fs.seekp(mFileDump.position, std::ios::beg); + + fs << "#@#@-- DUMPSYS START --@#@#" << std::endl; + fs << "PostCommit: " << ( prePrepare ? "false" : "true" ) << std::endl; + fs << timeStamp << std::endl; + fs << dataSize << std::endl; + fs << dumpsys << std::endl; + + if (prePrepare) { + mFileDump.replaceAfterCommit = true; + } else { + mFileDump.replaceAfterCommit = false; + // Reposition only after commit. + // Keem file size to appx 20 MB limit by default, wrap around if exceeds. + mFileDump.position = fs.tellp(); + if (!mFileDump.noLimit && (mFileDump.position > (20 * 1024 * 1024))) { + mFileDump.position = 0; + } + } + + fs.close(); +} +#endif + }; // namespace android diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.h b/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.h index 628fac7f0..068f2b93c 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.h +++ b/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.h @@ -79,6 +79,20 @@ protected: bool mDebugLogs; bool isDebug() { return mDebugLogs; } bool mDisableExtAnimation; + +#ifdef DEBUG_CONT_DUMPSYS + virtual status_t dump(int fd, const Vector& args); + virtual void dumpDrawCycle(bool prePrepare ); + + struct { + Mutex lock; + const char *name = "/data/misc/display/dumpsys.txt"; + bool running = false; + bool noLimit = false; + bool replaceAfterCommit = false; + long int position = 0; + } mFileDump; +#endif }; }; //namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index b27fc2be4..a4570194a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -453,13 +453,20 @@ void SurfaceFlinger::init() { eglInitialize(mEGLDisplay, NULL, NULL); // start the EventThread - sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync, - vsyncPhaseOffsetNs, true, "app"); - mEventThread = new EventThread(vsyncSrc); - sp sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, - sfVsyncPhaseOffsetNs, true, "sf"); - mSFEventThread = new EventThread(sfVsyncSrc); - mEventQueue.setEventThread(mSFEventThread); + if (vsyncPhaseOffsetNs != sfVsyncPhaseOffsetNs) { + sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync, + vsyncPhaseOffsetNs, true, "app"); + mEventThread = new EventThread(vsyncSrc); + sp sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, + sfVsyncPhaseOffsetNs, true, "sf"); + mSFEventThread = new EventThread(sfVsyncSrc); + mEventQueue.setEventThread(mSFEventThread); + } else { + sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync, + vsyncPhaseOffsetNs, true, "sf-app"); + mEventThread = new EventThread(vsyncSrc); + mEventQueue.setEventThread(mEventThread); + } // Initialize the H/W composer object. There may or may not be an // actual hardware composer underneath. @@ -1074,6 +1081,8 @@ void SurfaceFlinger::postComposition() mAnimFrameTracker.advanceFrame(); } + dumpDrawCycle(false); + if (hw->getPowerMode() == HWC_POWER_MODE_OFF) { return; } @@ -1241,6 +1250,8 @@ void SurfaceFlinger::setUpHWComposer() { } } + dumpDrawCycle(true); + status_t err = hwc.prepare(); ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); @@ -3137,12 +3148,14 @@ status_t SurfaceFlinger::onTransact( } case 1018: { // Modify Choreographer's phase offset n = data.readInt32(); - mEventThread->setPhaseOffset(static_cast(n)); + if (mEventThread != NULL) + mEventThread->setPhaseOffset(static_cast(n)); return NO_ERROR; } case 1019: { // Modify SurfaceFlinger's phase offset n = data.readInt32(); - mSFEventThread->setPhaseOffset(static_cast(n)); + if (mSFEventThread != NULL) + mSFEventThread->setPhaseOffset(static_cast(n)); return NO_ERROR; } } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 2028d6743..1f7601acc 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -471,6 +471,7 @@ private: void logFrameStats(); void dumpStaticScreenStats(String8& result) const; + virtual void dumpDrawCycle(bool /* prePrepare */ ) { } /* ------------------------------------------------------------------------ * Attributes diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp index 6127cf6be..e8464a37d 100644 --- a/services/surfaceflinger/main_surfaceflinger.cpp +++ b/services/surfaceflinger/main_surfaceflinger.cpp @@ -42,6 +42,13 @@ int main(int, char**) { set_sched_policy(0, SP_FOREGROUND); +#ifdef ENABLE_CPUSETS + // Put most SurfaceFlinger threads in the system-background cpuset + // Keeps us from unnecessarily using big cores + // Do this after the binder thread pool init + set_cpuset_policy(0, SP_SYSTEM); +#endif + // initialize before clients can connect flinger->init();