summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-03-18 02:11:06 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-03-18 02:11:06 +0100
commitdcadad708abe4fc3b5dfe122618f3f8d3a19e614 (patch)
tree258a05e0d0a8b9b3f1bffba3974aa95cdfd1f61a
parent932ec6cd7ae0fda0c186870c29c210a6afc8e692 (diff)
parent65a4c0c045185e8bf5ad54ef8db2a3dbbf6c2813 (diff)
downloadframeworks_native-dcadad708abe4fc3b5dfe122618f3f8d3a19e614.zip
frameworks_native-dcadad708abe4fc3b5dfe122618f3f8d3a19e614.tar.gz
frameworks_native-dcadad708abe4fc3b5dfe122618f3f8d3a19e614.tar.bz2
Merge branch 'cm-13.0' of https://github.com/CyanogenMod/android_frameworks_native into replicant-6.0
Signed-off-by: Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de>
-rw-r--r--cmds/atrace/atrace.cpp1
-rw-r--r--cmds/dumpstate/dumpstate.c17
-rw-r--r--cmds/installd/commands.cpp81
-rw-r--r--cmds/installd/installd.cpp8
-rw-r--r--cmds/installd/installd.h2
-rw-r--r--include/android/keycodes.h17
-rw-r--r--include/input/InputEventLabels.h9
-rw-r--r--include/media/openmax/OMX_Core.h6
-rw-r--r--include/media/openmax/OMX_VideoExt.h9
-rw-r--r--libs/binder/MemoryHeapIon.cpp12
-rw-r--r--libs/gui/IGraphicBufferConsumer.cpp2
-rw-r--r--libs/gui/IGraphicBufferProducer.cpp1
-rw-r--r--services/surfaceflinger/Android.mk9
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp10
-rw-r--r--services/surfaceflinger/DisplayUtils.cpp8
-rw-r--r--services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp122
-rw-r--r--services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.h14
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp31
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h1
-rw-r--r--services/surfaceflinger/main_surfaceflinger.cpp7
20 files changed, 292 insertions, 75 deletions
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 26c5b4a..7201e77 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 792f015..a2e4f4b 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 322d537..09369ce 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 c92bed0..df159e3 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 70e5e16..b4c5961 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 15bb786..421abe5 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 c2ed503..c03c0f2 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 521c223..f746a69 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 34c0405..3971bc5 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 c547395..26c5566 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 b86f4c5..c4660ba 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<GraphicBuffer> 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 8bdbc22..1099c84 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -402,6 +402,7 @@ status_t BnGraphicBufferProducer::onTransact(
QueueBufferOutput* const output =
reinterpret_cast<QueueBufferOutput *>(
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 c2b74ed..c1ddba1 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 1e4f907..5fd2136 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -19,6 +19,7 @@
#include "HWComposer.h"
#include <gui/BufferItem.h>
+#include <gui/Surface.h>
// ---------------------------------------------------------------------------
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> 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 96daeac..a07e69e 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 3579abb..96d4b1d 100644
--- a/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp
+++ b/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp
@@ -28,6 +28,7 @@
#include "ExSurfaceFlinger.h"
#include "ExLayer.h"
+#include <fstream>
#include <cutils/properties.h>
#ifdef QTI_BSP
#include <hardware/display_defs.h>
@@ -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<String16>& 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<String16> 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 628fac7..068f2b9 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<String16>& 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 b27fc2b..a457019 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<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- vsyncPhaseOffsetNs, true, "app");
- mEventThread = new EventThread(vsyncSrc);
- sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- sfVsyncPhaseOffsetNs, true, "sf");
- mSFEventThread = new EventThread(sfVsyncSrc);
- mEventQueue.setEventThread(mSFEventThread);
+ if (vsyncPhaseOffsetNs != sfVsyncPhaseOffsetNs) {
+ sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
+ vsyncPhaseOffsetNs, true, "app");
+ mEventThread = new EventThread(vsyncSrc);
+ sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
+ sfVsyncPhaseOffsetNs, true, "sf");
+ mSFEventThread = new EventThread(sfVsyncSrc);
+ mEventQueue.setEventThread(mSFEventThread);
+ } else {
+ sp<VSyncSource> 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<nsecs_t>(n));
+ if (mEventThread != NULL)
+ mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
return NO_ERROR;
}
case 1019: { // Modify SurfaceFlinger's phase offset
n = data.readInt32();
- mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
+ if (mSFEventThread != NULL)
+ mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
return NO_ERROR;
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 2028d67..1f7601a 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 6127cf6..e8464a3 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();