diff options
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r-- | services/surfaceflinger/Android.mk | 9 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp | 10 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayUtils.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp | 122 | ||||
-rw-r--r-- | services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.h | 14 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 31 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/main_surfaceflinger.cpp | 7 |
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(); |