summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Stoza <stoza@google.com>2015-03-23 15:50:23 -0700
committerDan Stoza <stoza@google.com>2015-04-15 13:20:01 -0700
commitee44edd0acccbf5eaa918d75737c3b65ee04fff7 (patch)
tree757e79db1df532e85418fe69af5d6e49732e6869
parent5065a55291b67f584d7b0be3fa3cfc4e29a3cd1c (diff)
downloadnative-ee44edd0acccbf5eaa918d75737c3b65ee04fff7.tar.gz
SurfaceFlinger: Pass surface damage to HWC
Passes the surface damage from the incoming SurfaceFlingerConsumer BufferQueue down to the hardware composer HAL interface, if the HWC version number is 1.5 or greater. Bug: 11239309 Change-Id: Ic4305210593874a8d6deba3319055b2b8c57e926
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp27
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h1
-rw-r--r--services/surfaceflinger/Layer.cpp23
-rw-r--r--services/surfaceflinger/Layer.h7
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp11
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h1
-rw-r--r--services/surfaceflinger/SurfaceFlingerConsumer.cpp5
-rw-r--r--services/surfaceflinger/SurfaceFlingerConsumer.h6
8 files changed, 80 insertions, 1 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 77a9a19b33..c8b36ec039 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -1020,6 +1020,21 @@ public:
SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects);
visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
}
+ virtual void setSurfaceDamage(const Region& reg) {
+ if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) {
+ return;
+ }
+ hwc_region_t& surfaceDamage = getLayer()->surfaceDamage;
+ // We encode default full-screen damage as INVALID_RECT upstream, but as
+ // 0 rects for HWComposer
+ if (reg.isRect() && reg.getBounds() == Rect::INVALID_RECT) {
+ surfaceDamage.numRects = 0;
+ surfaceDamage.rects = NULL;
+ return;
+ }
+ SharedBuffer const* sb = reg.getSharedBuffer(&surfaceDamage.numRects);
+ surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
+ }
virtual void setSidebandStream(const sp<NativeHandle>& stream) {
ALOG_ASSERT(stream->handle() != NULL);
getLayer()->compositionType = HWC_SIDEBAND;
@@ -1050,6 +1065,18 @@ public:
}
getLayer()->acquireFenceFd = -1;
+
+ if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) {
+ return;
+ }
+
+ hwc_region_t& surfaceDamage = getLayer()->surfaceDamage;
+ sb = SharedBuffer::bufferFromData(surfaceDamage.rects);
+ if (sb) {
+ sb->release();
+ surfaceDamage.numRects = 0;
+ surfaceDamage.rects = NULL;
+ }
}
};
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index a62ac5c652..28d8c6534b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -168,6 +168,7 @@ public:
virtual void setFrame(const Rect& frame) = 0;
virtual void setCrop(const FloatRect& crop) = 0;
virtual void setVisibleRegionScreen(const Region& reg) = 0;
+ virtual void setSurfaceDamage(const Region& reg) = 0;
virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0;
virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
virtual void setAcquireFenceFd(int fenceFd) = 0;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2ac4765a52..7bb7529edc 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -513,6 +513,16 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
layer.setVisibleRegionScreen(visible);
+ // Pass full-surface damage down untouched
+ if (surfaceDamageRegion.isRect() &&
+ surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
+ layer.setSurfaceDamage(surfaceDamageRegion);
+ } else {
+ Region surfaceDamage =
+ tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
+ layer.setSurfaceDamage(surfaceDamage);
+ }
+
if (mSidebandStream.get()) {
layer.setSidebandStream(mSidebandStream);
} else {
@@ -1034,6 +1044,18 @@ bool Layer::setLayerStack(uint32_t layerStack) {
return true;
}
+void Layer::useSurfaceDamage() {
+ if (mFlinger->mForceFullDamage) {
+ surfaceDamageRegion = Region::INVALID_REGION;
+ } else {
+ surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
+ }
+}
+
+void Layer::useEmptyDamage() {
+ surfaceDamageRegion.clear();
+}
+
// ----------------------------------------------------------------------------
// pageflip handling...
// ----------------------------------------------------------------------------
@@ -1349,6 +1371,7 @@ void Layer::dump(String8& result, Colorizer& colorizer) const
s.activeTransparentRegion.dump(result, "transparentRegion");
visibleRegion.dump(result, "visibleRegion");
+ surfaceDamageRegion.dump(result, "surfaceDamageRegion");
sp<Client> client(mClientRef.promote());
result.appendFormat( " "
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 424c03ed38..46c17e5d17 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -76,6 +76,7 @@ public:
Region visibleRegion;
Region coveredRegion;
Region visibleNonTransparentRegion;
+ Region surfaceDamageRegion;
// Layer serial number. This gives layers an explicit ordering, so we
// have a stable sort order when their layer stack and Z-order are
@@ -137,6 +138,12 @@ public:
bool setCrop(const Rect& crop);
bool setLayerStack(uint32_t layerStack);
+ // If we have received a new buffer this frame, we will pass its surface
+ // damage down to hardware composer. Otherwise, we must send a region with
+ // one empty rect.
+ void useSurfaceDamage();
+ void useEmptyDamage();
+
uint32_t getTransactionFlags(uint32_t flags);
uint32_t setTransactionFlags(uint32_t flags);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9dc140efd9..f967c9d891 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -145,6 +145,7 @@ SurfaceFlinger::SurfaceFlinger()
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
+ mForceFullDamage(false),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mDaltonize(false),
@@ -1725,12 +1726,17 @@ bool SurfaceFlinger::handlePageFlip()
frameQueued = true;
if (layer->shouldPresentNow(mPrimaryDispSync)) {
layersWithQueuedFrames.push_back(layer.get());
+ } else {
+ layer->useEmptyDamage();
}
+ } else {
+ layer->useEmptyDamage();
}
}
for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
Layer* layer = layersWithQueuedFrames[i];
const Region dirty(layer->latchBuffer(visibleRegions));
+ layer->useSurfaceDamage();
const Layer::State& s(layer->getDrawingState());
invalidateLayerStack(s.layerStack, dirty);
}
@@ -2876,6 +2882,11 @@ status_t SurfaceFlinger::onTransact(
mPrimaryDispSync.setRefreshSkipCount(n);
return NO_ERROR;
}
+ case 1017: {
+ n = data.readInt32();
+ mForceFullDamage = static_cast<bool>(n);
+ return NO_ERROR;
+ }
}
}
return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4deb815521..a06d1be1b6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -469,6 +469,7 @@ private:
volatile nsecs_t mDebugInTransaction;
nsecs_t mLastTransactionTime;
bool mBootFinished;
+ bool mForceFullDamage;
// these are thread safe
mutable MessageQueue mEventQueue;
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index abf39932f3..19c497a5d7 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -108,6 +108,7 @@ status_t SurfaceFlingerConsumer::acquireBufferLocked(BufferItem* item,
status_t result = GLConsumer::acquireBufferLocked(item, presentWhen);
if (result == NO_ERROR) {
mTransformToDisplayInverse = item->mTransformToDisplayInverse;
+ mSurfaceDamage = item->mSurfaceDamage;
}
return result;
}
@@ -116,6 +117,10 @@ bool SurfaceFlingerConsumer::getTransformToDisplayInverse() const {
return mTransformToDisplayInverse;
}
+const Region& SurfaceFlingerConsumer::getSurfaceDamage() const {
+ return mSurfaceDamage;
+}
+
sp<NativeHandle> SurfaceFlingerConsumer::getSidebandStream() const {
return mConsumer->getSidebandStream();
}
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index d1cf9b9993..1aaba18843 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -35,7 +35,7 @@ public:
SurfaceFlingerConsumer(const sp<IGraphicBufferConsumer>& consumer,
uint32_t tex)
: GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false),
- mTransformToDisplayInverse(false)
+ mTransformToDisplayInverse(false), mSurfaceDamage()
{}
class BufferRejecter {
@@ -60,6 +60,7 @@ public:
// must be called from SF main thread
bool getTransformToDisplayInverse() const;
+ const Region& getSurfaceDamage() const;
// Sets the contents changed listener. This should be used instead of
// ConsumerBase::setFrameAvailableListener().
@@ -78,6 +79,9 @@ private:
// it is displayed onto. This is applied after GLConsumer::mCurrentTransform.
// This must be set/read from SurfaceFlinger's main thread.
bool mTransformToDisplayInverse;
+
+ // The portion of this surface that has changed since the previous frame
+ Region mSurfaceDamage;
};
// ----------------------------------------------------------------------------