am 686c5be4: am 6b9454d1: SurfaceFlinger: Do less work when using PTS
* commit '686c5be4722dce02ae8e5580d6677f1eeea22464': SurfaceFlinger: Do less work when using PTS
This commit is contained in:
commit
e8e23c8b79
|
@ -34,6 +34,7 @@
|
||||||
#include <ui/GraphicBuffer.h>
|
#include <ui/GraphicBuffer.h>
|
||||||
#include <ui/PixelFormat.h>
|
#include <ui/PixelFormat.h>
|
||||||
|
|
||||||
|
#include <gui/BufferItem.h>
|
||||||
#include <gui/Surface.h>
|
#include <gui/Surface.h>
|
||||||
|
|
||||||
#include "clz.h"
|
#include "clz.h"
|
||||||
|
@ -158,11 +159,26 @@ void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layer::onFrameAvailable(const BufferItem& /* item */) {
|
void Layer::onFrameAvailable(const BufferItem& item) {
|
||||||
|
// Add this buffer from our internal queue tracker
|
||||||
|
{ // Autolock scope
|
||||||
|
Mutex::Autolock lock(mQueueItemLock);
|
||||||
|
mQueueItems.push_back(item);
|
||||||
|
}
|
||||||
|
|
||||||
android_atomic_inc(&mQueuedFrames);
|
android_atomic_inc(&mQueuedFrames);
|
||||||
mFlinger->signalLayerUpdate();
|
mFlinger->signalLayerUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Layer::onFrameReplaced(const BufferItem& item) {
|
||||||
|
Mutex::Autolock lock(mQueueItemLock);
|
||||||
|
if (mQueueItems.empty()) {
|
||||||
|
ALOGE("Can't replace a frame on an empty queue");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mQueueItems.editItemAt(0) = item;
|
||||||
|
}
|
||||||
|
|
||||||
void Layer::onSidebandStreamChanged() {
|
void Layer::onSidebandStreamChanged() {
|
||||||
if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
|
if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
|
||||||
// mSidebandStreamChanged was false
|
// mSidebandStreamChanged was false
|
||||||
|
@ -1012,6 +1028,14 @@ bool Layer::setLayerStack(uint32_t layerStack) {
|
||||||
// pageflip handling...
|
// pageflip handling...
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool Layer::shouldPresentNow(const DispSync& dispSync) const {
|
||||||
|
Mutex::Autolock lock(mQueueItemLock);
|
||||||
|
nsecs_t expectedPresent =
|
||||||
|
mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
|
||||||
|
return mQueueItems.empty() ?
|
||||||
|
false : mQueueItems[0].mTimestamp < expectedPresent;
|
||||||
|
}
|
||||||
|
|
||||||
bool Layer::onPreComposition() {
|
bool Layer::onPreComposition() {
|
||||||
mRefreshPending = false;
|
mRefreshPending = false;
|
||||||
return mQueuedFrames > 0 || mSidebandStreamChanged;
|
return mQueuedFrames > 0 || mSidebandStreamChanged;
|
||||||
|
@ -1201,6 +1225,12 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
|
||||||
return outDirtyRegion;
|
return outDirtyRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove this buffer from our internal queue tracker
|
||||||
|
{ // Autolock scope
|
||||||
|
Mutex::Autolock lock(mQueueItemLock);
|
||||||
|
mQueueItems.removeAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Decrement the queued-frames count. Signal another event if we
|
// Decrement the queued-frames count. Signal another event if we
|
||||||
// have more frames pending.
|
// have more frames pending.
|
||||||
if (android_atomic_dec(&mQueuedFrames) > 1) {
|
if (android_atomic_dec(&mQueuedFrames) > 1) {
|
||||||
|
|
|
@ -210,6 +210,8 @@ public:
|
||||||
void onLayerDisplayed(const sp<const DisplayDevice>& hw,
|
void onLayerDisplayed(const sp<const DisplayDevice>& hw,
|
||||||
HWComposer::HWCLayerInterface* layer);
|
HWComposer::HWCLayerInterface* layer);
|
||||||
|
|
||||||
|
bool shouldPresentNow(const DispSync& dispSync) const;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* called before composition.
|
* called before composition.
|
||||||
* returns true if the layer has pending updates.
|
* returns true if the layer has pending updates.
|
||||||
|
@ -331,6 +333,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
|
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
|
||||||
virtual void onFrameAvailable(const BufferItem& item);
|
virtual void onFrameAvailable(const BufferItem& item);
|
||||||
|
virtual void onFrameReplaced(const BufferItem& item);
|
||||||
virtual void onSidebandStreamChanged();
|
virtual void onSidebandStreamChanged();
|
||||||
|
|
||||||
void commitTransaction();
|
void commitTransaction();
|
||||||
|
@ -403,6 +406,10 @@ private:
|
||||||
|
|
||||||
// This layer can be a cursor on some displays.
|
// This layer can be a cursor on some displays.
|
||||||
bool mPotentialCursor;
|
bool mPotentialCursor;
|
||||||
|
|
||||||
|
// Local copy of the queued contents of the incoming BufferQueue
|
||||||
|
mutable Mutex mQueueItemLock;
|
||||||
|
Vector<BufferItem> mQueueItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -828,30 +828,39 @@ void SurfaceFlinger::eventControl(int disp, int event, int enabled) {
|
||||||
void SurfaceFlinger::onMessageReceived(int32_t what) {
|
void SurfaceFlinger::onMessageReceived(int32_t what) {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
switch (what) {
|
switch (what) {
|
||||||
case MessageQueue::TRANSACTION:
|
case MessageQueue::TRANSACTION: {
|
||||||
handleMessageTransaction();
|
handleMessageTransaction();
|
||||||
break;
|
break;
|
||||||
case MessageQueue::INVALIDATE:
|
}
|
||||||
handleMessageTransaction();
|
case MessageQueue::INVALIDATE: {
|
||||||
handleMessageInvalidate();
|
bool refreshNeeded = handleMessageTransaction();
|
||||||
signalRefresh();
|
refreshNeeded |= handleMessageInvalidate();
|
||||||
break;
|
if (refreshNeeded) {
|
||||||
case MessageQueue::REFRESH:
|
// Signal a refresh if a transaction modified the window state or if
|
||||||
handleMessageRefresh();
|
// a new buffer was latched
|
||||||
break;
|
signalRefresh();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MessageQueue::REFRESH: {
|
||||||
|
handleMessageRefresh();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::handleMessageTransaction() {
|
bool SurfaceFlinger::handleMessageTransaction() {
|
||||||
uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
|
uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
|
||||||
if (transactionFlags) {
|
if (transactionFlags) {
|
||||||
handleTransaction(transactionFlags);
|
handleTransaction(transactionFlags);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::handleMessageInvalidate() {
|
bool SurfaceFlinger::handleMessageInvalidate() {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
handlePageFlip();
|
return handlePageFlip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::handleMessageRefresh() {
|
void SurfaceFlinger::handleMessageRefresh() {
|
||||||
|
@ -1686,12 +1695,13 @@ void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::handlePageFlip()
|
bool SurfaceFlinger::handlePageFlip()
|
||||||
{
|
{
|
||||||
Region dirtyRegion;
|
Region dirtyRegion;
|
||||||
|
|
||||||
bool visibleRegions = false;
|
bool visibleRegions = false;
|
||||||
const LayerVector& layers(mDrawingState.layersSortedByZ);
|
const LayerVector& layers(mDrawingState.layersSortedByZ);
|
||||||
|
bool frameQueued = false;
|
||||||
|
|
||||||
// Store the set of layers that need updates. This set must not change as
|
// Store the set of layers that need updates. This set must not change as
|
||||||
// buffers are being latched, as this could result in a deadlock.
|
// buffers are being latched, as this could result in a deadlock.
|
||||||
|
@ -1705,8 +1715,12 @@ void SurfaceFlinger::handlePageFlip()
|
||||||
Vector<Layer*> layersWithQueuedFrames;
|
Vector<Layer*> layersWithQueuedFrames;
|
||||||
for (size_t i = 0, count = layers.size(); i<count ; i++) {
|
for (size_t i = 0, count = layers.size(); i<count ; i++) {
|
||||||
const sp<Layer>& layer(layers[i]);
|
const sp<Layer>& layer(layers[i]);
|
||||||
if (layer->hasQueuedFrame())
|
if (layer->hasQueuedFrame()) {
|
||||||
layersWithQueuedFrames.push_back(layer.get());
|
frameQueued = true;
|
||||||
|
if (layer->shouldPresentNow(mPrimaryDispSync)) {
|
||||||
|
layersWithQueuedFrames.push_back(layer.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
|
for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
|
||||||
Layer* layer = layersWithQueuedFrames[i];
|
Layer* layer = layersWithQueuedFrames[i];
|
||||||
|
@ -1716,6 +1730,16 @@ void SurfaceFlinger::handlePageFlip()
|
||||||
}
|
}
|
||||||
|
|
||||||
mVisibleRegionsDirty |= visibleRegions;
|
mVisibleRegionsDirty |= visibleRegions;
|
||||||
|
|
||||||
|
// If we will need to wake up at some time in the future to deal with a
|
||||||
|
// queued frame that shouldn't be displayed during this vsync period, wake
|
||||||
|
// up during the next vsync period to check again.
|
||||||
|
if (frameQueued && layersWithQueuedFrames.empty()) {
|
||||||
|
signalLayerUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only continue with the refresh if there is actually new work to do
|
||||||
|
return !layersWithQueuedFrames.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::invalidateHwcGeometry()
|
void SurfaceFlinger::invalidateHwcGeometry()
|
||||||
|
|
|
@ -247,8 +247,12 @@ private:
|
||||||
// called on the main thread in response to setPowerMode()
|
// called on the main thread in response to setPowerMode()
|
||||||
void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode);
|
void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode);
|
||||||
|
|
||||||
void handleMessageTransaction();
|
// Returns whether the transaction actually modified any state
|
||||||
void handleMessageInvalidate();
|
bool handleMessageTransaction();
|
||||||
|
|
||||||
|
// Returns whether a new buffer has been latched (see handlePageFlip())
|
||||||
|
bool handleMessageInvalidate();
|
||||||
|
|
||||||
void handleMessageRefresh();
|
void handleMessageRefresh();
|
||||||
|
|
||||||
void handleTransaction(uint32_t transactionFlags);
|
void handleTransaction(uint32_t transactionFlags);
|
||||||
|
@ -256,10 +260,11 @@ private:
|
||||||
|
|
||||||
void updateCursorAsync();
|
void updateCursorAsync();
|
||||||
|
|
||||||
/* handlePageFilp: this is were we latch a new buffer
|
/* handlePageFlip - latch a new buffer if available and compute the dirty
|
||||||
* if available and compute the dirty region.
|
* region. Returns whether a new buffer has been latched, i.e., whether it
|
||||||
|
* is necessary to perform a refresh during this vsync.
|
||||||
*/
|
*/
|
||||||
void handlePageFlip();
|
bool handlePageFlip();
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
* Transactions
|
* Transactions
|
||||||
|
|
|
@ -67,9 +67,9 @@ public:
|
||||||
|
|
||||||
sp<NativeHandle> getSidebandStream() const;
|
sp<NativeHandle> getSidebandStream() const;
|
||||||
|
|
||||||
private:
|
|
||||||
nsecs_t computeExpectedPresent(const DispSync& dispSync);
|
nsecs_t computeExpectedPresent(const DispSync& dispSync);
|
||||||
|
|
||||||
|
private:
|
||||||
virtual void onSidebandStreamChanged();
|
virtual void onSidebandStreamChanged();
|
||||||
|
|
||||||
wp<ContentsChangedListener> mContentsChangedListener;
|
wp<ContentsChangedListener> mContentsChangedListener;
|
||||||
|
|
Loading…
Reference in New Issue