Use pixel format from buffer to determine opacity.
The format that's passed into BufferQueueLayer creation is meant to
define what format the buffers should have that are dequeued from the
consumer. If the client submits its own buffers, they can have any
pixel format. Therefore, the format from the activeBuffer should be used
when determing opacity since that's the information about the buffer
that will be rendered.
Bug: 152162496
Test: LayerTypeAndRenderTypeTransactionTest#SetBufferFormat
Change-Id: I4295b837369b8ca8918d8398a29cab133a47cbf7
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index e4d754c..a32bc2b 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -272,7 +272,7 @@
// pixel format is HDR Y410 masquerading as RGBA_1010102
return (mBufferInfo.mDataspace == ui::Dataspace::BT2020_ITU_PQ &&
mBufferInfo.mApi == NATIVE_WINDOW_API_MEDIA &&
- mBufferInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
+ mBufferInfo.mPixelFormat == HAL_PIXEL_FORMAT_RGBA_1010102);
}
sp<compositionengine::LayerFE> BufferLayer::getCompositionEngineLayerFE() const {
@@ -374,6 +374,12 @@
return true;
}
+void BufferLayer::gatherBufferInfo() {
+ mBufferInfo.mPixelFormat =
+ !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->format;
+ mBufferInfo.mFrameLatencyNeeded = true;
+}
+
bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
nsecs_t expectedPresentTime) {
ATRACE_CALL();
@@ -434,7 +440,6 @@
gatherBufferInfo();
mRefreshPending = true;
- mBufferInfo.mFrameLatencyNeeded = true;
if (oldBufferInfo.mBuffer == nullptr) {
// the first time we receive a buffer, we need to trigger a
// geometry invalidation.
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index f678910..fbec6ee 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -161,7 +161,7 @@
Region mSurfaceDamage;
HdrMetadata mHdrMetadata;
int mApi;
- PixelFormat mPixelFormat;
+ PixelFormat mPixelFormat{PIXEL_FORMAT_NONE};
bool mTransformToDisplayInverse{false};
sp<GraphicBuffer> mBuffer;
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 4e5c593..c84b15d 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -525,8 +525,6 @@
return BAD_VALUE;
}
- mFormat = format;
-
setDefaultBufferSize(w, h);
mConsumer->setDefaultBufferFormat(format);
mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
@@ -550,6 +548,8 @@
}
void BufferQueueLayer::gatherBufferInfo() {
+ BufferLayer::gatherBufferInfo();
+
mBufferInfo.mDesiredPresentTime = mConsumer->getTimestamp();
mBufferInfo.mFenceTime = mConsumer->getCurrentFenceTime();
mBufferInfo.mFence = mConsumer->getCurrentFence();
@@ -560,7 +560,6 @@
mBufferInfo.mSurfaceDamage = mConsumer->getSurfaceDamage();
mBufferInfo.mHdrMetadata = mConsumer->getCurrentHdrMetadata();
mBufferInfo.mApi = mConsumer->getCurrentApi();
- mBufferInfo.mPixelFormat = mFormat;
mBufferInfo.mTransformToDisplayInverse = mConsumer->getTransformToDisplayInverse();
}
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index 5f7587c..ea7f203 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -132,8 +132,6 @@
sp<BufferLayerConsumer> mConsumer;
sp<IGraphicBufferProducer> mProducer;
- PixelFormat mFormat{PIXEL_FORMAT_NONE};
-
bool mUpdateTexImageFailed{false};
uint64_t mPreviousBufferId = 0;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 3ed6889..3e65171 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -718,8 +718,9 @@
}
void BufferStateLayer::gatherBufferInfo() {
- const State& s(getDrawingState());
+ BufferLayer::gatherBufferInfo();
+ const State& s(getDrawingState());
mBufferInfo.mDesiredPresentTime = s.desiredPresentTime;
mBufferInfo.mFenceTime = std::make_shared<FenceTime>(s.acquireFence);
mBufferInfo.mFence = s.acquireFence;
@@ -730,8 +731,6 @@
mBufferInfo.mSurfaceDamage = s.surfaceDamageRegion;
mBufferInfo.mHdrMetadata = s.hdrMetadata;
mBufferInfo.mApi = s.api;
- mBufferInfo.mPixelFormat =
- !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->format;
mBufferInfo.mTransformToDisplayInverse = s.transformToDisplayInverse;
mBufferInfo.mBufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
}
diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h
index 932c7c8..40ec502 100644
--- a/services/surfaceflinger/tests/LayerTransactionTest.h
+++ b/services/surfaceflinger/tests/LayerTransactionTest.h
@@ -52,9 +52,10 @@
virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
const char* name, uint32_t width, uint32_t height,
uint32_t flags = 0, SurfaceControl* parent = nullptr,
- uint32_t* outTransformHint = nullptr) {
- auto layer = createSurface(client, name, width, height, PIXEL_FORMAT_RGBA_8888, flags,
- parent, outTransformHint);
+ uint32_t* outTransformHint = nullptr,
+ PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
+ auto layer =
+ createSurface(client, name, width, height, format, flags, parent, outTransformHint);
Transaction t;
t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
@@ -81,8 +82,9 @@
virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
uint32_t flags = 0, SurfaceControl* parent = nullptr,
- uint32_t* outTransformHint = nullptr) {
- return createLayer(mClient, name, width, height, flags, parent, outTransformHint);
+ uint32_t* outTransformHint = nullptr,
+ PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
+ return createLayer(mClient, name, width, height, flags, parent, outTransformHint, format);
}
sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
index 2fd2579..d666d7e 100644
--- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
@@ -365,6 +365,67 @@
getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
}
}
+
+TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBufferFormat) {
+ int32_t width = 100;
+ int32_t height = 100;
+ Rect crop = Rect(0, 0, width, height);
+
+ sp<SurfaceControl> behindLayer = createColorLayer("Behind layer", Color::RED);
+ sp<SurfaceControl> layer;
+ ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", width, height, 0, nullptr, nullptr,
+ PIXEL_FORMAT_RGBX_8888));
+
+ Transaction()
+ .setLayer(layer, INT32_MAX - 1)
+ .show(layer)
+ .setLayerStack(behindLayer, mDisplayLayerStack)
+ .setCrop_legacy(behindLayer, crop)
+ .setLayer(behindLayer, INT32_MAX - 2)
+ .show(behindLayer)
+ .apply();
+
+ sp<Surface> surface = layer->getSurface();
+
+ sp<GraphicBuffer> buffer =
+ new GraphicBuffer(width, height, PIXEL_FORMAT_RGBX_8888, 1,
+ BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+ BufferUsage::COMPOSER_OVERLAY,
+ "test");
+ ASSERT_NO_FATAL_FAILURE(
+ TransactionUtils::fillGraphicBufferColor(buffer, crop, Color::TRANSPARENT));
+
+ if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) {
+ Surface::attachAndQueueBufferWithDataspace(surface.get(), buffer, ui::Dataspace::V0_SRGB);
+ } else {
+ Transaction().setBuffer(layer, buffer).apply();
+ }
+
+ {
+ SCOPED_TRACE("Buffer Opaque Format");
+ auto shot = screenshot();
+ shot->expectColor(crop, Color::BLACK);
+ }
+
+ buffer = new GraphicBuffer(width, height, PIXEL_FORMAT_RGBA_8888, 1,
+ BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+ BufferUsage::COMPOSER_OVERLAY,
+ "test");
+ ASSERT_NO_FATAL_FAILURE(
+ TransactionUtils::fillGraphicBufferColor(buffer, crop, Color::TRANSPARENT));
+
+ if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) {
+ Surface::attachAndQueueBufferWithDataspace(surface.get(), buffer, ui::Dataspace::V0_SRGB);
+ } else {
+ Transaction().setBuffer(layer, buffer).apply();
+ }
+
+ {
+ SCOPED_TRACE("Buffer Transparent Format");
+ auto shot = screenshot();
+ shot->expectColor(crop, Color::RED);
+ }
+}
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/tests/TransactionTestHarnesses.h b/services/surfaceflinger/tests/TransactionTestHarnesses.h
index 040852f..f0af363 100644
--- a/services/surfaceflinger/tests/TransactionTestHarnesses.h
+++ b/services/surfaceflinger/tests/TransactionTestHarnesses.h
@@ -88,13 +88,14 @@
sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
uint32_t flags = 0, SurfaceControl* parent = nullptr,
- uint32_t* outTransformHint = nullptr) {
+ uint32_t* outTransformHint = nullptr,
+ PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
// if the flags already have a layer type specified, return an error
if (flags & ISurfaceComposerClient::eFXSurfaceMask) {
return nullptr;
}
return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType, parent,
- outTransformHint);
+ outTransformHint, format);
}
void fillLayerColor(const sp<SurfaceControl>& layer, const Color& color, int32_t bufferWidth,