diff options
author | Eric Hassold <hassold@google.com> | 2011-02-10 14:41:26 -0800 |
---|---|---|
committer | Eric Hassold <hassold@google.com> | 2011-02-15 16:20:03 -0800 |
commit | 2ae32bdd7579ca6a9a336c74613185b21d39c8d4 (patch) | |
tree | 54057737faafcd5afb7c1d2469b697b9a242a5af /services/surfaceflinger | |
parent | 302b9884b3f0ecc96cc618643835d415e474cac3 (diff) | |
download | frameworks_base-2ae32bdd7579ca6a9a336c74613185b21d39c8d4.zip frameworks_base-2ae32bdd7579ca6a9a336c74613185b21d39c8d4.tar.gz frameworks_base-2ae32bdd7579ca6a9a336c74613185b21d39c8d4.tar.bz2 |
Correctly handle translucency of device-specific pixel formats
Check requested format for device-specific formats, and assume (as
documented in libhardware/include/hardware/hardware.h) this is opaque
layer so no blending is necessary.
Bug: 3215931
Change-Id: Ib4dff8060ac522d201ff1e74807ac340c17d3fa7
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 48 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 3 |
2 files changed, 50 insertions, 1 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index fde8e67..aed3fd4 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -344,6 +344,45 @@ void Layer::onDraw(const Region& clip) const drawWithOpenGL(clip, tex); } +// As documented in libhardware header, formats in the range +// 0x100 - 0x1FF are specific to the HAL implementation, and +// are known to have no alpha channel +// TODO: move definition for device-specific range into +// hardware.h, instead of using hard-coded values here. +#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) + +bool Layer::needsBlending(const sp<GraphicBuffer>& buffer) const +{ + // If buffers where set with eOpaque flag, all buffers are known to + // be opaque without having to check their actual format + if (mNeedsBlending && buffer != NULL) { + PixelFormat format = buffer->getPixelFormat(); + + if (HARDWARE_IS_DEVICE_FORMAT(format)) { + return false; + } + + PixelFormatInfo info; + status_t err = getPixelFormatInfo(format, &info); + if (!err && info.h_alpha <= info.l_alpha) { + return false; + } + } + + // Return opacity as determined from flags and format options + // passed to setBuffers() + return mNeedsBlending; +} + +bool Layer::needsBlending() const +{ + if (mBufferManager.hasActiveBuffer()) { + return needsBlending(mBufferManager.getActiveBuffer()); + } + + return mNeedsBlending; +} + bool Layer::needsFiltering() const { if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { @@ -591,6 +630,9 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) // we retired a buffer, which becomes the new front buffer const bool noActiveBuffer = !mBufferManager.hasActiveBuffer(); + const bool activeBlending = + noActiveBuffer ? true : needsBlending(mBufferManager.getActiveBuffer()); + if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); mPostedDirtyRegion.clear(); @@ -605,6 +647,12 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); if (newFrontBuffer != NULL) { + if (!noActiveBuffer && activeBlending != needsBlending(newFrontBuffer)) { + // new buffer has different opacity than previous active buffer, need + // to recompute visible regions accordingly + recomputeVisibleRegions = true; + } + // get the dirty region // compute the posted region const Region dirty(lcblk->getDirtyRegion(buf)); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index d9a8be3..7538231 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -75,7 +75,8 @@ public: virtual uint32_t doTransaction(uint32_t transactionFlags); virtual void lockPageFlip(bool& recomputeVisibleRegions); virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); - virtual bool needsBlending() const { return mNeedsBlending; } + virtual bool needsBlending(const sp<GraphicBuffer>& buffer) const; + virtual bool needsBlending() const; virtual bool needsDithering() const { return mNeedsDithering; } virtual bool needsFiltering() const; virtual bool isSecure() const { return mSecure; } |