summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp599
1 files changed, 337 insertions, 262 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 98277b4..ab09bfa 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -34,18 +34,21 @@
#include <binder/MemoryHeapBase.h>
#include <binder/PermissionCache.h>
+#include <gui/IDisplayEventConnection.h>
+
#include <utils/String8.h>
#include <utils/String16.h>
#include <utils/StopWatch.h>
#include <ui/GraphicBufferAllocator.h>
-#include <ui/GraphicLog.h>
#include <ui/PixelFormat.h>
#include <pixelflinger/pixelflinger.h>
#include <GLES/gl.h>
#include "clz.h"
+#include "DisplayEventConnection.h"
+#include "EventThread.h"
#include "GLExtensions.h"
#include "DdmConnection.h"
#include "Layer.h"
@@ -56,15 +59,9 @@
#include "DisplayHardware/DisplayHardware.h"
#include "DisplayHardware/HWComposer.h"
+#include <private/android_filesystem_config.h>
#include <private/surfaceflinger/SharedBufferStack.h>
-/* ideally AID_GRAPHICS would be in a semi-public header
- * or there would be a way to map a user/group name to its id
- */
-#ifndef AID_GRAPHICS
-#define AID_GRAPHICS 1003
-#endif
-
#define EGL_VERSION_HW_ANDROID 0x3143
#define DISPLAY_COUNT 1
@@ -128,11 +125,34 @@ void SurfaceFlinger::init()
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
}
+void SurfaceFlinger::onFirstRef()
+{
+ mEventQueue.init(this);
+
+ run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
+
+ // Wait for the main thread to be done with its initialization
+ mReadyToRunBarrier.wait();
+}
+
+
SurfaceFlinger::~SurfaceFlinger()
{
glDeleteTextures(1, &mWormholeTexName);
}
+void SurfaceFlinger::binderDied(const wp<IBinder>& who)
+{
+ // the window manager died on us. prepare its eulogy.
+
+ // reset screen orientation
+ Vector<ComposerState> state;
+ setTransactionState(state, eOrientationDefault, 0);
+
+ // restart the boot-animation
+ property_set("ctl.start", "bootanim");
+}
+
sp<IMemoryHeap> SurfaceFlinger::getCblk() const
{
return mServerHeap;
@@ -186,25 +206,6 @@ void SurfaceFlinger::bootFinished()
property_set("ctl.stop", "bootanim");
}
-void SurfaceFlinger::binderDied(const wp<IBinder>& who)
-{
- // the window manager died on us. prepare its eulogy.
-
- // reset screen orientation
- setOrientation(0, eOrientationDefault, 0);
-
- // restart the boot-animation
- property_set("ctl.start", "bootanim");
-}
-
-void SurfaceFlinger::onFirstRef()
-{
- run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
-
- // Wait for the main thread to be done with its initialization
- mReadyToRunBarrier.wait();
-}
-
static inline uint16_t pack565(int r, int g, int b) {
return (r<<11)|(g<<5)|b;
}
@@ -295,12 +296,18 @@ status_t SurfaceFlinger::readyToRun()
// put the origin in the left-bottom corner
glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
- mReadyToRunBarrier.open();
+
+ // start the EventThread
+ mEventThread = new EventThread(this);
+ mEventQueue.setEventThread(mEventThread);
+ hw.startSleepManagement();
/*
* We're now ready to accept clients...
*/
+ mReadyToRunBarrier.open();
+
// start boot animation
property_set("ctl.start", "bootanim");
@@ -308,29 +315,6 @@ status_t SurfaceFlinger::readyToRun()
}
// ----------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#pragma mark Events Handler
-#endif
-
-void SurfaceFlinger::waitForEvent()
-{
- while (true) {
- nsecs_t timeout = -1;
- sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
- if (msg != 0) {
- switch (msg->what) {
- case MessageQueue::INVALIDATE:
- // invalidate message, just return to the main loop
- return;
- }
- }
- }
-}
-
-void SurfaceFlinger::signalEvent() {
- mEventQueue.invalidate();
-}
bool SurfaceFlinger::authenticateSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture) const {
@@ -373,92 +357,121 @@ bool SurfaceFlinger::authenticateSurfaceTexture(
return false;
}
+// ----------------------------------------------------------------------------
+
+sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
+ return mEventThread->createEventConnection();
+}
+
+// ----------------------------------------------------------------------------
+
+void SurfaceFlinger::waitForEvent() {
+ mEventQueue.waitMessage();
+}
+
+void SurfaceFlinger::signalTransaction() {
+ mEventQueue.invalidate();
+}
+
+void SurfaceFlinger::signalLayerUpdate() {
+ mEventQueue.invalidate();
+}
+
+void SurfaceFlinger::signalRefresh() {
+ mEventQueue.refresh();
+}
+
status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
- nsecs_t reltime, uint32_t flags)
-{
- return mEventQueue.postMessage(msg, reltime, flags);
+ nsecs_t reltime, uint32_t flags) {
+ return mEventQueue.postMessage(msg, reltime);
}
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
- nsecs_t reltime, uint32_t flags)
-{
- status_t res = mEventQueue.postMessage(msg, reltime, flags);
+ nsecs_t reltime, uint32_t flags) {
+ status_t res = mEventQueue.postMessage(msg, reltime);
if (res == NO_ERROR) {
msg->wait();
}
return res;
}
-// ----------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#pragma mark Main loop
-#endif
-
bool SurfaceFlinger::threadLoop()
{
waitForEvent();
+ return true;
+}
- // check for transactions
- if (UNLIKELY(mConsoleSignals)) {
- handleConsoleEvents();
- }
-
- // if we're in a global transaction, don't do anything.
- const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
- uint32_t transactionFlags = peekTransactionFlags(mask);
- if (UNLIKELY(transactionFlags)) {
- handleTransaction(transactionFlags);
- }
+void SurfaceFlinger::onMessageReceived(int32_t what)
+{
+ switch (what) {
+ case MessageQueue::REFRESH: {
+// case MessageQueue::INVALIDATE: {
+ // check for transactions
+ if (CC_UNLIKELY(mConsoleSignals)) {
+ handleConsoleEvents();
+ }
- // post surfaces (if needed)
- handlePageFlip();
+ // if we're in a global transaction, don't do anything.
+ const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
+ uint32_t transactionFlags = peekTransactionFlags(mask);
+ if (CC_UNLIKELY(transactionFlags)) {
+ handleTransaction(transactionFlags);
+ }
- if (mDirtyRegion.isEmpty()) {
- // nothing new to do.
- return true;
- }
+ // post surfaces (if needed)
+ handlePageFlip();
- if (UNLIKELY(mHwWorkListDirty)) {
- // build the h/w work list
- handleWorkList();
- }
+// signalRefresh();
+//
+// } break;
+//
+// case MessageQueue::REFRESH: {
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- if (LIKELY(hw.canDraw())) {
- // repaint the framebuffer (if needed)
+ handleRefresh();
- const int index = hw.getCurrentBufferIndex();
- GraphicLog& logger(GraphicLog::getInstance());
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
- logger.log(GraphicLog::SF_REPAINT, index);
- handleRepaint();
+// if (mDirtyRegion.isEmpty()) {
+// return;
+// }
- // inform the h/w that we're done compositing
- logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
- hw.compositionComplete();
+ if (CC_UNLIKELY(mHwWorkListDirty)) {
+ // build the h/w work list
+ handleWorkList();
+ }
- logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
- postFramebuffer();
+ if (CC_LIKELY(hw.canDraw())) {
+ // repaint the framebuffer (if needed)
+ handleRepaint();
+ // inform the h/w that we're done compositing
+ hw.compositionComplete();
+ postFramebuffer();
+ } else {
+ // pretend we did the post
+ hw.compositionComplete();
+ }
- logger.log(GraphicLog::SF_REPAINT_DONE, index);
- } else {
- // pretend we did the post
- hw.compositionComplete();
- usleep(16667); // 60 fps period
+ } break;
}
- return true;
}
void SurfaceFlinger::postFramebuffer()
{
- // this should never happen. we do the flip anyways so we don't
- // risk to cause a deadlock with hwc
- ALOGW_IF(mSwapRegion.isEmpty(), "mSwapRegion is empty");
+ // mSwapRegion can be empty here is some cases, for instance if a hidden
+ // or fully transparent window is updating.
+ // in that case, we need to flip anyways to not risk a deadlock with
+ // h/w composer.
+
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const nsecs_t now = systemTime();
mDebugInSwapBuffers = now;
hw.flip(mSwapRegion);
+
+ size_t numLayers = mVisibleLayersSortedByZ.size();
+ for (size_t i = 0; i < numLayers; i++) {
+ mVisibleLayersSortedByZ[i]->onLayerDisplayed();
+ }
+
mLastSwapBufferTime = systemTime() - now;
mDebugInSwapBuffers = 0;
mSwapRegion.clear();
@@ -625,7 +638,7 @@ void SurfaceFlinger::computeVisibleRegions(
// handle hidden surfaces by setting the visible region to empty
- if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
+ if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
const bool translucent = !layer->isOpaque();
const Rect bounds(layer->visibleBounds());
visibleRegion.set(bounds);
@@ -725,13 +738,13 @@ void SurfaceFlinger::commitTransaction()
void SurfaceFlinger::handlePageFlip()
{
- bool visibleRegions = mVisibleRegionsDirty;
+ const DisplayHardware& hw = graphicPlane(0).displayHardware();
+ const Region screenRegion(hw.bounds());
+
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
- visibleRegions |= lockPageFlip(currentLayers);
+ const bool visibleRegions = lockPageFlip(currentLayers);
- const DisplayHardware& hw = graphicPlane(0).displayHardware();
- const Region screenRegion(hw.bounds());
- if (visibleRegions) {
+ if (visibleRegions || mVisibleRegionsDirty) {
Region opaqueRegion;
computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
@@ -778,7 +791,7 @@ void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
{
const GraphicPlane& plane(graphicPlane(0));
const Transform& planeTransform(plane.transform());
- size_t count = currentLayers.size();
+ const size_t count = currentLayers.size();
sp<LayerBase> const* layers = currentLayers.array();
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(layers[i]);
@@ -786,6 +799,23 @@ void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
}
}
+void SurfaceFlinger::handleRefresh()
+{
+ bool needInvalidate = false;
+ const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ if (layer->onPreComposition()) {
+ needInvalidate = true;
+ }
+ }
+ if (needInvalidate) {
+ signalLayerUpdate();
+ }
+}
+
+
void SurfaceFlinger::handleWorkList()
{
mHwWorkListDirty = false;
@@ -810,7 +840,7 @@ void SurfaceFlinger::handleRepaint()
// compute the invalid region
mSwapRegion.orSelf(mDirtyRegion);
- if (UNLIKELY(mDebugRegion)) {
+ if (CC_UNLIKELY(mDebugRegion)) {
debugFlashRegions();
}
@@ -964,7 +994,7 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
HWComposer& hwc(hw.getHwComposer());
const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
- if (UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
+ if (CC_UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
// should never happen unless the window manager has a bug
// draw something...
drawWormhole();
@@ -1049,7 +1079,7 @@ void SurfaceFlinger::drawWormhole() const
const int32_t width = hw.getWidth();
const int32_t height = hw.getHeight();
- if (LIKELY(!mDebugBackground)) {
+ if (CC_LIKELY(!mDebugBackground)) {
glClearColor(0,0,0,0);
Region::const_iterator it = region.begin();
Region::const_iterator const end = region.end();
@@ -1093,23 +1123,6 @@ void SurfaceFlinger::drawWormhole() const
}
}
-void SurfaceFlinger::debugShowFPS() const
-{
- static int mFrameCount;
- static int mLastFrameCount = 0;
- static nsecs_t mLastFpsTime = 0;
- static float mFps = 0;
- mFrameCount++;
- nsecs_t now = systemTime();
- nsecs_t diff = now - mLastFpsTime;
- if (diff > ms2ns(250)) {
- mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
- mLastFpsTime = now;
- mLastFrameCount = mFrameCount;
- }
- // XXX: mFPS has the value we want
- }
-
status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
{
Mutex::Autolock _l(mStateLock);
@@ -1200,7 +1213,7 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
{
uint32_t old = android_atomic_or(flags, &mTransactionFlags);
if ((old & flags)==0) { // wake the server up
- signalEvent();
+ signalTransaction();
}
return old;
}
@@ -1250,26 +1263,6 @@ void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
}
}
-int SurfaceFlinger::setOrientation(DisplayID dpy,
- int orientation, uint32_t flags)
-{
- if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
- return BAD_VALUE;
-
- Mutex::Autolock _l(mStateLock);
- if (mCurrentState.orientation != orientation) {
- if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
- mCurrentState.orientationFlags = flags;
- mCurrentState.orientation = orientation;
- setTransactionFlags(eTransactionNeeded);
- mTransactionCV.wait(mStateLock);
- } else {
- orientation = BAD_VALUE;
- }
- }
- return orientation;
-}
-
sp<ISurface> SurfaceFlinger::createSurface(
ISurfaceComposerClient::surface_data_t* params,
const String8& name,
@@ -1352,7 +1345,7 @@ sp<Layer> SurfaceFlinger::createNormalSurface(
sp<Layer> layer = new Layer(this, display, client);
status_t err = layer->setBuffers(w, h, format, flags);
- if (LIKELY(err != NO_ERROR)) {
+ if (CC_LIKELY(err != NO_ERROR)) {
ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
layer.clear();
}
@@ -1471,14 +1464,14 @@ void SurfaceFlinger::screenReleased(int dpy)
{
// this may be called by a signal handler, we can't do too much in here
android_atomic_or(eConsoleReleased, &mConsoleSignals);
- signalEvent();
+ signalTransaction();
}
void SurfaceFlinger::screenAcquired(int dpy)
{
// this may be called by a signal handler, we can't do too much in here
android_atomic_or(eConsoleAcquired, &mConsoleSignals);
- signalEvent();
+ signalTransaction();
}
status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
@@ -1494,14 +1487,6 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
IPCThreadState::self()->getCallingUid());
result.append(buffer);
} else {
-
- // 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).
@@ -1517,110 +1502,205 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
result.append(buffer);
}
- /*
- * Dump the visible layer list
- */
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
- result.append(buffer);
- for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
- layer->dump(result, buffer, SIZE);
- const Layer::State& s(layer->drawingState());
- s.transparentRegion.dump(result, "transparentRegion");
- layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
- layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
- }
-
- /*
- * Dump the layers in the purgatory
- */
+ bool dumpAll = true;
+ size_t index = 0;
+ size_t numArgs = args.size();
+ if (numArgs) {
+ dumpAll = false;
- const size_t purgatorySize = mLayerPurgatory.size();
- snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
- result.append(buffer);
- for (size_t i=0 ; i<purgatorySize ; i++) {
- const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
- layer->shortDump(result, buffer, SIZE);
- }
+ if ((index < numArgs) &&
+ (args[index] == String16("--list"))) {
+ index++;
+ listLayersLocked(args, index, result, buffer, SIZE);
+ }
- /*
- * Dump SurfaceFlinger global state
- */
+ if ((index < numArgs) &&
+ (args[index] == String16("--latency"))) {
+ index++;
+ dumpStatsLocked(args, index, result, buffer, SIZE);
+ }
- snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
- result.append(buffer);
+ if ((index < numArgs) &&
+ (args[index] == String16("--latency-clear"))) {
+ index++;
+ clearStatsLocked(args, index, result, buffer, SIZE);
+ }
+ }
- const GLExtensions& extensions(GLExtensions::getInstance());
- snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
- extensions.getVendor(),
- extensions.getRenderer(),
- extensions.getVersion());
- result.append(buffer);
+ if (dumpAll) {
+ dumpAllLocked(result, buffer, SIZE);
+ }
- snprintf(buffer, SIZE, "EGL : %s\n",
- eglQueryString(graphicPlane(0).getEGLDisplay(),
- EGL_VERSION_HW_ANDROID));
- result.append(buffer);
+ if (locked) {
+ mStateLock.unlock();
+ }
+ }
+ write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
- snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
+void SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const
+{
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ snprintf(buffer, SIZE, "%s\n", layer->getName().string());
result.append(buffer);
+ }
+}
- mWormholeRegion.dump(result, "WormholeRegion");
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- snprintf(buffer, SIZE,
- " orientation=%d, canDraw=%d\n",
- mCurrentState.orientation, hw.canDraw());
- result.append(buffer);
- snprintf(buffer, SIZE,
- " last eglSwapBuffers() time: %f us\n"
- " last transaction time : %f us\n"
- " refresh-rate : %f fps\n"
- " x-dpi : %f\n"
- " y-dpi : %f\n",
- mLastSwapBufferTime/1000.0,
- mLastTransactionTime/1000.0,
- hw.getRefreshRate(),
- hw.getDpiX(),
- hw.getDpiY());
- result.append(buffer);
+void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const
+{
+ String8 name;
+ if (index < args.size()) {
+ name = String8(args[index]);
+ index++;
+ }
- if (inSwapBuffersDuration || !locked) {
- snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",
- inSwapBuffersDuration/1000.0);
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ if (name.isEmpty()) {
+ snprintf(buffer, SIZE, "%s\n", layer->getName().string());
result.append(buffer);
}
+ if (name.isEmpty() || (name == layer->getName())) {
+ layer->dumpStats(result, buffer, SIZE);
+ }
+ }
+}
- if (inTransactionDuration || !locked) {
- snprintf(buffer, SIZE, " transaction time: %f us\n",
- inTransactionDuration/1000.0);
- result.append(buffer);
+void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const
+{
+ String8 name;
+ if (index < args.size()) {
+ name = String8(args[index]);
+ index++;
+ }
+
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ if (name.isEmpty() || (name == layer->getName())) {
+ layer->clearStats();
}
+ }
+}
- /*
- * Dump HWComposer state
- */
- HWComposer& hwc(hw.getHwComposer());
- snprintf(buffer, SIZE, " h/w composer %s and %s\n",
- hwc.initCheck()==NO_ERROR ? "present" : "not present",
- (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
- result.append(buffer);
- hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
+void SurfaceFlinger::dumpAllLocked(
+ String8& result, char* buffer, size_t SIZE) const
+{
+ // 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;
- /*
- * Dump gralloc state
- */
- const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
- alloc.dump(result);
- hw.dump(result);
+ /*
+ * Dump the visible layer list
+ */
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
+ result.append(buffer);
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ layer->dump(result, buffer, SIZE);
+ }
- if (locked) {
- mStateLock.unlock();
- }
+ /*
+ * Dump the layers in the purgatory
+ */
+
+ const size_t purgatorySize = mLayerPurgatory.size();
+ snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
+ result.append(buffer);
+ for (size_t i=0 ; i<purgatorySize ; i++) {
+ const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+ layer->shortDump(result, buffer, SIZE);
}
- write(fd, result.string(), result.size());
- return NO_ERROR;
+
+ /*
+ * Dump SurfaceFlinger global state
+ */
+
+ snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
+ result.append(buffer);
+
+ const GLExtensions& extensions(GLExtensions::getInstance());
+ snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
+ extensions.getVendor(),
+ extensions.getRenderer(),
+ extensions.getVersion());
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, "EGL : %s\n",
+ eglQueryString(graphicPlane(0).getEGLDisplay(),
+ EGL_VERSION_HW_ANDROID));
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
+ result.append(buffer);
+
+ mWormholeRegion.dump(result, "WormholeRegion");
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ snprintf(buffer, SIZE,
+ " orientation=%d, canDraw=%d\n",
+ mCurrentState.orientation, hw.canDraw());
+ result.append(buffer);
+ snprintf(buffer, SIZE,
+ " last eglSwapBuffers() time: %f us\n"
+ " last transaction time : %f us\n"
+ " transaction-flags : %08x\n"
+ " refresh-rate : %f fps\n"
+ " x-dpi : %f\n"
+ " y-dpi : %f\n",
+ mLastSwapBufferTime/1000.0,
+ mLastTransactionTime/1000.0,
+ mTransactionFlags,
+ hw.getRefreshRate(),
+ hw.getDpiX(),
+ hw.getDpiY());
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",
+ inSwapBuffersDuration/1000.0);
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, " transaction time: %f us\n",
+ inTransactionDuration/1000.0);
+ result.append(buffer);
+
+ /*
+ * VSYNC state
+ */
+ mEventThread->dump(result, buffer, SIZE);
+
+ /*
+ * Dump HWComposer state
+ */
+ HWComposer& hwc(hw.getHwComposer());
+ snprintf(buffer, SIZE, "h/w composer state:\n");
+ result.append(buffer);
+ snprintf(buffer, SIZE, " h/w composer %s and %s\n",
+ hwc.initCheck()==NO_ERROR ? "present" : "not present",
+ (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
+ result.append(buffer);
+ hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
+
+ /*
+ * Dump gralloc state
+ */
+ const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+ alloc.dump(result);
+ hw.dump(result);
}
status_t SurfaceFlinger::onTransact(
@@ -1665,7 +1745,7 @@ status_t SurfaceFlinger::onTransact(
status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
+ if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
@@ -1696,11 +1776,6 @@ status_t SurfaceFlinger::onTransact(
setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
return NO_ERROR;
}
- case 1006:{ // enable/disable GraphicLog
- int enabled = data.readInt32();
- GraphicLog::getInstance().setEnabled(enabled);
- return NO_ERROR;
- }
case 1008: // toggle use of hw composer
n = data.readInt32();
mDebugDisableHWC = n ? 1 : 0;
@@ -1734,7 +1809,7 @@ void SurfaceFlinger::repaintEverything() {
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const Rect bounds(hw.getBounds());
setInvalidateRegion(Region(bounds));
- signalEvent();
+ signalTransaction();
}
void SurfaceFlinger::setInvalidateRegion(const Region& reg) {
@@ -2210,7 +2285,7 @@ status_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
// make sure to redraw the whole screen when the animation is done
mDirtyRegion.set(hw.bounds());
- signalEvent();
+ signalTransaction();
return NO_ERROR;
}
@@ -2250,7 +2325,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
status_t result = PERMISSION_DENIED;
// only one display supported for now
- if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+ if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
return BAD_VALUE;
if (!GLExtensions::getInstance().haveFramebufferObject())
@@ -2372,7 +2447,7 @@ status_t SurfaceFlinger::captureScreen(DisplayID dpy,
uint32_t minLayerZ, uint32_t maxLayerZ)
{
// only one display supported for now
- if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+ if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
return BAD_VALUE;
if (!GLExtensions::getInstance().haveFramebufferObject())
@@ -2500,7 +2575,7 @@ status_t Client::onTransact(
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
const int self_pid = getpid();
- if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
+ if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
// we're called from a different process, do the real check
if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
{