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
This commit is contained in:
Eric Hassold 2011-02-10 14:41:26 -08:00
parent 860143f0e4
commit ac45e6bff1
2 changed files with 50 additions and 1 deletions

View File

@ -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));

View File

@ -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; }