summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger')
-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
8 files changed, 190 insertions, 12 deletions
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();