am e7d20eb0
: Merge "SurfaceFlinger: Pass surface damage to HWC"
* commit 'e7d20eb000c1d342c8f5f58011023c0eb7cea6d5': SurfaceFlinger: Pass surface damage to HWC
This commit is contained in:
commit
40b2a8b48c
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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( " "
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -469,6 +469,7 @@ private:
|
||||
volatile nsecs_t mDebugInTransaction;
|
||||
nsecs_t mLastTransactionTime;
|
||||
bool mBootFinished;
|
||||
bool mForceFullDamage;
|
||||
|
||||
// these are thread safe
|
||||
mutable MessageQueue mEventQueue;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user