summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/Layer.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-01-31 18:24:27 -0800
committerMathias Agopian <mathias@google.com>2012-02-01 20:43:06 -0800
commit9a9dbd5921b6c138673eea206a1a067a01928cb5 (patch)
tree3505a7dd951f0fa46d0245aa9d84a354a35e3857 /services/surfaceflinger/Layer.cpp
parent26daa02bdb0c62f8162ad8d4d771cabce8644b4a (diff)
downloadframeworks_base-9a9dbd5921b6c138673eea206a1a067a01928cb5.zip
frameworks_base-9a9dbd5921b6c138673eea206a1a067a01928cb5.tar.gz
frameworks_base-9a9dbd5921b6c138673eea206a1a067a01928cb5.tar.bz2
separate transactions from updates
with this changes, SF transactions are handled as soon as possible but do not trigger updates. the update is delayed until the next vsync. this allows us to work much better without requiring triple-buffering. Change-Id: I1fa10794d0cf742129f0877698b7b1e1f2ec7401
Diffstat (limited to 'services/surfaceflinger/Layer.cpp')
-rw-r--r--services/surfaceflinger/Layer.cpp39
1 files changed, 30 insertions, 9 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 9c04d59..64f72d5 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -55,6 +55,7 @@ Layer::Layer(SurfaceFlinger* flinger,
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
+ mRefreshPending(0),
mFrameLatencyNeeded(false),
mFrameLatencyOffset(0),
mFormat(PIXEL_FORMAT_NONE),
@@ -97,12 +98,7 @@ void Layer::onFirstRef()
mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);
mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
mSurfaceTexture->setSynchronousMode(true);
-#ifdef USE_TRIPLE_BUFFERING
-#warning "using triple buffering"
- mSurfaceTexture->setBufferCountServer(3);
-#else
mSurfaceTexture->setBufferCountServer(2);
-#endif
}
Layer::~Layer()
@@ -113,7 +109,7 @@ Layer::~Layer()
void Layer::onFrameQueued() {
android_atomic_inc(&mQueuedFrames);
- mFlinger->signalEvent();
+ mFlinger->signalLayerUpdate();
}
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
@@ -407,16 +403,37 @@ bool Layer::isCropped() const {
// pageflip handling...
// ----------------------------------------------------------------------------
+bool Layer::onPreComposition()
+{
+ // if there was more than one pending update, request a refresh
+ if (mRefreshPending >= 2) {
+ mRefreshPending = 0;
+ return true;
+ }
+ mRefreshPending = 0;
+ return false;
+}
+
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
if (mQueuedFrames > 0) {
+
+ // if we've already called updateTexImage() without going through
+ // a composition step, we have to skip this layer at this point
+ // because we cannot call updateTeximage() without a corresponding
+ // compositionComplete() call.
+ // we'll trigger an update in onPreComposition().
+ if (mRefreshPending++) {
+ return;
+ }
+
// Capture the old state of the layer for comparisons later
const bool oldOpacity = isOpaque();
sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
// signal another event if we have more frames pending
if (android_atomic_dec(&mQueuedFrames) > 1) {
- mFlinger->signalEvent();
+ mFlinger->signalLayerUpdate();
}
if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
@@ -519,6 +536,10 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
void Layer::unlockPageFlip(
const Transform& planeTransform, Region& outDirtyRegion)
{
+ if (mRefreshPending >= 2) {
+ return;
+ }
+
Region dirtyRegion(mPostedDirtyRegion);
if (!dirtyRegion.isEmpty()) {
mPostedDirtyRegion.clear();
@@ -552,9 +573,9 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
snprintf(buffer, SIZE,
" "
"format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
- " transform-hint=0x%02x, queued-frames=%d\n",
+ " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
mFormat, w0, h0, s0,f0,
- getTransformHint(), mQueuedFrames);
+ getTransformHint(), mQueuedFrames, mRefreshPending);
result.append(buffer);