Signed-off-by: Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de>
This commit is contained in:
Wolfgang Wiedmeyer 2016-03-18 02:11:06 +01:00
commit dcadad708a
No known key found for this signature in database
GPG Key ID: 5816A24C10757FC4
20 changed files with 292 additions and 75 deletions

View File

@ -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" },

View File

@ -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);

View File

@ -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) {

View File

@ -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 },

View File

@ -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);

View File

@ -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.

View File

@ -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 }
};

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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() {

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -471,6 +471,7 @@ private:
void logFrameStats();
void dumpStaticScreenStats(String8& result) const;
virtual void dumpDrawCycle(bool /* prePrepare */ ) { }
/* ------------------------------------------------------------------------
* Attributes

View File

@ -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();