summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger
diff options
context:
space:
mode:
authorEric Hassold <hassold@google.com>2011-02-10 14:41:26 -0800
committerEric Hassold <hassold@google.com>2011-02-15 16:20:03 -0800
commit2ae32bdd7579ca6a9a336c74613185b21d39c8d4 (patch)
tree54057737faafcd5afb7c1d2469b697b9a242a5af /services/surfaceflinger
parent302b9884b3f0ecc96cc618643835d415e474cac3 (diff)
downloadframeworks_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.cpp48
-rw-r--r--services/surfaceflinger/Layer.h3
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; }