summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp136
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h131
-rw-r--r--services/surfaceflinger/Layer.cpp34
-rw-r--r--services/surfaceflinger/Layer.h4
-rw-r--r--services/surfaceflinger/LayerBase.cpp42
-rw-r--r--services/surfaceflinger/LayerBase.h6
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp33
7 files changed, 286 insertions, 100 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 65763db..ce63ee7 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -43,6 +43,19 @@
namespace android {
// ---------------------------------------------------------------------------
+struct HWComposer::cb_context {
+ struct callbacks : public hwc_procs_t {
+ // these are here to facilitate the transition when adding
+ // new callbacks (an implementation can check for NULL before
+ // calling a new callback).
+ void (*zero[4])(void);
+ };
+ callbacks procs;
+ HWComposer* hwc;
+};
+
+// ---------------------------------------------------------------------------
+
HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,
EventHandler& handler,
@@ -51,6 +64,7 @@ HWComposer::HWComposer(
mModule(0), mHwc(0), mList(0), mCapacity(0),
mNumOVLayers(0), mNumFBLayers(0),
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE),
+ mCBContext(new cb_context),
mEventHandler(handler),
mRefreshPeriod(refreshPeriod),
mVSyncCount(0), mDebugForceFakeVSync(false)
@@ -68,11 +82,11 @@ HWComposer::HWComposer(
HWC_HARDWARE_COMPOSER, strerror(-err));
if (err == 0) {
if (mHwc->registerProcs) {
- mCBContext.hwc = this;
- mCBContext.procs.invalidate = &hook_invalidate;
- mCBContext.procs.vsync = &hook_vsync;
- mHwc->registerProcs(mHwc, &mCBContext.procs);
- memset(mCBContext.procs.zero, 0, sizeof(mCBContext.procs.zero));
+ mCBContext->hwc = this;
+ mCBContext->procs.invalidate = &hook_invalidate;
+ mCBContext->procs.vsync = &hook_vsync;
+ mHwc->registerProcs(mHwc, &mCBContext->procs);
+ memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
}
if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
if (mDebugForceFakeVSync) {
@@ -102,6 +116,7 @@ HWComposer::~HWComposer() {
if (mHwc) {
hwc_close(mHwc);
}
+ delete mCBContext;
}
status_t HWComposer::initCheck() const {
@@ -230,10 +245,117 @@ size_t HWComposer::getNumLayers() const {
return mList ? mList->numHwLayers : 0;
}
-hwc_layer_t* HWComposer::getLayers() const {
- return mList ? mList->hwLayers : 0;
+/*
+ * Helper template to implement a concrete HWCLayer
+ * This holds the pointer to the concrete hwc layer type
+ * and implements the "iterable" side of HWCLayer.
+ */
+template<typename CONCRETE, typename HWCTYPE>
+class Iterable : public HWComposer::HWCLayer {
+protected:
+ HWCTYPE* const mLayerList;
+ HWCTYPE* mCurrentLayer;
+ Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
+ inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
+ inline HWCTYPE* getLayer() { return mCurrentLayer; }
+ virtual ~Iterable() { }
+private:
+ // returns a copy of ourselves
+ virtual HWComposer::HWCLayer* dup() {
+ return new CONCRETE( static_cast<const CONCRETE&>(*this) );
+ }
+ virtual status_t setLayer(size_t index) {
+ mCurrentLayer = &mLayerList[index];
+ return NO_ERROR;
+ }
+};
+
+/*
+ * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
+ * This implements the HWCLayer side of HWCIterableLayer.
+ */
+class HWCLayerVersion03 : public Iterable<HWCLayerVersion03, hwc_layer_t> {
+public:
+ HWCLayerVersion03(hwc_layer_t* layer)
+ : Iterable<HWCLayerVersion03, hwc_layer_t>(layer) { }
+
+ virtual int32_t getCompositionType() const {
+ return getLayer()->compositionType;
+ }
+ virtual uint32_t getHints() const {
+ return getLayer()->hints;
+ }
+
+ virtual void setDefaultState() {
+ getLayer()->compositionType = HWC_FRAMEBUFFER;
+ getLayer()->hints = 0;
+ getLayer()->flags = HWC_SKIP_LAYER;
+ getLayer()->transform = 0;
+ getLayer()->blending = HWC_BLENDING_NONE;
+ getLayer()->visibleRegionScreen.numRects = 0;
+ getLayer()->visibleRegionScreen.rects = NULL;
+ }
+ virtual void setSkip(bool skip) {
+ if (skip) {
+ getLayer()->flags |= HWC_SKIP_LAYER;
+ } else {
+ getLayer()->flags &= ~HWC_SKIP_LAYER;
+ }
+ }
+ virtual void setBlending(uint32_t blending) {
+ getLayer()->blending = blending;
+ }
+ virtual void setTransform(uint32_t transform) {
+ getLayer()->transform = transform;
+ }
+ virtual void setFrame(const Rect& frame) {
+ reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
+ }
+ virtual void setCrop(const Rect& crop) {
+ reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
+ }
+ virtual void setVisibleRegionScreen(const Region& reg) {
+ getLayer()->visibleRegionScreen.rects =
+ reinterpret_cast<hwc_rect_t const *>(
+ reg.getArray(&getLayer()->visibleRegionScreen.numRects));
+ }
+ virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
+ if (buffer == 0 || buffer->handle == 0) {
+ getLayer()->compositionType = HWC_FRAMEBUFFER;
+ getLayer()->flags |= HWC_SKIP_LAYER;
+ getLayer()->handle = 0;
+ } else {
+ getLayer()->handle = buffer->handle;
+ }
+ }
+};
+
+/*
+ * returns an iterator initialized at a given index in the layer list
+ */
+HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
+ if (!mList || index > mList->numHwLayers) {
+ return LayerListIterator();
+ }
+ return LayerListIterator(new HWCLayerVersion03(mList->hwLayers), index);
+}
+
+/*
+ * returns an iterator on the beginning of the layer list
+ */
+HWComposer::LayerListIterator HWComposer::begin() {
+ return getLayerIterator(0);
}
+/*
+ * returns an iterator on the end of the layer list
+ */
+HWComposer::LayerListIterator HWComposer::end() {
+ return getLayerIterator(getNumLayers());
+}
+
+
+
void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
if (mHwc && mList) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index aada3cd..cafa247 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -22,7 +22,7 @@
#include <EGL/egl.h>
-#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer_defs.h>
#include <utils/StrongPointer.h>
#include <utils/Vector.h>
@@ -31,12 +31,17 @@ extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
const struct timespec *request,
struct timespec *remain);
+struct hwc_composer_device;
+struct hwc_layer_list;
+struct hwc_procs;
+
namespace android {
// ---------------------------------------------------------------------------
class String8;
class SurfaceFlinger;
class LayerBase;
+class GraphicBuffer;
class HWComposer
{
@@ -57,9 +62,6 @@ public:
// tells the HAL what the framebuffer is
void setFrameBuffer(EGLDisplay dpy, EGLSurface sur);
- // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
- status_t createWorkList(size_t numLayers);
-
// Asks the HAL what it can do
status_t prepare() const;
@@ -72,14 +74,109 @@ public:
// release hardware resources
status_t release() const;
+ // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
+ status_t createWorkList(size_t numLayers);
+
// get the layer array created by createWorkList()
size_t getNumLayers() const;
- hwc_layer_t* getLayers() const;
// get number of layers of the given type as updated in prepare().
// type is HWC_OVERLAY or HWC_FRAMEBUFFER
size_t getLayerCount(int type) const;
+ // needed forward declarations
+ class LayerListIterator;
+
+ /*
+ * Interface to hardware composer's layers functionality.
+ * This abstracts the HAL interface to layers which can evolve in
+ * incompatible ways from one release to another.
+ * The idea is that we could extend this interface as we add
+ * features to h/w composer.
+ */
+ class HWCLayerInterface {
+ protected:
+ virtual ~HWCLayerInterface() { }
+ public:
+ virtual int32_t getCompositionType() const = 0;
+ virtual uint32_t getHints() const = 0;
+ virtual void setDefaultState() = 0;
+ virtual void setSkip(bool skip) = 0;
+ virtual void setBlending(uint32_t blending) = 0;
+ virtual void setTransform(uint32_t transform) = 0;
+ virtual void setFrame(const Rect& frame) = 0;
+ virtual void setCrop(const Rect& crop) = 0;
+ virtual void setVisibleRegionScreen(const Region& reg) = 0;
+ virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
+ };
+
+ /*
+ * Interface used to implement an iterator to a list
+ * of HWCLayer.
+ */
+ class HWCLayer : public HWCLayerInterface {
+ friend class LayerListIterator;
+ // select the layer at the given index
+ virtual status_t setLayer(size_t index) = 0;
+ virtual HWCLayer* dup() = 0;
+ static HWCLayer* copy(HWCLayer *rhs) {
+ return rhs ? rhs->dup() : NULL;
+ }
+ protected:
+ virtual ~HWCLayer() { }
+ };
+
+ /*
+ * Iterator through a HWCLayer list.
+ * This behaves more or less like a forward iterator.
+ */
+ class LayerListIterator {
+ friend struct HWComposer;
+ HWCLayer* const mLayerList;
+ size_t mIndex;
+
+ LayerListIterator() : mLayerList(NULL), mIndex(0) { }
+
+ LayerListIterator(HWCLayer* layer, size_t index)
+ : mLayerList(layer), mIndex(index) { }
+
+ // we don't allow assignment, because we don't need it for now
+ LayerListIterator& operator = (const LayerListIterator& rhs);
+
+ public:
+ // copy operators
+ LayerListIterator(const LayerListIterator& rhs)
+ : mLayerList(HWCLayer::copy(rhs.mLayerList)), mIndex(rhs.mIndex) {
+ }
+
+ ~LayerListIterator() { delete mLayerList; }
+
+ // pre-increment
+ LayerListIterator& operator++() {
+ mLayerList->setLayer(++mIndex);
+ return *this;
+ }
+
+ // dereference
+ HWCLayerInterface& operator * () { return *mLayerList; }
+ HWCLayerInterface* operator -> () { return mLayerList; }
+
+ // comparison
+ bool operator == (const LayerListIterator& rhs) const {
+ return mIndex == rhs.mIndex;
+ }
+ bool operator != (const LayerListIterator& rhs) const {
+ return !operator==(rhs);
+ }
+ };
+
+ // Returns an iterator to the beginning of the layer list
+ LayerListIterator begin();
+
+ // Returns an iterator to the end of the layer list
+ LayerListIterator end();
+
+
// Events handling ---------------------------------------------------------
enum {
@@ -111,18 +208,9 @@ public:
const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;
private:
+ LayerListIterator getLayerIterator(size_t index);
- struct callbacks : public hwc_procs_t {
- // these are here to facilitate the transition when adding
- // new callbacks (an implementation can check for NULL before
- // calling a new callback).
- void (*zero[4])(void);
- };
-
- struct cb_context {
- callbacks procs;
- HWComposer* hwc;
- };
+ struct cb_context;
static void hook_invalidate(struct hwc_procs* procs);
static void hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp);
@@ -132,14 +220,14 @@ private:
sp<SurfaceFlinger> mFlinger;
hw_module_t const* mModule;
- hwc_composer_device_t* mHwc;
- hwc_layer_list_t* mList;
+ struct hwc_composer_device* mHwc;
+ struct hwc_layer_list* mList;
size_t mCapacity;
mutable size_t mNumOVLayers;
mutable size_t mNumFBLayers;
- hwc_display_t mDpy;
- hwc_surface_t mSur;
- cb_context mCBContext;
+ EGLDisplay mDpy;
+ EGLSurface mSur;
+ cb_context* mCBContext;
EventHandler& mEventHandler;
nsecs_t mRefreshPeriod;
size_t mVSyncCount;
@@ -147,7 +235,6 @@ private:
bool mDebugForceFakeVSync;
};
-
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 4062340..890bcb4 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -259,16 +259,17 @@ Rect Layer::computeBufferCrop() const {
return crop;
}
-void Layer::setGeometry(hwc_layer_t* hwcl)
+void Layer::setGeometry(HWComposer::HWCLayerInterface& layer)
{
- LayerBaseClient::setGeometry(hwcl);
+ LayerBaseClient::setGeometry(layer);
- hwcl->flags &= ~HWC_SKIP_LAYER;
+ // enable this layer
+ layer.setSkip(false);
// we can't do alpha-fade with the hwc HAL
const State& s(drawingState());
if (s.alpha < 0xFF) {
- hwcl->flags = HWC_SKIP_LAYER;
+ layer.setSkip(true);
}
/*
@@ -288,29 +289,18 @@ void Layer::setGeometry(hwc_layer_t* hwcl)
// we can only handle simple transformation
if (finalTransform & Transform::ROT_INVALID) {
- hwcl->flags = HWC_SKIP_LAYER;
+ layer.setSkip(true);
} else {
- hwcl->transform = finalTransform;
+ layer.setTransform(finalTransform);
}
-
- Rect crop = computeBufferCrop();
- hwcl->sourceCrop.left = crop.left;
- hwcl->sourceCrop.top = crop.top;
- hwcl->sourceCrop.right = crop.right;
- hwcl->sourceCrop.bottom = crop.bottom;
+ layer.setCrop(computeBufferCrop());
}
-void Layer::setPerFrameData(hwc_layer_t* hwcl) {
+void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
const sp<GraphicBuffer>& buffer(mActiveBuffer);
- if (buffer == NULL) {
- // this can happen if the client never drew into this layer yet,
- // or if we ran out of memory. In that case, don't let
- // HWC handle it.
- hwcl->flags |= HWC_SKIP_LAYER;
- hwcl->handle = NULL;
- } else {
- hwcl->handle = buffer->handle;
- }
+ // NOTE: buffer can be NULL if the client never drew into this
+ // layer yet, or if we ran out of memory
+ layer.setBuffer(buffer);
}
void Layer::onDraw(const Region& clip) const
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 393599f..7a164aa 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -64,8 +64,8 @@ public:
bool isFixedSize() const;
// LayerBase interface
- virtual void setGeometry(hwc_layer_t* hwcl);
- virtual void setPerFrameData(hwc_layer_t* hwcl);
+ virtual void setGeometry(HWComposer::HWCLayerInterface& layer);
+ virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
virtual void onDraw(const Region& clip) const;
virtual uint32_t doTransaction(uint32_t transactionFlags);
virtual void lockPageFlip(bool& recomputeVisibleRegions);
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 16bac8f..fe15dc9 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -281,48 +281,34 @@ void LayerBase::unlockPageFlip(
const Transform& planeTransform, Region& outDirtyRegion) {
}
-void LayerBase::setGeometry(hwc_layer_t* hwcl)
+void LayerBase::setGeometry(HWComposer::HWCLayerInterface& layer)
{
- hwcl->compositionType = HWC_FRAMEBUFFER;
- hwcl->hints = 0;
- hwcl->flags = HWC_SKIP_LAYER;
- hwcl->transform = 0;
- hwcl->blending = HWC_BLENDING_NONE;
+ layer.setDefaultState();
// this gives us only the "orientation" component of the transform
const State& s(drawingState());
const uint32_t finalTransform = s.transform.getOrientation();
// we can only handle simple transformation
if (finalTransform & Transform::ROT_INVALID) {
- hwcl->flags = HWC_SKIP_LAYER;
+ layer.setTransform(0);
} else {
- hwcl->transform = finalTransform;
+ layer.setTransform(finalTransform);
}
if (!isOpaque()) {
- hwcl->blending = mPremultipliedAlpha ?
- HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
+ layer.setBlending(mPremultipliedAlpha ?
+ HWC_BLENDING_PREMULT :
+ HWC_BLENDING_COVERAGE);
}
// scaling is already applied in mTransformedBounds
- hwcl->displayFrame.left = mTransformedBounds.left;
- hwcl->displayFrame.top = mTransformedBounds.top;
- hwcl->displayFrame.right = mTransformedBounds.right;
- hwcl->displayFrame.bottom = mTransformedBounds.bottom;
- hwcl->visibleRegionScreen.rects =
- reinterpret_cast<hwc_rect_t const *>(
- visibleRegionScreen.getArray(
- &hwcl->visibleRegionScreen.numRects));
-
- hwcl->sourceCrop.left = 0;
- hwcl->sourceCrop.top = 0;
- hwcl->sourceCrop.right = mTransformedBounds.width();
- hwcl->sourceCrop.bottom = mTransformedBounds.height();
-}
-
-void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
- hwcl->compositionType = HWC_FRAMEBUFFER;
- hwcl->handle = NULL;
+ layer.setFrame(mTransformedBounds);
+ layer.setVisibleRegionScreen(visibleRegionScreen);
+ layer.setCrop(mTransformedBounds.getBounds());
+}
+
+void LayerBase::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
+ layer.setBuffer(0);
}
void LayerBase::setFiltering(bool filtering)
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index c547a40..4d5d1e4 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -32,8 +32,6 @@
#include <private/gui/LayerState.h>
-#include <hardware/hwcomposer.h>
-
#include "DisplayHardware/DisplayHardware.h"
#include "Transform.h"
@@ -116,8 +114,8 @@ public:
virtual const char* getTypeId() const { return "LayerBase"; }
- virtual void setGeometry(hwc_layer_t* hwcl);
- virtual void setPerFrameData(hwc_layer_t* hwcl);
+ virtual void setGeometry(HWComposer::HWCLayerInterface& layer);
+ virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
/**
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 61b5f71..e2c7aed 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -800,12 +800,13 @@ void SurfaceFlinger::handleWorkList()
const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
const size_t count = currentLayers.size();
hwc.createWorkList(count);
- hwc_layer_t* const cur(hwc.getLayers());
- for (size_t i=0 ; cur && i<count ; i++) {
- currentLayers[i]->setGeometry(&cur[i]);
+
+ HWComposer::LayerListIterator cur = hwc.begin();
+ const HWComposer::LayerListIterator end = hwc.end();
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
+ currentLayers[i]->setGeometry(*cur);
if (mDebugDisableHWC || mDebugRegion) {
- cur[i].compositionType = HWC_FRAMEBUFFER;
- cur[i].flags |= HWC_SKIP_LAYER;
+ cur->setSkip(true);
}
}
}
@@ -859,8 +860,10 @@ void SurfaceFlinger::setupHardwareComposer()
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer());
- hwc_layer_t* const cur(hwc.getLayers());
- if (!cur) {
+
+ HWComposer::LayerListIterator cur = hwc.begin();
+ const HWComposer::LayerListIterator end = hwc.end();
+ if (cur == end) {
return;
}
@@ -880,9 +883,9 @@ void SurfaceFlinger::setupHardwareComposer()
* update the per-frame h/w composer data for each layer
* and build the transparent region of the FB
*/
- for (size_t i=0 ; i<count ; i++) {
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
const sp<LayerBase>& layer(layers[i]);
- layer->setPerFrameData(&cur[i]);
+ layer->setPerFrameData(*cur);
}
status_t err = hwc.prepare();
ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
@@ -892,10 +895,11 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer());
- hwc_layer_t* const cur(hwc.getLayers());
+ HWComposer::LayerListIterator cur = hwc.begin();
+ const HWComposer::LayerListIterator end = hwc.end();
const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
- if (!cur || fbLayerCount) {
+ if (cur==end || fbLayerCount) {
// Never touch the framebuffer if we don't have any framebuffer layers
if (hwc.getLayerCount(HWC_OVERLAY)) {
@@ -920,13 +924,12 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
const size_t count = layers.size();
-
- for (size_t i=0 ; i<count ; i++) {
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
const sp<LayerBase>& layer(layers[i]);
const Region clip(dirty.intersect(layer->visibleRegionScreen));
if (!clip.isEmpty()) {
- if (cur && (cur[i].compositionType == HWC_OVERLAY)) {
- if (i && (cur[i].hints & HWC_HINT_CLEAR_FB)
+ if (cur->getCompositionType() == HWC_OVERLAY) {
+ if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
&& layer->isOpaque()) {
// never clear the very first layer since we're
// guaranteed the FB is already cleared