summaryrefslogtreecommitdiff
path: root/libs/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
author Android (Google) Code Review <android-gerrit@google.com> 2009-08-26 17:40:56 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2009-08-26 17:40:56 -0700
commit205c34b02f66bc6e1596e23868c4ecf57724d0e5 (patch)
treed5d82843e6f352ddee5127025da8b06be250e42e /libs/surfaceflinger/SurfaceFlinger.cpp
parent0033bfa79c385377f7bca8a11c09b2c3507a4d61 (diff)
parent9795c42e557cfa37b9fd353ef7a2a7977a77f504 (diff)
Merge change 22841 into eclair
* changes: dumpsys SurfaceFlinger will now always dump SF's state, even if SF is deadlocked (in this case the state is dumped without the proper locks held which could result to a crash)
Diffstat (limited to 'libs/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp55
1 files changed, 54 insertions, 1 deletions
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 3824024a34..a72294a2ac 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -186,6 +186,10 @@ SurfaceFlinger::SurfaceFlinger()
mFreezeDisplayTime(0),
mDebugRegion(0),
mDebugBackground(0),
+ mDebugInSwapBuffers(0),
+ mLastSwapBufferTime(0),
+ mDebugInTransaction(0),
+ mLastTransactionTime(0),
mConsoleSignals(0),
mSecureFrameBuffer(0)
{
@@ -517,7 +521,11 @@ void SurfaceFlinger::postFramebuffer()
if (!mInvalidRegion.isEmpty()) {
const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const nsecs_t now = systemTime();
+ mDebugInSwapBuffers = now;
hw.flip(mInvalidRegion);
+ mLastSwapBufferTime = systemTime() - now;
+ mDebugInSwapBuffers = 0;
mInvalidRegion.clear();
}
}
@@ -555,7 +563,11 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
{ // scope for the lock
Mutex::Autolock _l(mStateLock);
+ const nsecs_t now = systemTime();
+ mDebugInTransaction = now;
handleTransactionLocked(transactionFlags, ditchedLayers);
+ mLastTransactionTime = systemTime() - now;
+ mDebugInTransaction = 0;
}
// do this without lock held
@@ -1467,7 +1479,29 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
IPCThreadState::self()->getCallingUid());
result.append(buffer);
} else {
- Mutex::Autolock _l(mStateLock);
+
+ // figure out if we're stuck somewhere
+ const nsecs_t now = systemTime();
+ const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
+ const nsecs_t inTransaction(mDebugInTransaction);
+ nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
+ nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
+
+ // Try to get the main lock, but don't insist if we can't
+ // (this would indicate SF is stuck, but we want to be able to
+ // print something in dumpsys).
+ int retry = 3;
+ while (mStateLock.tryLock()<0 && --retry>=0) {
+ usleep(1000000);
+ }
+ const bool locked(retry >= 0);
+ if (!locked) {
+ snprintf(buffer, SIZE,
+ "SurfaceFlinger appears to be unresponsive, "
+ "dumping anyways (no locks held)\n");
+ result.append(buffer);
+ }
+
size_t s = mClientsMap.size();
char name[64];
for (size_t i=0 ; i<s ; i++) {
@@ -1538,10 +1572,29 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
mFreezeDisplay?"yes":"no", mFreezeCount,
mCurrentState.orientation, hw.canDraw());
result.append(buffer);
+ snprintf(buffer, SIZE,
+ " last eglSwapBuffers() time: %f us\n"
+ " last transaction time : %f us\n",
+ mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
+ result.append(buffer);
+ if (inSwapBuffersDuration || !locked) {
+ snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",
+ inSwapBuffersDuration/1000.0);
+ result.append(buffer);
+ }
+ if (inTransactionDuration || !locked) {
+ snprintf(buffer, SIZE, " transaction time: %f us\n",
+ inTransactionDuration/1000.0);
+ result.append(buffer);
+ }
snprintf(buffer, SIZE, " client count: %d\n", mClientsMap.size());
result.append(buffer);
const BufferAllocator& alloc(BufferAllocator::get());
alloc.dump(result);
+
+ if (locked) {
+ mStateLock.unlock();
+ }
}
write(fd, result.string(), result.size());
return NO_ERROR;