Merge "Remove perfetto_src_tracing_ipc dependency"
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index 76f7c7f..3d550ba 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -452,7 +452,7 @@
}
TEST_F(ListTest, DumpVintf) {
- const std::string expected = "<manifest version=\"1.0\" type=\"device\">\n"
+ const std::string expected = "<manifest version=\"2.0\" type=\"device\">\n"
" <hal format=\"hidl\">\n"
" <name>a.h.foo1</name>\n"
" <transport>hwbinder</transport>\n"
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index c2f6d55..b1b8ff1 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -21,8 +21,6 @@
#include <string>
#include <vector>
-#include <linux/android/binder.h>
-
#include <android-base/unique_fd.h>
#include <cutils/native_handle.h>
#include <utils/Errors.h>
@@ -34,11 +32,19 @@
#include <binder/IInterface.h>
#include <binder/Parcelable.h>
+#ifdef BINDER_IPC_32BIT
+typedef __u32 binder_size_t;
+#else
+typedef __u64 binder_size_t;
+#endif
+
+
// ---------------------------------------------------------------------------
namespace android {
template <typename T> class Flattenable;
template <typename T> class LightFlattenable;
+struct flat_binder_object;
class IBinder;
class IPCThreadState;
class ProcessState;
@@ -378,7 +384,6 @@
// Returns the work source provided by the caller. This can only be trusted for trusted calling
// uid.
uid_t readCallingWorkSourceUid() const;
- void readRequestHeaders() const;
private:
typedef void (*release_func)(Parcel* parcel,
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 5c6cf9d..db4a36b 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -28,6 +28,7 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <private/binder/binder_module.h>
#include <sys/epoll.h>
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index be58b85..523ed1d 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -291,9 +291,6 @@
what |= eOverrideScalingModeChanged;
overrideScalingMode = other.overrideScalingMode;
}
- if (other.what & eGeometryAppliesWithResize) {
- what |= eGeometryAppliesWithResize;
- }
if (other.what & eReparentChildren) {
what |= eReparentChildren;
reparentHandle = other.reparentHandle;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 5faf010..67dd726 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1187,19 +1187,6 @@
return *this;
}
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeometryAppliesWithResize(
- const sp<SurfaceControl>& sc) {
- layer_state_t* s = getLayerState(sc);
- if (!s) {
- mStatus = BAD_INDEX;
- return *this;
- }
- s->what |= layer_state_t::eGeometryAppliesWithResize;
-
- registerSurfaceControlForCallback(sc);
- return *this;
-}
-
#ifndef NO_INPUT
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo(
const sp<SurfaceControl>& sc,
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index cbd1c85..2eb5492 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -71,7 +71,7 @@
eCropChanged_legacy = 0x00000100,
eDeferTransaction_legacy = 0x00000200,
eOverrideScalingModeChanged = 0x00000400,
- eGeometryAppliesWithResize = 0x00000800,
+ // AVAILABLE 0x00000800,
eReparentChildren = 0x00001000,
eDetachChildren = 0x00002000,
eRelativeLayerChanged = 0x00004000,
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 64ee65f..8a6920c 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -446,12 +446,6 @@
Transaction& setOverrideScalingMode(const sp<SurfaceControl>& sc,
int32_t overrideScalingMode);
- // If the size changes in this transaction, all geometry updates specified
- // in this transaction will not complete until a buffer of the new size
- // arrives. As some elements normally apply immediately, this enables
- // freezing the total geometry of a surface until a resize is completed.
- Transaction& setGeometryAppliesWithResize(const sp<SurfaceControl>& sc);
-
#ifndef NO_INPUT
Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
Transaction& transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
diff --git a/libs/vr/libdisplay/vsync_service.cpp b/libs/vr/libdisplay/vsync_service.cpp
index 4668b98..04d4f30 100644
--- a/libs/vr/libdisplay/vsync_service.cpp
+++ b/libs/vr/libdisplay/vsync_service.cpp
@@ -45,8 +45,8 @@
ALOGE("onVsync failed to writeInt64: %d", result);
return result;
}
- result = remote()->transact(
- BnVsyncCallback::ON_VSYNC, data, &reply, TF_ONE_WAY);
+ result = remote()->transact(BnVsyncCallback::ON_VSYNC, data, &reply,
+ IBinder::FLAG_ONEWAY);
if (result != OK) {
ALOGE("onVsync failed to transact: %d", result);
return result;
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 26abe1c..486b042 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -81,7 +81,7 @@
if (mFlinger->mForceFullDamage) {
surfaceDamageRegion = Region::INVALID_REGION;
} else {
- surfaceDamageRegion = getDrawingSurfaceDamage();
+ surfaceDamageRegion = mBufferInfo.mSurfaceDamage;
}
}
@@ -92,7 +92,7 @@
bool BufferLayer::isOpaque(const Layer::State& s) const {
// if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
// layer's opaque flag.
- if ((mSidebandStream == nullptr) && (mActiveBuffer == nullptr)) {
+ if ((mSidebandStream == nullptr) && (mBufferInfo.mBuffer == nullptr)) {
return false;
}
@@ -103,7 +103,7 @@
bool BufferLayer::isVisible() const {
bool visible = !(isHiddenByPolicy()) && getAlpha() > 0.0f &&
- (mActiveBuffer != nullptr || mSidebandStream != nullptr);
+ (mBufferInfo.mBuffer != nullptr || mSidebandStream != nullptr);
mFlinger->mScheduler->setLayerVisibility(mSchedulerLayerHandle, visible);
return visible;
@@ -144,7 +144,7 @@
return result;
}
- if (CC_UNLIKELY(mActiveBuffer == 0)) {
+ if (CC_UNLIKELY(mBufferInfo.mBuffer == 0)) {
// the texture has not been created yet, this Layer has
// in fact never been drawn into. This happens frequently with
// SurfaceView because the WindowManager can't know when the client
@@ -176,9 +176,9 @@
const State& s(getDrawingState());
auto& layer = *result;
if (!blackOutLayer) {
- layer.source.buffer.buffer = mActiveBuffer;
+ layer.source.buffer.buffer = mBufferInfo.mBuffer;
layer.source.buffer.isOpaque = isOpaque(s);
- layer.source.buffer.fence = mActiveBufferFence;
+ layer.source.buffer.fence = mBufferInfo.mFence;
layer.source.buffer.textureName = mTextureName;
layer.source.buffer.usePremultipliedAlpha = getPremultipledAlpha();
layer.source.buffer.isY410BT2020 = isHdrY410();
@@ -188,7 +188,7 @@
// Query the texture matrix given our current filtering mode.
float textureMatrix[16];
setFilteringEnabled(useFiltering);
- getDrawingTransformMatrix(textureMatrix);
+ memcpy(textureMatrix, mBufferInfo.mTransformMatrix, sizeof(mBufferInfo.mTransformMatrix));
if (getTransformToDisplayInverse()) {
/*
@@ -255,9 +255,9 @@
bool BufferLayer::isHdrY410() const {
// pixel format is HDR Y410 masquerading as RGBA_1010102
- return (mCurrentDataSpace == ui::Dataspace::BT2020_ITU_PQ &&
- getDrawingApi() == NATIVE_WINDOW_API_MEDIA &&
- mActiveBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
+ return (mBufferInfo.mDataspace == ui::Dataspace::BT2020_ITU_PQ &&
+ mBufferInfo.mApi == NATIVE_WINDOW_API_MEDIA &&
+ mBufferInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
}
void BufferLayer::latchPerFrameState(
@@ -269,7 +269,7 @@
compositionState.compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
} else {
// Normal buffer layers
- compositionState.hdrMetadata = getDrawingHdrMetadata();
+ compositionState.hdrMetadata = mBufferInfo.mHdrMetadata;
compositionState.compositionType = mPotentialCursor
? Hwc2::IComposerClient::Composition::CURSOR
: Hwc2::IComposerClient::Composition::DEVICE;
@@ -277,7 +277,7 @@
}
bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
- if (mBufferLatched) {
+ if (mBufferInfo.mBuffer != nullptr) {
Mutex::Autolock lock(mFrameEventHistoryMutex);
mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime);
}
@@ -301,13 +301,13 @@
}
// Update mFrameTracker.
- nsecs_t desiredPresentTime = getDesiredPresentTime();
+ nsecs_t desiredPresentTime = mBufferInfo.mDesiredPresentTime;
mFrameTracker.setDesiredPresentTime(desiredPresentTime);
const int32_t layerID = getSequence();
mFlinger->mTimeStats->setDesiredTime(layerID, mCurrentFrameNumber, desiredPresentTime);
- std::shared_ptr<FenceTime> frameReadyFence = getCurrentFenceTime();
+ std::shared_ptr<FenceTime> frameReadyFence = mBufferInfo.mFenceTime;
if (frameReadyFence->isValid()) {
mFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
} else {
@@ -371,7 +371,8 @@
// Capture the old state of the layer for comparisons later
const State& s(getDrawingState());
const bool oldOpacity = isOpaque(s);
- sp<GraphicBuffer> oldBuffer = mActiveBuffer;
+
+ BufferInfo oldBufferInfo = mBufferInfo;
if (!allTransactionsSignaled(expectedPresentTime)) {
mFlinger->setTransactionFlags(eTraversalNeeded);
@@ -388,65 +389,33 @@
return false;
}
- mBufferLatched = true;
-
err = updateFrameNumber(latchTime);
if (err != NO_ERROR) {
return false;
}
+ gatherBufferInfo();
+
mRefreshPending = true;
mFrameLatencyNeeded = true;
- if (oldBuffer == nullptr) {
+ if (oldBufferInfo.mBuffer == nullptr) {
// the first time we receive a buffer, we need to trigger a
// geometry invalidation.
recomputeVisibleRegions = true;
}
- ui::Dataspace dataSpace = getDrawingDataSpace();
- // translate legacy dataspaces to modern dataspaces
- switch (dataSpace) {
- case ui::Dataspace::SRGB:
- dataSpace = ui::Dataspace::V0_SRGB;
- break;
- case ui::Dataspace::SRGB_LINEAR:
- dataSpace = ui::Dataspace::V0_SRGB_LINEAR;
- break;
- case ui::Dataspace::JFIF:
- dataSpace = ui::Dataspace::V0_JFIF;
- break;
- case ui::Dataspace::BT601_625:
- dataSpace = ui::Dataspace::V0_BT601_625;
- break;
- case ui::Dataspace::BT601_525:
- dataSpace = ui::Dataspace::V0_BT601_525;
- break;
- case ui::Dataspace::BT709:
- dataSpace = ui::Dataspace::V0_BT709;
- break;
- default:
- break;
- }
- mCurrentDataSpace = dataSpace;
-
- Rect crop(getDrawingCrop());
- const uint32_t transform(getDrawingTransform());
- const uint32_t scalingMode(getDrawingScalingMode());
- const bool transformToDisplayInverse(getTransformToDisplayInverse());
- if ((crop != mCurrentCrop) || (transform != mCurrentTransform) ||
- (scalingMode != mCurrentScalingMode) ||
- (transformToDisplayInverse != mTransformToDisplayInverse)) {
- mCurrentCrop = crop;
- mCurrentTransform = transform;
- mCurrentScalingMode = scalingMode;
- mTransformToDisplayInverse = transformToDisplayInverse;
+ if ((mBufferInfo.mCrop != oldBufferInfo.mCrop) ||
+ (mBufferInfo.mTransform != oldBufferInfo.mTransform) ||
+ (mBufferInfo.mScaleMode != oldBufferInfo.mScaleMode) ||
+ (mBufferInfo.mTransformToDisplayInverse != oldBufferInfo.mTransformToDisplayInverse)) {
recomputeVisibleRegions = true;
}
- if (oldBuffer != nullptr) {
- uint32_t bufWidth = mActiveBuffer->getWidth();
- uint32_t bufHeight = mActiveBuffer->getHeight();
- if (bufWidth != uint32_t(oldBuffer->width) || bufHeight != uint32_t(oldBuffer->height)) {
+ if (oldBufferInfo.mBuffer != nullptr) {
+ uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
+ uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
+ if (bufWidth != uint32_t(oldBufferInfo.mBuffer->width) ||
+ bufHeight != uint32_t(oldBufferInfo.mBuffer->height)) {
recomputeVisibleRegions = true;
}
}
@@ -511,11 +480,11 @@
return mOverrideScalingMode;
}
- return mCurrentScalingMode;
+ return mBufferInfo.mScaleMode;
}
bool BufferLayer::isProtected() const {
- const sp<GraphicBuffer>& buffer(mActiveBuffer);
+ const sp<GraphicBuffer>& buffer(mBufferInfo.mBuffer);
return (buffer != 0) && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
}
@@ -619,15 +588,15 @@
return Rect(getActiveWidth(s), getActiveHeight(s));
}
- if (mActiveBuffer == nullptr) {
+ if (mBufferInfo.mBuffer == nullptr) {
return Rect::INVALID_RECT;
}
- uint32_t bufWidth = mActiveBuffer->getWidth();
- uint32_t bufHeight = mActiveBuffer->getHeight();
+ uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
+ uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
// Undo any transformations on the buffer and return the result.
- if (mCurrentTransform & ui::Transform::ROT_90) {
+ if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
std::swap(bufWidth, bufHeight);
}
@@ -655,15 +624,15 @@
return FloatRect(0, 0, getActiveWidth(s), getActiveHeight(s));
}
- if (mActiveBuffer == nullptr) {
+ if (mBufferInfo.mBuffer == nullptr) {
return parentBounds;
}
- uint32_t bufWidth = mActiveBuffer->getWidth();
- uint32_t bufHeight = mActiveBuffer->getHeight();
+ uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
+ uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
// Undo any transformations on the buffer and return the result.
- if (mCurrentTransform & ui::Transform::ROT_90) {
+ if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
std::swap(bufWidth, bufHeight);
}
@@ -686,6 +655,70 @@
releasePendingBuffer(systemTime());
}
+PixelFormat BufferLayer::getPixelFormat() const {
+ return mBufferInfo.mPixelFormat;
+}
+
+bool BufferLayer::getTransformToDisplayInverse() const {
+ return mBufferInfo.mTransformToDisplayInverse;
+}
+
+Rect BufferLayer::getBufferCrop() const {
+ // this is the crop rectangle that applies to the buffer
+ // itself (as opposed to the window)
+ if (!mBufferInfo.mCrop.isEmpty()) {
+ // if the buffer crop is defined, we use that
+ return mBufferInfo.mCrop;
+ } else if (mBufferInfo.mBuffer != nullptr) {
+ // otherwise we use the whole buffer
+ return mBufferInfo.mBuffer->getBounds();
+ } else {
+ // if we don't have a buffer yet, we use an empty/invalid crop
+ return Rect();
+ }
+}
+
+uint32_t BufferLayer::getBufferTransform() const {
+ return mBufferInfo.mTransform;
+}
+
+ui::Dataspace BufferLayer::getDataSpace() const {
+ return mBufferInfo.mDataspace;
+}
+
+ui::Dataspace BufferLayer::translateDataspace(ui::Dataspace dataspace) {
+ ui::Dataspace updatedDataspace = dataspace;
+ // translate legacy dataspaces to modern dataspaces
+ switch (dataspace) {
+ case ui::Dataspace::SRGB:
+ updatedDataspace = ui::Dataspace::V0_SRGB;
+ break;
+ case ui::Dataspace::SRGB_LINEAR:
+ updatedDataspace = ui::Dataspace::V0_SRGB_LINEAR;
+ break;
+ case ui::Dataspace::JFIF:
+ updatedDataspace = ui::Dataspace::V0_JFIF;
+ break;
+ case ui::Dataspace::BT601_625:
+ updatedDataspace = ui::Dataspace::V0_BT601_625;
+ break;
+ case ui::Dataspace::BT601_525:
+ updatedDataspace = ui::Dataspace::V0_BT601_525;
+ break;
+ case ui::Dataspace::BT709:
+ updatedDataspace = ui::Dataspace::V0_BT709;
+ break;
+ default:
+ break;
+ }
+
+ return updatedDataspace;
+}
+
+sp<GraphicBuffer> BufferLayer::getBuffer() const {
+ return mBufferInfo.mBuffer;
+}
+
} // namespace android
#if defined(__gl_h_)
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index ee44cbe..a685ea2 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -106,6 +106,16 @@
// Should only be called on the main thread.
void latchAndReleaseBuffer() override;
+ bool getTransformToDisplayInverse() const override;
+
+ Rect getBufferCrop() const override;
+
+ uint32_t getBufferTransform() const override;
+
+ ui::Dataspace getDataSpace() const override;
+
+ sp<GraphicBuffer> getBuffer() const override;
+
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
@@ -115,18 +125,7 @@
virtual bool fenceHasSignaled() const = 0;
virtual bool framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const = 0;
- virtual nsecs_t getDesiredPresentTime() = 0;
- virtual std::shared_ptr<FenceTime> getCurrentFenceTime() const = 0;
-
- virtual void getDrawingTransformMatrix(float *matrix) = 0;
- virtual uint32_t getDrawingTransform() const = 0;
- virtual ui::Dataspace getDrawingDataSpace() const = 0;
- virtual Rect getDrawingCrop() const = 0;
- virtual uint32_t getDrawingScalingMode() const = 0;
- virtual Region getDrawingSurfaceDamage() const = 0;
- virtual const HdrMetadata& getDrawingHdrMetadata() const = 0;
- virtual int getDrawingApi() const = 0;
- virtual PixelFormat getPixelFormat() const = 0;
+ PixelFormat getPixelFormat() const;
virtual uint64_t getFrameNumber(nsecs_t expectedPresentTime) const = 0;
@@ -148,6 +147,28 @@
virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;
protected:
+ struct BufferInfo {
+ nsecs_t mDesiredPresentTime;
+ std::shared_ptr<FenceTime> mFenceTime;
+ sp<Fence> mFence;
+ float mTransformMatrix[16];
+ uint32_t mTransform{0};
+ ui::Dataspace mDataspace;
+ Rect mCrop;
+ uint32_t mScaleMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
+ Region mSurfaceDamage;
+ HdrMetadata mHdrMetadata;
+ int mApi;
+ PixelFormat mPixelFormat;
+ bool mTransformToDisplayInverse{false};
+
+ sp<GraphicBuffer> mBuffer;
+ int mBufferSlot{BufferQueue::INVALID_BUFFER_SLOT};
+ };
+
+ BufferInfo mBufferInfo;
+ virtual void gatherBufferInfo() = 0;
+
/*
* compositionengine::LayerFE overrides
*/
@@ -171,19 +192,14 @@
bool mRefreshPending{false};
+ ui::Dataspace translateDataspace(ui::Dataspace dataspace);
+
private:
// Returns true if this layer requires filtering
bool needsFiltering(const sp<const DisplayDevice>& displayDevice) const override;
uint64_t getHeadFrameNumber(nsecs_t expectedPresentTime) const;
- uint32_t mCurrentScalingMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
-
- bool mTransformToDisplayInverse{false};
-
- // main thread.
- bool mBufferLatched{false}; // TODO: Use mActiveBuffer?
-
// BufferStateLayers can return Rect::INVALID_RECT if the layer does not have a display frame
// and its parent layer is not bounded
Rect getBufferSize(const State& s) const override;
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 4da39e4..a9e364a 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -70,10 +70,6 @@
return history;
}
-bool BufferQueueLayer::getTransformToDisplayInverse() const {
- return mConsumer->getTransformToDisplayInverse();
-}
-
void BufferQueueLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
if (!mConsumer->releasePendingBuffer()) {
return;
@@ -155,55 +151,12 @@
return mQueueItems[0].mTimestamp <= expectedPresentTime;
}
-nsecs_t BufferQueueLayer::getDesiredPresentTime() {
- return mConsumer->getTimestamp();
-}
-
-std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTime() const {
- return mConsumer->getCurrentFenceTime();
-}
-
-void BufferQueueLayer::getDrawingTransformMatrix(float *matrix) {
- return mConsumer->getTransformMatrix(matrix);
-}
-
// NOTE: SurfaceFlinger's definitions of "Current" and "Drawing" do not neatly map to BufferQueue's
// These functions get the fields for the frame that is currently in SurfaceFlinger's Drawing state
// so the functions start with "getDrawing". The data is retrieved from the BufferQueueConsumer's
// current buffer so the consumer functions start with "getCurrent".
//
// This results in the rather confusing functions below.
-uint32_t BufferQueueLayer::getDrawingTransform() const {
- return mConsumer->getCurrentTransform();
-}
-
-ui::Dataspace BufferQueueLayer::getDrawingDataSpace() const {
- return mConsumer->getCurrentDataSpace();
-}
-
-Rect BufferQueueLayer::getDrawingCrop() const {
- return mConsumer->getCurrentCrop();
-}
-
-uint32_t BufferQueueLayer::getDrawingScalingMode() const {
- return mConsumer->getCurrentScalingMode();
-}
-
-Region BufferQueueLayer::getDrawingSurfaceDamage() const {
- return mConsumer->getSurfaceDamage();
-}
-
-const HdrMetadata& BufferQueueLayer::getDrawingHdrMetadata() const {
- return mConsumer->getCurrentHdrMetadata();
-}
-
-int BufferQueueLayer::getDrawingApi() const {
- return mConsumer->getCurrentApi();
-}
-
-PixelFormat BufferQueueLayer::getPixelFormat() const {
- return mFormat;
-}
uint64_t BufferQueueLayer::getFrameNumber(nsecs_t expectedPresentTime) const {
Mutex::Autolock lock(mQueueItemLock);
@@ -285,7 +238,7 @@
const int32_t layerID = getSequence();
LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
- getTransformToDisplayInverse(), mFreezeGeometryUpdates);
+ getTransformToDisplayInverse());
if (isRemovedFromCurrentState()) {
expectedPresentTime = 0;
@@ -390,11 +343,12 @@
status_t BufferQueueLayer::updateActiveBuffer() {
// update the active buffer
mPreviousBufferId = getCurrentBufferId();
- mActiveBuffer = mConsumer->getCurrentBuffer(&mActiveBufferSlot, &mActiveBufferFence);
+ mBufferInfo.mBuffer =
+ mConsumer->getCurrentBuffer(&mBufferInfo.mBufferSlot, &mBufferInfo.mFence);
auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
- layerCompositionState.buffer = mActiveBuffer;
+ layerCompositionState.buffer = mBufferInfo.mBuffer;
- if (mActiveBuffer == nullptr) {
+ if (mBufferInfo.mBuffer == nullptr) {
// this can only happen if the very first buffer was rejected.
return BAD_VALUE;
}
@@ -419,10 +373,11 @@
return;
}
- compositionState.buffer = mActiveBuffer;
- compositionState.bufferSlot =
- (mActiveBufferSlot == BufferQueue::INVALID_BUFFER_SLOT) ? 0 : mActiveBufferSlot;
- compositionState.acquireFence = mConsumer->getCurrentFence();
+ compositionState.buffer = mBufferInfo.mBuffer;
+ compositionState.bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
+ ? 0
+ : mBufferInfo.mBufferSlot;
+ compositionState.acquireFence = mBufferInfo.mFence;
}
// -----------------------------------------------------------------------
@@ -573,4 +528,20 @@
return static_cast<uint32_t>(producerStickyTransform);
}
+void BufferQueueLayer::gatherBufferInfo() {
+ mBufferInfo.mDesiredPresentTime = mConsumer->getTimestamp();
+ mBufferInfo.mFenceTime = mConsumer->getCurrentFenceTime();
+ mBufferInfo.mFence = mConsumer->getCurrentFence();
+ mConsumer->getTransformMatrix(mBufferInfo.mTransformMatrix);
+ mBufferInfo.mTransform = mConsumer->getCurrentTransform();
+ mBufferInfo.mDataspace = translateDataspace(mConsumer->getCurrentDataSpace());
+ mBufferInfo.mCrop = mConsumer->getCurrentCrop();
+ mBufferInfo.mScaleMode = mConsumer->getCurrentScalingMode();
+ mBufferInfo.mSurfaceDamage = mConsumer->getSurfaceDamage();
+ mBufferInfo.mHdrMetadata = mConsumer->getCurrentHdrMetadata();
+ mBufferInfo.mApi = mConsumer->getCurrentApi();
+ mBufferInfo.mPixelFormat = mFormat;
+ mBufferInfo.mTransformToDisplayInverse = mConsumer->getTransformToDisplayInverse();
+}
+
} // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index bf3f917..43eb3ea 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -46,7 +46,6 @@
std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override;
- bool getTransformToDisplayInverse() const override;
// If a buffer was replaced this frame, release the former buffer
void releasePendingBuffer(nsecs_t dequeueReadyTime) override;
@@ -66,18 +65,6 @@
bool framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const override;
private:
- nsecs_t getDesiredPresentTime() override;
- std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
-
- void getDrawingTransformMatrix(float *matrix) override;
- uint32_t getDrawingTransform() const override;
- ui::Dataspace getDrawingDataSpace() const override;
- Rect getDrawingCrop() const override;
- uint32_t getDrawingScalingMode() const override;
- Region getDrawingSurfaceDamage() const override;
- const HdrMetadata& getDrawingHdrMetadata() const override;
- int getDrawingApi() const override;
- PixelFormat getPixelFormat() const override;
uint64_t getFrameNumber(nsecs_t expectedPresentTime) const override;
@@ -103,6 +90,8 @@
// Interface implementation for BufferLayerConsumer::ContentsChangedListener
// -----------------------------------------------------------------------
protected:
+ void gatherBufferInfo() override;
+
void onFrameAvailable(const BufferItem& item) override;
void onFrameReplaced(const BufferItem& item) override;
void onSidebandStreamChanged() override;
@@ -138,7 +127,6 @@
std::atomic<uint64_t> mLastFrameNumberReceived{0};
bool mAutoRefresh{false};
- int mActiveBufferSlot{BufferQueue::INVALID_BUFFER_SLOT};
// thread-safe
std::atomic<int32_t> mQueuedFrames{0};
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index e7d1b63..afbe228 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -53,12 +53,12 @@
}
BufferStateLayer::~BufferStateLayer() {
- if (mActiveBuffer != nullptr) {
- // Ensure that mActiveBuffer is uncached from RenderEngine here, as
+ if (mBufferInfo.mBuffer != nullptr) {
+ // Ensure that mBuffer is uncached from RenderEngine here, as
// RenderEngine may have been using the buffer as an external texture
// after the client uncached the buffer.
auto& engine(mFlinger->getRenderEngine());
- engine.unbindExternalTextureBuffer(mActiveBuffer->getId());
+ engine.unbindExternalTextureBuffer(mBufferInfo.mBuffer->getId());
}
}
@@ -125,10 +125,6 @@
(mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr));
}
-bool BufferStateLayer::getTransformToDisplayInverse() const {
- return mCurrentState.transformToDisplayInverse;
-}
-
void BufferStateLayer::pushPendingState() {
if (!mCurrentState.modified) {
return;
@@ -400,75 +396,6 @@
return mCurrentState.desiredPresentTime <= expectedPresentTime;
}
-nsecs_t BufferStateLayer::getDesiredPresentTime() {
- return getDrawingState().desiredPresentTime;
-}
-
-std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
- return std::make_shared<FenceTime>(getDrawingState().acquireFence);
-}
-
-void BufferStateLayer::getDrawingTransformMatrix(float *matrix) {
- std::copy(std::begin(mTransformMatrix), std::end(mTransformMatrix), matrix);
-}
-
-uint32_t BufferStateLayer::getDrawingTransform() const {
- return getDrawingState().transform;
-}
-
-ui::Dataspace BufferStateLayer::getDrawingDataSpace() const {
- return getDrawingState().dataspace;
-}
-
-// Crop that applies to the buffer
-Rect BufferStateLayer::getDrawingCrop() const {
- const State& s(getDrawingState());
-
- if (s.crop.isEmpty() && s.buffer) {
- return s.buffer->getBounds();
- } else if (s.buffer) {
- Rect crop = s.crop;
- crop.left = std::max(crop.left, 0);
- crop.top = std::max(crop.top, 0);
- uint32_t bufferWidth = s.buffer->getWidth();
- uint32_t bufferHeight = s.buffer->getHeight();
- if (bufferHeight <= std::numeric_limits<int32_t>::max() &&
- bufferWidth <= std::numeric_limits<int32_t>::max()) {
- crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth));
- crop.bottom = std::min(crop.bottom, static_cast<int32_t>(bufferHeight));
- }
- if (!crop.isValid()) {
- // Crop rect is out of bounds, return whole buffer
- return s.buffer->getBounds();
- }
- return crop;
- }
- return s.crop;
-}
-
-uint32_t BufferStateLayer::getDrawingScalingMode() const {
- return NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
-}
-
-Region BufferStateLayer::getDrawingSurfaceDamage() const {
- return getDrawingState().surfaceDamageRegion;
-}
-
-const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const {
- return getDrawingState().hdrMetadata;
-}
-
-int BufferStateLayer::getDrawingApi() const {
- return getDrawingState().api;
-}
-
-PixelFormat BufferStateLayer::getPixelFormat() const {
- if (!mActiveBuffer) {
- return PIXEL_FORMAT_NONE;
- }
- return mActiveBuffer->format;
-}
-
uint64_t BufferStateLayer::getFrameNumber(nsecs_t /*expectedPresentTime*/) const {
return mFrameNumber;
}
@@ -506,8 +433,8 @@
}
void BufferStateLayer::setFilteringEnabled(bool enabled) {
- GLConsumer::computeTransformMatrix(mTransformMatrix.data(), mActiveBuffer, mCurrentCrop,
- mCurrentTransform, enabled);
+ GLConsumer::computeTransformMatrix(mTransformMatrix.data(), mBufferInfo.mBuffer,
+ mBufferInfo.mCrop, mBufferInfo.mTransform, enabled);
}
status_t BufferStateLayer::bindTextureImage() {
@@ -576,8 +503,8 @@
}
const uint64_t bufferID = getCurrentBufferId();
- mFlinger->mTimeStats->setAcquireFence(layerID, mFrameNumber, getCurrentFenceTime());
- mFlinger->mFrameTracer->traceFence(layerID, bufferID, mFrameNumber, getCurrentFenceTime(),
+ mFlinger->mTimeStats->setAcquireFence(layerID, mFrameNumber, mBufferInfo.mFenceTime);
+ mFlinger->mFrameTracer->traceFence(layerID, bufferID, mFrameNumber, mBufferInfo.mFenceTime,
FrameTracer::FrameEvent::ACQUIRE_FENCE);
mFlinger->mTimeStats->setLatchTime(layerID, mFrameNumber, latchTime);
mFlinger->mFrameTracer->traceTimestamp(layerID, bufferID, mFrameNumber, latchTime,
@@ -596,10 +523,10 @@
}
mPreviousBufferId = getCurrentBufferId();
- mActiveBuffer = s.buffer;
- mActiveBufferFence = s.acquireFence;
+ mBufferInfo.mBuffer = s.buffer;
+ mBufferInfo.mFence = s.acquireFence;
auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
- layerCompositionState.buffer = mActiveBuffer;
+ layerCompositionState.buffer = mBufferInfo.mBuffer;
return NO_ERROR;
}
@@ -622,7 +549,7 @@
compositionState.buffer = s.buffer;
compositionState.bufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
- compositionState.acquireFence = s.acquireFence;
+ compositionState.acquireFence = mBufferInfo.mFence;
mFrameNumber++;
}
@@ -707,4 +634,48 @@
mFreeHwcCacheSlots.push(hwcCacheSlot);
mCachedBuffers.erase(clientCacheId);
}
+
+void BufferStateLayer::gatherBufferInfo() {
+ const State& s(getDrawingState());
+
+ mBufferInfo.mDesiredPresentTime = s.desiredPresentTime;
+ mBufferInfo.mFenceTime = std::make_shared<FenceTime>(s.acquireFence);
+ mBufferInfo.mFence = s.acquireFence;
+ std::copy(std::begin(mTransformMatrix), std::end(mTransformMatrix),
+ mBufferInfo.mTransformMatrix);
+ mBufferInfo.mTransform = s.transform;
+ mBufferInfo.mDataspace = translateDataspace(s.dataspace);
+ mBufferInfo.mCrop = computeCrop(s);
+ mBufferInfo.mScaleMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
+ 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;
+}
+
+Rect BufferStateLayer::computeCrop(const State& s) {
+ if (s.crop.isEmpty() && s.buffer) {
+ return s.buffer->getBounds();
+ } else if (s.buffer) {
+ Rect crop = s.crop;
+ crop.left = std::max(crop.left, 0);
+ crop.top = std::max(crop.top, 0);
+ uint32_t bufferWidth = s.buffer->getWidth();
+ uint32_t bufferHeight = s.buffer->getHeight();
+ if (bufferHeight <= std::numeric_limits<int32_t>::max() &&
+ bufferWidth <= std::numeric_limits<int32_t>::max()) {
+ crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth));
+ crop.bottom = std::min(crop.bottom, static_cast<int32_t>(bufferHeight));
+ }
+ if (!crop.isValid()) {
+ // Crop rect is out of bounds, return whole buffer
+ return s.buffer->getBounds();
+ }
+ return crop;
+ }
+ return s.crop;
+}
+
} // namespace android
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index c060ca8..0b27d64 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -48,8 +48,6 @@
bool shouldPresentNow(nsecs_t expectedPresentTime) const override;
- bool getTransformToDisplayInverse() const override;
-
uint32_t doTransactionResize(uint32_t flags, Layer::State* /*stateToCommit*/) override {
return flags;
}
@@ -82,13 +80,13 @@
// Override to ignore legacy layer state properties that are not used by BufferStateLayer
bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; }
- bool setPosition(float /*x*/, float /*y*/, bool /*immediate*/) override { return false; }
+ bool setPosition(float /*x*/, float /*y*/) override { return false; }
bool setTransparentRegionHint(const Region& transparent) override;
bool setMatrix(const layer_state_t::matrix22_t& /*matrix*/,
bool /*allowNonRectPreservingTransforms*/) override {
return false;
}
- bool setCrop_legacy(const Rect& /*crop*/, bool /*immediate*/) override { return false; }
+ bool setCrop_legacy(const Rect& /*crop*/) override { return false; }
bool setOverrideScalingMode(int32_t /*overrideScalingMode*/) override { return false; }
void deferTransactionUntil_legacy(const sp<IBinder>& /*barrierHandle*/,
uint64_t /*frameNumber*/) override {}
@@ -106,19 +104,10 @@
bool fenceHasSignaled() const override;
bool framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const override;
-private:
- nsecs_t getDesiredPresentTime() override;
- std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
+protected:
+ void gatherBufferInfo() override;
- void getDrawingTransformMatrix(float *matrix) override;
- uint32_t getDrawingTransform() const override;
- ui::Dataspace getDrawingDataSpace() const override;
- Rect getDrawingCrop() const override;
- uint32_t getDrawingScalingMode() const override;
- Region getDrawingSurfaceDamage() const override;
- const HdrMetadata& getDrawingHdrMetadata() const override;
- int getDrawingApi() const override;
- PixelFormat getPixelFormat() const override;
+private:
uint64_t getFrameNumber(nsecs_t expectedPresentTime) const override;
@@ -140,6 +129,9 @@
void latchPerFrameState(compositionengine::LayerFECompositionState&) const override;
+ // Crop that applies to the buffer
+ Rect computeCrop(const State& s);
+
private:
friend class SlotGenerationTest;
void onFirstRef() override;
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 2ad7591..49b1810 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -99,11 +99,6 @@
compositionState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
}
-void ColorLayer::commitTransaction(const State& stateToCommit) {
- Layer::commitTransaction(stateToCommit);
- mCurrentDataSpace = mDrawingState.dataspace;
-}
-
std::shared_ptr<compositionengine::Layer> ColorLayer::getCompositionLayer() const {
return mCompositionLayer;
}
@@ -112,6 +107,10 @@
return (s.flags & layer_state_t::eLayerOpaque) != 0;
}
+ui::Dataspace ColorLayer::getDataSpace() const {
+ return mDrawingState.dataspace;
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 57c54c7..16921df 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -37,7 +37,7 @@
bool setDataspace(ui::Dataspace dataspace) override;
- void commitTransaction(const State& stateToCommit) override;
+ ui::Dataspace getDataSpace() const override;
bool isOpaque(const Layer::State& s) const override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index db4f969..57cca69 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -39,9 +39,26 @@
// process.
virtual bool onPreComposition(nsecs_t refreshStartTime) = 0;
- // Latches the output-independent state. If includeGeometry is false, the
- // geometry state can be skipped.
- virtual void latchCompositionState(LayerFECompositionState&, bool includeGeometry) const = 0;
+ // Used with latchCompositionState()
+ enum class StateSubset {
+ // Gets the basic geometry (bounds, transparent region, visibility,
+ // transforms, alpha) for the layer, for computing visibility and
+ // coverage.
+ BasicGeometry,
+
+ // Gets the full geometry (crops, buffer transforms, metadata) and
+ // content (buffer or color) state for the layer.
+ GeometryAndContent,
+
+ // Gets the per frame content (buffer or color) state the layer.
+ Content,
+ };
+
+ // Latches the output-independent composition state for the layer. The
+ // StateSubset argument selects what portion of the state is actually needed
+ // by the CompositionEngine code, since computing everything may be
+ // expensive.
+ virtual void latchCompositionState(LayerFECompositionState&, StateSubset) const = 0;
// Latches the minimal bit of state for the cursor for a fast asynchronous
// update.
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index b066cd1..530f49a 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -40,6 +40,45 @@
// the next geometry change.
bool forceClientComposition{false};
+ // TODO(b/121291683): Reorganize and rename the contents of this structure
+
+ /*
+ * Visibility state
+ */
+ // the layer stack this layer belongs to
+ std::optional<uint32_t> layerStackId;
+
+ // If true, this layer should be only visible on the internal display
+ bool internalOnly{false};
+
+ // If false, this layer should not be considered visible
+ bool isVisible{true};
+
+ // True if the layer is completely opaque
+ bool isOpaque{true};
+
+ // If true, invalidates the entire visible region
+ bool contentDirty{false};
+
+ // The alpha value for this layer
+ float alpha{1.f};
+
+ // The transform from layer local coordinates to composition coordinates
+ ui::Transform geomLayerTransform;
+
+ // The inverse of the layer transform
+ ui::Transform geomInverseLayerTransform;
+
+ // The hint from the layer producer as to what portion of the layer is
+ // transparent.
+ Region transparentRegionHint;
+
+ // The blend mode for this layer
+ Hwc2::IComposerClient::BlendMode blendMode{Hwc2::IComposerClient::BlendMode::INVALID};
+
+ // The bounds of the layer in layer local coordinates
+ FloatRect geomLayerBounds;
+
/*
* Geometry state
*/
@@ -48,23 +87,9 @@
bool geomUsesSourceCrop{false};
bool geomBufferUsesDisplayInverseTransform{false};
uint32_t geomBufferTransform{0};
- ui::Transform geomLayerTransform;
- ui::Transform geomInverseLayerTransform;
Rect geomBufferSize;
Rect geomContentCrop;
Rect geomCrop;
- Region geomActiveTransparentRegion;
- FloatRect geomLayerBounds;
-
- /*
- * Presentation
- */
-
- // The blend mode for this layer
- Hwc2::IComposerClient::BlendMode blendMode{Hwc2::IComposerClient::BlendMode::INVALID};
-
- // The alpha value for this layer
- float alpha{1.f};
/*
* Extra metadata
@@ -113,9 +138,6 @@
mat4 colorTransform;
bool colorTransformIsIdentity{true};
- // True if the layer is completely opaque
- bool isOpaque{true};
-
// True if the layer has protected content
bool hasProtectedContent{false};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index a509ca8..2e44c07 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -132,17 +132,20 @@
// A layer belongs to the output if its layerStackId matches. Additionally
// if the layer should only show in the internal (primary) display only and
// this output allows that.
- virtual bool belongsInOutput(uint32_t layerStackId, bool internalOnly) const = 0;
+ virtual bool belongsInOutput(std::optional<uint32_t> layerStackId, bool internalOnly) const = 0;
// Returns a pointer to the output layer corresponding to the given layer on
// this output, or nullptr if the layer does not have one
virtual OutputLayer* getOutputLayerForLayer(Layer*) const = 0;
+ // Creates an OutputLayer instance for this output
+ virtual std::unique_ptr<OutputLayer> createOutputLayer(const std::shared_ptr<Layer>&,
+ const sp<LayerFE>&) const = 0;
+
// Gets the OutputLayer corresponding to the input Layer instance from the
// current ordered set of output layers. If there is no such layer, a new
// one is created and returned.
- virtual std::unique_ptr<OutputLayer> getOrCreateOutputLayer(std::optional<DisplayId>,
- std::shared_ptr<Layer>,
+ virtual std::unique_ptr<OutputLayer> getOrCreateOutputLayer(std::shared_ptr<Layer>,
sp<LayerFE>) = 0;
// Sets the new ordered set of output layers for this output
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
index cedd728..389b605 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
@@ -48,6 +48,9 @@
public:
virtual ~OutputLayer();
+ // Sets the HWC2::Layer associated with this layer
+ virtual void setHwcLayer(std::shared_ptr<HWC2::Layer>) = 0;
+
// Gets the output which owns this output layer
virtual const Output& getOutput() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index bd1aa08..2e595d6 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -40,6 +40,8 @@
// compositionengine::Output overrides
void dump(std::string&) const override;
+ std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
+ const std::shared_ptr<Layer>&, const sp<LayerFE>&) const override;
void setColorTransform(const compositionengine::CompositionRefreshArgs&) override;
void setColorProfile(const ColorProfile&) override;
void chooseCompositionStrategy() override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index d826161..bdb35c2 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -62,13 +62,14 @@
OutputCompositionState& editState() override;
Region getDirtyRegion(bool repaintEverything) const override;
- bool belongsInOutput(uint32_t, bool) const override;
+ bool belongsInOutput(std::optional<uint32_t>, bool) const override;
compositionengine::OutputLayer* getOutputLayerForLayer(
compositionengine::Layer*) const override;
+ std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
+ const std::shared_ptr<Layer>&, const sp<LayerFE>&) const override;
std::unique_ptr<compositionengine::OutputLayer> getOrCreateOutputLayer(
- std::optional<DisplayId>, std::shared_ptr<compositionengine::Layer>,
- sp<LayerFE>) override;
+ std::shared_ptr<compositionengine::Layer>, sp<LayerFE>) override;
void setOutputLayersOrderedByZ(OutputLayers&&) override;
const OutputLayers& getOutputLayersOrderedByZ() const override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
index fa4d8cd..1199fea 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
@@ -34,11 +34,11 @@
class OutputLayer : public compositionengine::OutputLayer {
public:
- OutputLayer(const compositionengine::Output&, std::shared_ptr<compositionengine::Layer>,
- sp<compositionengine::LayerFE>);
+ OutputLayer(const compositionengine::Output&, const std::shared_ptr<compositionengine::Layer>&,
+ const sp<compositionengine::LayerFE>&);
~OutputLayer() override;
- void initialize(const CompositionEngine&, std::optional<DisplayId>);
+ void setHwcLayer(std::shared_ptr<HWC2::Layer>) override;
const compositionengine::Output& getOutput() const override;
compositionengine::Layer& getLayer() const override;
@@ -86,8 +86,8 @@
};
std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
- const CompositionEngine&, std::optional<DisplayId>, const compositionengine::Output&,
- std::shared_ptr<compositionengine::Layer>, sp<compositionengine::LayerFE>);
+ const compositionengine::Output&, const std::shared_ptr<compositionengine::Layer>&,
+ const sp<compositionengine::LayerFE>&);
} // namespace impl
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index e280295..3eada3c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -32,7 +32,8 @@
MOCK_METHOD1(onPreComposition, bool(nsecs_t));
- MOCK_CONST_METHOD2(latchCompositionState, void(LayerFECompositionState&, bool));
+ MOCK_CONST_METHOD2(latchCompositionState,
+ void(LayerFECompositionState&, compositionengine::LayerFE::StateSubset));
MOCK_CONST_METHOD1(latchCursorCompositionState, void(LayerFECompositionState&));
MOCK_METHOD1(prepareClientComposition,
std::optional<renderengine::LayerSettings>(
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index 33925d5..93274e7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -59,13 +59,17 @@
MOCK_METHOD0(editState, OutputCompositionState&());
MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
- MOCK_CONST_METHOD2(belongsInOutput, bool(uint32_t, bool));
+ MOCK_CONST_METHOD2(belongsInOutput, bool(std::optional<uint32_t>, bool));
MOCK_CONST_METHOD1(getOutputLayerForLayer,
compositionengine::OutputLayer*(compositionengine::Layer*));
- MOCK_METHOD3(getOrCreateOutputLayer,
+ MOCK_CONST_METHOD2(createOutputLayer,
+ std::unique_ptr<compositionengine::OutputLayer>(
+ const std::shared_ptr<compositionengine::Layer>&,
+ const sp<compositionengine::LayerFE>&));
+ MOCK_METHOD2(getOrCreateOutputLayer,
std::unique_ptr<compositionengine::OutputLayer>(
- std::optional<DisplayId>, std::shared_ptr<compositionengine::Layer>,
+ std::shared_ptr<compositionengine::Layer>,
sp<compositionengine::LayerFE>));
MOCK_METHOD1(setOutputLayersOrderedByZ, void(OutputLayers&&));
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
index 6b2224a..4f2afac 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
@@ -31,6 +31,8 @@
OutputLayer();
virtual ~OutputLayer();
+ MOCK_METHOD1(setHwcLayer, void(std::shared_ptr<HWC2::Layer>));
+
MOCK_CONST_METHOD0(getOutput, const compositionengine::Output&());
MOCK_CONST_METHOD0(getLayer, compositionengine::Layer&());
MOCK_CONST_METHOD0(getLayerFE, compositionengine::LayerFE&());
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 000a294..49727df 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -19,6 +19,7 @@
#include <compositionengine/CompositionRefreshArgs.h>
#include <compositionengine/DisplayCreationArgs.h>
#include <compositionengine/DisplaySurface.h>
+#include <compositionengine/LayerFE.h>
#include <compositionengine/impl/Display.h>
#include <compositionengine/impl/DisplayColorProfile.h>
#include <compositionengine/impl/DumpHelpers.h>
@@ -133,6 +134,30 @@
std::move(args)));
}
+std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
+ const std::shared_ptr<compositionengine::Layer>& layer,
+ const sp<compositionengine::LayerFE>& layerFE) const {
+ auto result = Output::createOutputLayer(layer, layerFE);
+
+ if (result && mId) {
+ auto& hwc = getCompositionEngine().getHwComposer();
+ auto displayId = *mId;
+ // Note: For the moment we ensure it is safe to take a reference to the
+ // HWComposer implementation by destroying all the OutputLayers (and
+ // hence the HWC2::Layers they own) before setting a new HWComposer. See
+ // for example SurfaceFlinger::updateVrFlinger().
+ // TODO(b/121291683): Make this safer.
+ auto hwcLayer = std::shared_ptr<HWC2::Layer>(hwc.createLayer(displayId),
+ [&hwc, displayId](HWC2::Layer* layer) {
+ hwc.destroyLayer(displayId, layer);
+ });
+ ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
+ getName().c_str());
+ result->setHwcLayer(std::move(hwcLayer));
+ }
+ return result;
+}
+
void Display::chooseCompositionStrategy() {
ATRACE_CALL();
ALOGV(__FUNCTION__);
diff --git a/services/surfaceflinger/CompositionEngine/src/LayerCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerCompositionState.cpp
index 0dc4bf1..c5debf6 100644
--- a/services/surfaceflinger/CompositionEngine/src/LayerCompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/LayerCompositionState.cpp
@@ -45,7 +45,7 @@
dumpVal(out, "geomBufferTransform", state.geomBufferTransform);
out.append("\n ");
- dumpVal(out, "geomActiveTransparentRegion", state.geomActiveTransparentRegion);
+ dumpVal(out, "transparentRegionHint", state.transparentRegionHint);
out.append(" ");
dumpVal(out, "geomLayerBounds", state.geomLayerBounds);
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 9f4f259..cb04e95 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -212,10 +212,11 @@
return dirty;
}
-bool Output::belongsInOutput(uint32_t layerStackId, bool internalOnly) const {
+bool Output::belongsInOutput(std::optional<uint32_t> layerStackId, bool internalOnly) const {
// The layerStackId's must match, and also the layer must not be internal
// only when not on an internal output.
- return (layerStackId == mState.layerStackId) && (!internalOnly || mState.layerStackInternal);
+ return layerStackId && (*layerStackId == mState.layerStackId) &&
+ (!internalOnly || mState.layerStackInternal);
}
compositionengine::OutputLayer* Output::getOutputLayerForLayer(
@@ -229,14 +230,20 @@
}
std::unique_ptr<compositionengine::OutputLayer> Output::getOrCreateOutputLayer(
- std::optional<DisplayId> displayId, std::shared_ptr<compositionengine::Layer> layer,
- sp<compositionengine::LayerFE> layerFE) {
+ std::shared_ptr<compositionengine::Layer> layer, sp<compositionengine::LayerFE> layerFE) {
for (auto& outputLayer : mOutputLayersOrderedByZ) {
if (outputLayer && &outputLayer->getLayer() == layer.get()) {
return std::move(outputLayer);
}
}
- return createOutputLayer(mCompositionEngine, displayId, *this, layer, layerFE);
+
+ return createOutputLayer(layer, layerFE);
+}
+
+std::unique_ptr<compositionengine::OutputLayer> Output::createOutputLayer(
+ const std::shared_ptr<compositionengine::Layer>& layer,
+ const sp<compositionengine::LayerFE>& layerFE) const {
+ return impl::createOutputLayer(*this, layer, layerFE);
}
void Output::setOutputLayersOrderedByZ(OutputLayers&& layers) {
@@ -281,7 +288,9 @@
void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const {
for (auto& layer : mOutputLayersOrderedByZ) {
layer->getLayerFE().latchCompositionState(layer->getLayer().editState().frontEnd,
- args.updatingGeometryThisFrame);
+ args.updatingGeometryThisFrame
+ ? LayerFE::StateSubset::GeometryAndContent
+ : LayerFE::StateSubset::Content);
}
}
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 21f0ce8..4eb256f 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -15,7 +15,6 @@
*/
#include <android-base/stringprintf.h>
-#include <compositionengine/CompositionEngine.h>
#include <compositionengine/DisplayColorProfile.h>
#include <compositionengine/Layer.h>
#include <compositionengine/LayerFE.h>
@@ -46,31 +45,24 @@
} // namespace
std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
- const CompositionEngine& compositionEngine, std::optional<DisplayId> displayId,
- const compositionengine::Output& output, std::shared_ptr<compositionengine::Layer> layer,
- sp<compositionengine::LayerFE> layerFE) {
- auto result = std::make_unique<OutputLayer>(output, layer, layerFE);
- result->initialize(compositionEngine, displayId);
- return result;
+ const compositionengine::Output& output,
+ const std::shared_ptr<compositionengine::Layer>& layer,
+ const sp<compositionengine::LayerFE>& layerFE) {
+ return std::make_unique<OutputLayer>(output, layer, layerFE);
}
-OutputLayer::OutputLayer(const Output& output, std::shared_ptr<Layer> layer, sp<LayerFE> layerFE)
+OutputLayer::OutputLayer(const Output& output, const std::shared_ptr<Layer>& layer,
+ const sp<LayerFE>& layerFE)
: mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
OutputLayer::~OutputLayer() = default;
-void OutputLayer::initialize(const CompositionEngine& compositionEngine,
- std::optional<DisplayId> displayId) {
- if (!displayId) {
- return;
+void OutputLayer::setHwcLayer(std::shared_ptr<HWC2::Layer> hwcLayer) {
+ if (hwcLayer) {
+ mState.hwc.emplace(hwcLayer);
+ } else {
+ mState.hwc.reset();
}
-
- auto& hwc = compositionEngine.getHwComposer();
-
- mState.hwc.emplace(std::shared_ptr<HWC2::Layer>(hwc.createLayer(*displayId),
- [&hwc, displayId](HWC2::Layer* layer) {
- hwc.destroyLayer(*displayId, layer);
- }));
}
const compositionengine::Output& OutputLayer::getOutput() const {
@@ -102,7 +94,7 @@
// pixels in the buffer.
FloatRect activeCropFloat =
- reduce(layerState.geomLayerBounds, layerState.geomActiveTransparentRegion);
+ reduce(layerState.geomLayerBounds, layerState.transparentRegionHint);
const Rect& viewport = mOutput.getState().viewport;
const ui::Transform& layerTransform = layerState.geomLayerTransform;
@@ -209,7 +201,7 @@
// apply the layer's transform, followed by the display's global transform
// here we're guaranteed that the layer's transform preserves rects
- Region activeTransparentRegion = layerState.geomActiveTransparentRegion;
+ Region activeTransparentRegion = layerState.transparentRegionHint;
const ui::Transform& layerTransform = layerState.geomLayerTransform;
const ui::Transform& inverseLayerTransform = layerState.geomInverseLayerTransform;
const Rect& bufferSize = layerState.geomBufferSize;
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 008e631..6821ec1 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -23,6 +23,8 @@
#include <compositionengine/impl/Display.h>
#include <compositionengine/mock/CompositionEngine.h>
#include <compositionengine/mock/DisplayColorProfile.h>
+#include <compositionengine/mock/Layer.h>
+#include <compositionengine/mock/LayerFE.h>
#include <compositionengine/mock/NativeWindow.h>
#include <compositionengine/mock/OutputLayer.h>
#include <compositionengine/mock/RenderSurface.h>
@@ -256,6 +258,25 @@
}
/*
+ * Display::createOutputLayer()
+ */
+
+TEST_F(DisplayTest, createOutputLayerSetsHwcLayer) {
+ sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
+ auto layer = std::make_shared<StrictMock<mock::Layer>>();
+ StrictMock<HWC2::mock::Layer> hwcLayer;
+
+ EXPECT_CALL(mHwComposer, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
+
+ auto outputLayer = mDisplay.createOutputLayer(layer, layerFE);
+
+ EXPECT_EQ(&hwcLayer, outputLayer->getHwcLayer());
+
+ EXPECT_CALL(mHwComposer, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
+ outputLayer.reset();
+}
+
+/*
* Display::chooseCompositionStrategy()
*/
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 2276dc3..b73c47b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -36,8 +36,6 @@
using testing::ReturnRef;
using testing::StrictMock;
-constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
-
constexpr auto TR_IDENT = 0u;
constexpr auto TR_FLP_H = HAL_TRANSFORM_FLIP_H;
constexpr auto TR_FLP_V = HAL_TRANSFORM_FLIP_V;
@@ -83,35 +81,27 @@
TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
/*
- * OutputLayer::initialize()
+ * OutputLayer::setHwcLayer()
*/
-TEST_F(OutputLayerTest, initializingOutputLayerWithoutHwcDoesNothingInteresting) {
+TEST_F(OutputLayerTest, settingNullHwcLayerSetsEmptyHwcState) {
StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
- mOutputLayer.initialize(compositionEngine, std::nullopt);
+ mOutputLayer.setHwcLayer(nullptr);
EXPECT_FALSE(mOutputLayer.getState().hwc);
}
-TEST_F(OutputLayerTest, initializingOutputLayerWithHwcDisplayCreatesHwcLayer) {
- StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
- StrictMock<android::mock::HWComposer> hwc;
- StrictMock<HWC2::mock::Layer> hwcLayer;
+TEST_F(OutputLayerTest, settingHwcLayerSetsHwcState) {
+ auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
- EXPECT_CALL(compositionEngine, getHwComposer()).WillOnce(ReturnRef(hwc));
- EXPECT_CALL(hwc, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
-
- mOutputLayer.initialize(compositionEngine, DEFAULT_DISPLAY_ID);
+ mOutputLayer.setHwcLayer(hwcLayer);
const auto& outputLayerState = mOutputLayer.getState();
ASSERT_TRUE(outputLayerState.hwc);
const auto& hwcState = *outputLayerState.hwc;
- EXPECT_EQ(&hwcLayer, hwcState.hwcLayer.get());
-
- EXPECT_CALL(hwc, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
- mOutputLayer.editState().hwc.reset();
+ EXPECT_EQ(hwcLayer, hwcState.hwcLayer);
}
/*
@@ -124,7 +114,7 @@
// set one specific value to something different.
mLayerState.frontEnd.geomUsesSourceCrop = true;
mLayerState.frontEnd.geomContentCrop = Rect{0, 0, 1920, 1080};
- mLayerState.frontEnd.geomActiveTransparentRegion = Region{};
+ mLayerState.frontEnd.transparentRegionHint = Region{};
mLayerState.frontEnd.geomLayerBounds = FloatRect{0.f, 0.f, 1920.f, 1080.f};
mLayerState.frontEnd.geomLayerTransform = ui::Transform{TR_IDENT};
mLayerState.frontEnd.geomBufferSize = Rect{0, 0, 1920, 1080};
@@ -231,7 +221,7 @@
// Set reasonable default values for a simple case. Each test will
// set one specific value to something different.
- mLayerState.frontEnd.geomActiveTransparentRegion = Region{};
+ mLayerState.frontEnd.transparentRegionHint = Region{};
mLayerState.frontEnd.geomLayerTransform = ui::Transform{TR_IDENT};
mLayerState.frontEnd.geomBufferSize = Rect{0, 0, 1920, 1080};
mLayerState.frontEnd.geomBufferUsesDisplayInverseTransform = false;
@@ -256,7 +246,7 @@
}
TEST_F(OutputLayerDisplayFrameTest, fullActiveTransparentRegionReturnsEmptyFrame) {
- mLayerState.frontEnd.geomActiveTransparentRegion = Region{Rect{0, 0, 1920, 1080}};
+ mLayerState.frontEnd.transparentRegionHint = Region{Rect{0, 0, 1920, 1080}};
const Rect expected{0, 0, 0, 0};
EXPECT_THAT(calculateOutputDisplayFrame(), RectEq(expected));
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index b0e8e36..10ec1ee 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -356,6 +356,10 @@
// If the output accepts layerStack1 and internal-only layers....
mOutput.setLayerStackFilter(layerStack1, true);
+ // A layer with no layerStack does not belong to it, internal-only or not.
+ EXPECT_FALSE(mOutput.belongsInOutput(std::nullopt, false));
+ EXPECT_FALSE(mOutput.belongsInOutput(std::nullopt, true));
+
// Any layer with layerStack1 belongs to it, internal-only or not.
EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, false));
EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, true));
@@ -425,7 +429,7 @@
// If there is no OutputLayer corresponding to the input layer, a
// new OutputLayer is constructed and returned.
EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(otherLayer));
- auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
+ auto result = mOutput.getOrCreateOutputLayer(layer, layerFE);
EXPECT_NE(existingOutputLayer, result.get());
EXPECT_TRUE(result.get() != nullptr);
EXPECT_EQ(layer.get(), &result->getLayer());
@@ -441,7 +445,7 @@
// If there is an existing OutputLayer for the requested layer, an owned
// pointer is returned
EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(*layer));
- auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
+ auto result = mOutput.getOrCreateOutputLayer(layer, layerFE);
EXPECT_EQ(existingOutputLayer, result.get());
// The corresponding entry in the ordered array should be cleared.
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5e5302d..8f6672c 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -78,7 +78,6 @@
mName(args.name),
mClientRef(args.client),
mWindowType(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0)) {
- mCurrentCrop.makeInvalid();
uint32_t layerFlags = 0;
if (args.flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;
@@ -259,23 +258,6 @@
// h/w composer set-up
// ---------------------------------------------------------------------------
-Rect Layer::getContentCrop() const {
- // this is the crop rectangle that applies to the buffer
- // itself (as opposed to the window)
- Rect crop;
- if (!mCurrentCrop.isEmpty()) {
- // if the buffer crop is defined, we use that
- crop = mCurrentCrop;
- } else if (mActiveBuffer != nullptr) {
- // otherwise we use the whole buffer
- crop = mActiveBuffer->getBounds();
- } else {
- // if we don't have a buffer yet, we use an empty/invalid crop
- crop.makeInvalid();
- }
- return crop;
-}
-
static Rect reduce(const Rect& win, const Region& exclude) {
if (CC_LIKELY(exclude.isEmpty())) {
return win;
@@ -320,7 +302,7 @@
// If the layer is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
// it isFixedSize) then there may be additional scaling not accounted
// for in the layer transform.
- if (!isFixedSize() || !mActiveBuffer) {
+ if (!isFixedSize() || getBuffer() == nullptr) {
return {};
}
@@ -332,10 +314,10 @@
return {};
}
- int bufferWidth = mActiveBuffer->getWidth();
- int bufferHeight = mActiveBuffer->getHeight();
+ int bufferWidth = getBuffer()->getWidth();
+ int bufferHeight = getBuffer()->getHeight();
- if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ if (getBufferTransform() & NATIVE_WINDOW_TRANSFORM_ROT_90) {
std::swap(bufferWidth, bufferHeight);
}
@@ -350,7 +332,7 @@
ui::Transform Layer::getTransformWithScale(const ui::Transform& bufferScaleTransform) const {
// We need to mirror this scaling to child surfaces or we will break the contract where WM can
// treat child surfaces as pixels in the parent surface.
- if (!isFixedSize() || !mActiveBuffer) {
+ if (!isFixedSize() || getBuffer() == nullptr) {
return mEffectiveTransform;
}
return mEffectiveTransform * bufferScaleTransform;
@@ -359,7 +341,7 @@
FloatRect Layer::getBoundsPreScaling(const ui::Transform& bufferScaleTransform) const {
// We need the pre scaled layer bounds when computing child bounds to make sure the child is
// cropped to its parent layer after any buffer transform scaling is applied.
- if (!isFixedSize() || !mActiveBuffer) {
+ if (!isFixedSize() || getBuffer() == nullptr) {
return mBounds;
}
return bufferScaleTransform.inverse().transform(mBounds);
@@ -417,14 +399,43 @@
win.bottom -= roundedCornersCrop.top;
}
+void Layer::latchBasicGeometry(compositionengine::LayerFECompositionState& compositionState) const {
+ const auto& drawingState{getDrawingState()};
+ const uint32_t layerStack = getLayerStack();
+ const auto alpha = static_cast<float>(getAlpha());
+ const bool opaque = isOpaque(drawingState);
+ const bool usesRoundedCorners = getRoundedCornerState().radius != 0.f;
+
+ auto blendMode = Hwc2::IComposerClient::BlendMode::NONE;
+ if (!opaque || alpha != 1.0f) {
+ blendMode = mPremultipliedAlpha ? Hwc2::IComposerClient::BlendMode::PREMULTIPLIED
+ : Hwc2::IComposerClient::BlendMode::COVERAGE;
+ }
+
+ // TODO(b/121291683): Instead of filling in a passed-in compositionState
+ // structure, switch to Layer owning the structure and have
+ // CompositionEngine be able to get a reference to it.
+
+ compositionState.layerStackId =
+ (layerStack != ~0u) ? std::make_optional(layerStack) : std::nullopt;
+ compositionState.internalOnly = getPrimaryDisplayOnly();
+ compositionState.isVisible = isVisible();
+ compositionState.isOpaque = opaque && !usesRoundedCorners && alpha == 1.f;
+
+ compositionState.contentDirty = contentDirty;
+ contentDirty = false;
+
+ compositionState.geomLayerBounds = mBounds;
+ compositionState.geomLayerTransform = getTransform();
+ compositionState.geomInverseLayerTransform = compositionState.geomLayerTransform.inverse();
+ compositionState.transparentRegionHint = getActiveTransparentRegion(drawingState);
+
+ compositionState.blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode);
+ compositionState.alpha = alpha;
+}
+
void Layer::latchGeometry(compositionengine::LayerFECompositionState& compositionState) const {
const auto& drawingState{getDrawingState()};
- auto alpha = static_cast<float>(getAlpha());
- auto blendMode = HWC2::BlendMode::None;
- if (!isOpaque(drawingState) || alpha != 1.0f) {
- blendMode =
- mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
- }
int type = drawingState.metadata.getInt32(METADATA_WINDOW_TYPE, 0);
int appId = drawingState.metadata.getInt32(METADATA_OWNER_UID, 0);
@@ -439,20 +450,14 @@
}
}
- compositionState.geomLayerTransform = getTransform();
- compositionState.geomInverseLayerTransform = compositionState.geomLayerTransform.inverse();
compositionState.geomBufferSize = getBufferSize(drawingState);
- compositionState.geomContentCrop = getContentCrop();
+ compositionState.geomContentCrop = getBufferCrop();
compositionState.geomCrop = getCrop(drawingState);
- compositionState.geomBufferTransform = mCurrentTransform;
+ compositionState.geomBufferTransform = getBufferTransform();
compositionState.geomBufferUsesDisplayInverseTransform = getTransformToDisplayInverse();
- compositionState.geomActiveTransparentRegion = getActiveTransparentRegion(drawingState);
- compositionState.geomLayerBounds = mBounds;
compositionState.geomUsesSourceCrop = usesSourceCrop();
compositionState.isSecure = isSecure();
- compositionState.blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode);
- compositionState.alpha = alpha;
compositionState.type = type;
compositionState.appId = appId;
}
@@ -462,7 +467,7 @@
compositionState.forceClientComposition = false;
compositionState.isColorspaceAgnostic = isColorSpaceAgnostic();
- compositionState.dataspace = mCurrentDataSpace;
+ compositionState.dataspace = getDataSpace();
compositionState.colorTransform = getColorTransform();
compositionState.colorTransformIsIdentity = !hasColorTransform();
compositionState.surfaceDamage = surfaceDamageRegion;
@@ -498,12 +503,24 @@
}
void Layer::latchCompositionState(compositionengine::LayerFECompositionState& compositionState,
- bool includeGeometry) const {
- if (includeGeometry) {
- latchGeometry(compositionState);
- }
+ compositionengine::LayerFE::StateSubset subset) const {
+ using StateSubset = compositionengine::LayerFE::StateSubset;
- latchPerFrameState(compositionState);
+ switch (subset) {
+ case StateSubset::BasicGeometry:
+ latchBasicGeometry(compositionState);
+ break;
+
+ case StateSubset::GeometryAndContent:
+ latchBasicGeometry(compositionState);
+ latchGeometry(compositionState);
+ latchPerFrameState(compositionState);
+ break;
+
+ case StateSubset::Content:
+ latchPerFrameState(compositionState);
+ break;
+ }
}
const char* Layer::getDebugName() const {
@@ -539,7 +556,7 @@
layerSettings.geometry.roundedCornersCrop = roundedCornerState.cropRect;
layerSettings.alpha = alpha;
- layerSettings.sourceDataspace = mCurrentDataSpace;
+ layerSettings.sourceDataspace = getDataSpace();
return layerSettings;
}
@@ -701,7 +718,7 @@
" requested={ wh={%4u,%4u} }}\n"
" drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
" requested={ wh={%4u,%4u} }}\n",
- this, getName().string(), mCurrentTransform, getEffectiveScalingMode(),
+ this, getName().string(), getBufferTransform(), getEffectiveScalingMode(),
stateToCommit->active_legacy.w, stateToCommit->active_legacy.h,
stateToCommit->crop_legacy.left, stateToCommit->crop_legacy.top,
stateToCommit->crop_legacy.right, stateToCommit->crop_legacy.bottom,
@@ -733,7 +750,7 @@
const bool resizePending =
((stateToCommit->requested_legacy.w != stateToCommit->active_legacy.w) ||
(stateToCommit->requested_legacy.h != stateToCommit->active_legacy.h)) &&
- (mActiveBuffer != nullptr);
+ (getBuffer() != nullptr);
if (!isFixedSize()) {
if (resizePending && mSidebandStream == nullptr) {
flags |= eDontUpdateGeometryState;
@@ -746,11 +763,6 @@
if (!(flags & eDontUpdateGeometryState)) {
State& editCurrentState(getCurrentState());
- // If mFreezeGeometryUpdates is true we are in the setGeometryAppliesWithResize
- // mode, which causes attributes which normally latch regardless of scaling mode,
- // to be delayed. We copy the requested state to the active state making sure
- // to respect these rules (again see Layer.h for a detailed discussion).
- //
// There is an awkward asymmetry in the handling of the crop states in the position
// states, as can be seen below. Largely this arises from position and transform
// being stored in the same data structure while having different latching rules.
@@ -758,16 +770,8 @@
//
// Careful that "stateToCommit" and editCurrentState may not begin as equivalent due to
// applyPendingStates in the presence of deferred transactions.
- if (mFreezeGeometryUpdates) {
- float tx = stateToCommit->active_legacy.transform.tx();
- float ty = stateToCommit->active_legacy.transform.ty();
- stateToCommit->active_legacy = stateToCommit->requested_legacy;
- stateToCommit->active_legacy.transform.set(tx, ty);
- editCurrentState.active_legacy = stateToCommit->active_legacy;
- } else {
- editCurrentState.active_legacy = editCurrentState.requested_legacy;
- stateToCommit->active_legacy = stateToCommit->requested_legacy;
- }
+ editCurrentState.active_legacy = editCurrentState.requested_legacy;
+ stateToCommit->active_legacy = stateToCommit->requested_legacy;
}
return flags;
@@ -834,7 +838,7 @@
return mTransactionFlags.fetch_or(flags);
}
-bool Layer::setPosition(float x, float y, bool immediate) {
+bool Layer::setPosition(float x, float y) {
if (mCurrentState.requested_legacy.transform.tx() == x &&
mCurrentState.requested_legacy.transform.ty() == y)
return false;
@@ -844,14 +848,11 @@
// we want to apply the position portion of the transform matrix immediately,
// but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
mCurrentState.requested_legacy.transform.set(x, y);
- if (immediate && !mFreezeGeometryUpdates) {
- // Here we directly update the active state
- // unlike other setters, because we store it within
- // the transform, but use different latching rules.
- // b/38182305
- mCurrentState.active_legacy.transform.set(x, y);
- }
- mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
+ // Here we directly update the active state
+ // unlike other setters, because we store it within
+ // the transform, but use different latching rules.
+ // b/38182305
+ mCurrentState.active_legacy.transform.set(x, y);
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
@@ -1057,14 +1058,11 @@
return true;
}
-bool Layer::setCrop_legacy(const Rect& crop, bool immediate) {
+bool Layer::setCrop_legacy(const Rect& crop) {
if (mCurrentState.requestedCrop_legacy == crop) return false;
mCurrentState.sequence++;
mCurrentState.requestedCrop_legacy = crop;
- if (immediate && !mFreezeGeometryUpdates) {
- mCurrentState.crop_legacy = crop;
- }
- mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
+ mCurrentState.crop_legacy = crop;
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
@@ -1208,13 +1206,13 @@
info.mColor = ds.color;
info.mFlags = ds.flags;
info.mPixelFormat = getPixelFormat();
- info.mDataSpace = static_cast<android_dataspace>(mCurrentDataSpace);
+ info.mDataSpace = static_cast<android_dataspace>(getDataSpace());
info.mMatrix[0][0] = ds.active_legacy.transform[0][0];
info.mMatrix[0][1] = ds.active_legacy.transform[0][1];
info.mMatrix[1][0] = ds.active_legacy.transform[1][0];
info.mMatrix[1][1] = ds.active_legacy.transform[1][1];
{
- sp<const GraphicBuffer> buffer = mActiveBuffer;
+ sp<const GraphicBuffer> buffer = getBuffer();
if (buffer != 0) {
info.mActiveBufferWidth = buffer->getWidth();
info.mActiveBufferHeight = buffer->getHeight();
@@ -1527,8 +1525,9 @@
bool Layer::isLegacyDataSpace() const {
// return true when no higher bits are set
- return !(mCurrentDataSpace & (ui::Dataspace::STANDARD_MASK |
- ui::Dataspace::TRANSFER_MASK | ui::Dataspace::RANGE_MASK));
+ return !(getDataSpace() &
+ (ui::Dataspace::STANDARD_MASK | ui::Dataspace::TRANSFER_MASK |
+ ui::Dataspace::RANGE_MASK));
}
void Layer::setParent(const sp<Layer>& layer) {
@@ -1806,17 +1805,16 @@
}
}
- auto buffer = mActiveBuffer;
+ auto buffer = getBuffer();
if (buffer != nullptr) {
LayerProtoHelper::writeToProto(buffer,
[&]() { return layerInfo->mutable_active_buffer(); });
- LayerProtoHelper::writeToProto(ui::Transform(mCurrentTransform),
+ LayerProtoHelper::writeToProto(ui::Transform(getBufferTransform()),
layerInfo->mutable_buffer_transform());
}
layerInfo->set_invalidate(contentDirty);
layerInfo->set_is_protected(isProtected());
- layerInfo->set_dataspace(
- dataspaceDetails(static_cast<android_dataspace>(mCurrentDataSpace)));
+ layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(getDataSpace())));
layerInfo->set_queued_frames(getQueuedFrameCount());
layerInfo->set_refresh_pending(isBufferLatched());
layerInfo->set_curr_frame(mCurrentFrameNumber);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 1486efe..8771ccd 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -264,9 +264,9 @@
// setPosition operates in parent buffer space (pre parent-transform) or display
// space for top-level layers.
- virtual bool setPosition(float x, float y, bool immediate);
+ virtual bool setPosition(float x, float y);
// Buffer space
- virtual bool setCrop_legacy(const Rect& crop, bool immediate);
+ virtual bool setCrop_legacy(const Rect& crop);
// TODO(b/38182121): Could we eliminate the various latching modes by
// using the layer hierarchy?
@@ -326,7 +326,7 @@
virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace);
virtual bool setColorSpaceAgnostic(const bool agnostic);
- ui::Dataspace getDataSpace() const { return mCurrentDataSpace; }
+ virtual ui::Dataspace getDataSpace() const { return ui::Dataspace::UNKNOWN; }
// Before color management is introduced, contents on Android have to be
// desaturated in order to match what they appears like visually.
@@ -378,7 +378,7 @@
// creates its tracks by buffer id and has no way of associating a buffer back to the process
// that created it, the current implementation is only sufficient for cases where a buffer is
// only used within a single layer.
- uint64_t getCurrentBufferId() const { return mActiveBuffer ? mActiveBuffer->getId() : 0; }
+ uint64_t getCurrentBufferId() const { return getBuffer() ? getBuffer()->getId() : 0; }
// -----------------------------------------------------------------------
// Virtuals
@@ -471,7 +471,7 @@
*/
bool onPreComposition(nsecs_t) override;
void latchCompositionState(compositionengine::LayerFECompositionState&,
- bool includeGeometry) const override;
+ compositionengine::LayerFE::StateSubset subset) const override;
void latchCursorCompositionState(compositionengine::LayerFECompositionState&) const override;
std::optional<renderengine::LayerSettings> prepareClientComposition(
compositionengine::LayerFE::ClientCompositionTargetSettings&) override;
@@ -479,6 +479,7 @@
const char* getDebugName() const override;
protected:
+ void latchBasicGeometry(compositionengine::LayerFECompositionState& outState) const;
void latchGeometry(compositionengine::LayerFECompositionState& outState) const;
virtual void latchPerFrameState(compositionengine::LayerFECompositionState& outState) const;
@@ -559,7 +560,14 @@
* returns the rectangle that crops the content of the layer and scales it
* to the layer's size.
*/
- Rect getContentCrop() const;
+ virtual Rect getBufferCrop() const { return Rect(); }
+
+ /*
+ * Returns the transform applied to the buffer.
+ */
+ virtual uint32_t getBufferTransform() const { return 0; }
+
+ virtual sp<GraphicBuffer> getBuffer() const { return nullptr; }
/*
* Returns if a frame is ready
@@ -813,16 +821,10 @@
// main thread
sp<NativeHandle> mSidebandStream;
- // Active buffer fields
- sp<GraphicBuffer> mActiveBuffer;
- sp<Fence> mActiveBufferFence;
// False if the buffer and its contents have been previously used for GPU
// composition, true otherwise.
bool mIsActiveBufferUpdatedForGpu = true;
- ui::Dataspace mCurrentDataSpace = ui::Dataspace::UNKNOWN;
- Rect mCurrentCrop;
- uint32_t mCurrentTransform{0};
// We encode unset as -1.
int32_t mOverrideScalingMode{-1};
std::atomic<uint64_t> mCurrentFrameNumber{0};
@@ -843,8 +845,6 @@
// This layer can be a cursor on some displays.
bool mPotentialCursor{false};
- bool mFreezeGeometryUpdates{false};
-
// Child list about to be committed/used for editing.
LayerVector mCurrentChildren{LayerVector::StateSet::Current};
// Child list used for rendering.
diff --git a/services/surfaceflinger/LayerRejecter.cpp b/services/surfaceflinger/LayerRejecter.cpp
index 72abea8..8a22183 100644
--- a/services/surfaceflinger/LayerRejecter.cpp
+++ b/services/surfaceflinger/LayerRejecter.cpp
@@ -23,22 +23,16 @@
namespace android {
-LayerRejecter::LayerRejecter(Layer::State& front,
- Layer::State& current,
- bool& recomputeVisibleRegions,
- bool stickySet,
- const char* name,
- int32_t overrideScalingMode,
- bool transformToDisplayInverse,
- bool& freezePositionUpdates)
- : mFront(front),
- mCurrent(current),
- mRecomputeVisibleRegions(recomputeVisibleRegions),
- mStickyTransformSet(stickySet),
- mName(name),
- mOverrideScalingMode(overrideScalingMode),
- mTransformToDisplayInverse(transformToDisplayInverse),
- mFreezeGeometryUpdates(freezePositionUpdates) {}
+LayerRejecter::LayerRejecter(Layer::State& front, Layer::State& current,
+ bool& recomputeVisibleRegions, bool stickySet, const char* name,
+ int32_t overrideScalingMode, bool transformToDisplayInverse)
+ : mFront(front),
+ mCurrent(current),
+ mRecomputeVisibleRegions(recomputeVisibleRegions),
+ mStickyTransformSet(stickySet),
+ mName(name),
+ mOverrideScalingMode(overrideScalingMode),
+ mTransformToDisplayInverse(transformToDisplayInverse) {}
bool LayerRejecter::reject(const sp<GraphicBuffer>& buf, const BufferItem& item) {
if (buf == nullptr) {
@@ -83,8 +77,6 @@
// recompute visible region
mRecomputeVisibleRegions = true;
- mFreezeGeometryUpdates = false;
-
if (mFront.crop_legacy != mFront.requestedCrop_legacy) {
mFront.crop_legacy = mFront.requestedCrop_legacy;
mCurrent.crop_legacy = mFront.requestedCrop_legacy;
diff --git a/services/surfaceflinger/LayerRejecter.h b/services/surfaceflinger/LayerRejecter.h
index 63d51de..1bd0c26 100644
--- a/services/surfaceflinger/LayerRejecter.h
+++ b/services/surfaceflinger/LayerRejecter.h
@@ -23,14 +23,9 @@
namespace android {
class LayerRejecter : public BufferLayerConsumer::BufferRejecter {
public:
- LayerRejecter(Layer::State &front,
- Layer::State ¤t,
- bool &recomputeVisibleRegions,
- bool stickySet,
- const char *name,
- int32_t overrideScalingMode,
- bool transformToDisplayInverse,
- bool &freezePositionUpdates);
+ LayerRejecter(Layer::State &front, Layer::State ¤t, bool &recomputeVisibleRegions,
+ bool stickySet, const char *name, int32_t overrideScalingMode,
+ bool transformToDisplayInverse);
virtual bool reject(const sp<GraphicBuffer> &buf, const BufferItem &item);
@@ -42,7 +37,6 @@
const char *mName;
int32_t mOverrideScalingMode;
bool mTransformToDisplayInverse;
- bool &mFreezeGeometryUpdates;
};
} // namespace android
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 5b4bec9..976fedb 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -39,7 +39,7 @@
Mutex::Autolock _l(mFlinger.mStateLock);
mLayer = mClient->getLayerUser(mIBinder);
- mLayer->setCrop_legacy(Rect(50, 70, 200, 100), true);
+ mLayer->setCrop_legacy(Rect(50, 70, 200, 100));
// setting Layer's Z requires resorting layersSortedByZ
ssize_t idx = mFlinger.mCurrentState.layersSortedByZ.indexOf(mLayer);
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index eb52d3f..e2a880a 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -514,8 +514,13 @@
// Content detection is on, find the appropriate refresh rate with minimal error
// TODO(b/139751853): Scan allowed refresh rates only (SurfaceFlinger::mAllowedDisplayConfigs)
const float rate = static_cast<float>(mFeatures.contentRefreshRate);
- auto iter = min_element(mRefreshRateConfigs.getRefreshRates().cbegin(),
- mRefreshRateConfigs.getRefreshRates().cend(),
+ auto begin = mRefreshRateConfigs.getRefreshRates().cbegin();
+
+ // Skip POWER_SAVING config as it is not a real config
+ if (begin->first == RefreshRateType::POWER_SAVING) {
+ ++begin;
+ }
+ auto iter = min_element(begin, mRefreshRateConfigs.getRefreshRates().cend(),
[rate](const auto& lhs, const auto& rhs) -> bool {
return std::abs(lhs.second->fps - rate) <
std::abs(rhs.second->fps - rate);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3498419..4361a94 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -112,6 +112,7 @@
#include <cutils/compiler.h>
+#include "android-base/parseint.h"
#include "android-base/stringprintf.h"
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
@@ -2757,11 +2758,22 @@
return;
}
- // start with the whole surface at its current location
- const Layer::State& s(layer->getDrawingState());
+ // Note: Converts a wp<LayerFE> to a sp<LayerFE>
+ auto layerFE = compositionLayer->getLayerFE();
+ if (layerFE == nullptr) {
+ return;
+ }
+
+ // Request a snapshot of the subset of state relevant to visibility
+ // determination
+ layerFE->latchCompositionState(compositionLayer->editState().frontEnd,
+ compositionengine::LayerFE::StateSubset::BasicGeometry);
+
+ // Work with a read-only copy of the snapshot
+ const auto& layerFEState = compositionLayer->getState().frontEnd;
// only consider the layers on the given layer stack
- if (!display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) {
+ if (!display->belongsInOutput(layerFEState.layerStackId, layerFEState.internalOnly)) {
return;
}
@@ -2795,18 +2807,17 @@
Region transparentRegion;
// handle hidden surfaces by setting the visible region to empty
- if (CC_LIKELY(layer->isVisible())) {
- const bool translucent = !layer->isOpaque(s);
- Rect bounds(layer->getScreenBounds());
-
- visibleRegion.set(bounds);
- ui::Transform tr = layer->getTransform();
+ if (CC_LIKELY(layerFEState.isVisible)) {
+ // Get the visible region
+ visibleRegion.set(
+ Rect(layerFEState.geomLayerTransform.transform(layerFEState.geomLayerBounds)));
+ const ui::Transform& tr = layerFEState.geomLayerTransform;
if (!visibleRegion.isEmpty()) {
// Remove the transparent area from the visible region
- if (translucent) {
+ if (!layerFEState.isOpaque) {
if (tr.preserveRects()) {
// transform the transparent region
- transparentRegion = tr.transform(layer->getActiveTransparentRegion(s));
+ transparentRegion = tr.transform(layerFEState.transparentRegionHint);
} else {
// transformation too complex, can't do the
// transparent region optimization.
@@ -2816,9 +2827,8 @@
// compute the opaque region
const int32_t layerOrientation = tr.getOrientation();
- if (layer->getAlpha() == 1.0f && !translucent &&
- layer->getRoundedCornerState().radius == 0.0f &&
- ((layerOrientation & ui::Transform::ROT_INVALID) == false)) {
+ if (layerFEState.isOpaque &&
+ ((layerOrientation & ui::Transform::ROT_INVALID) == false)) {
// the opaque region is the layer's footprint
opaqueRegion = visibleRegion;
}
@@ -2848,12 +2858,11 @@
prevOutputLayer ? prevOutputLayer->getState().coveredRegion : kEmptyRegion;
// compute this layer's dirty region
- if (layer->contentDirty) {
+ if (layerFEState.contentDirty) {
// we need to invalidate the whole region
dirty = visibleRegion;
// as well, as the old visible region
dirty.orSelf(oldVisibleRegion);
- layer->contentDirty = false;
} else {
/* compute the exposed region:
* the exposed region consists of two components:
@@ -2891,12 +2900,7 @@
return;
}
- const auto displayId = displayDevice->getId();
- sp<compositionengine::LayerFE> layerFE = compositionLayer->getLayerFE();
- LOG_ALWAYS_FATAL_IF(layerFE.get() == nullptr);
-
- outLayersSortedByZ.emplace_back(
- display->getOrCreateOutputLayer(displayId, compositionLayer, layerFE));
+ outLayersSortedByZ.emplace_back(display->getOrCreateOutputLayer(compositionLayer, layerFE));
auto& outputLayerState = outLayersSortedByZ.back()->editState();
outputLayerState.visibleRegion = std::move(visibleRegion);
outputLayerState.visibleNonTransparentRegion = std::move(visibleNonTransparentRegion);
@@ -3392,8 +3396,6 @@
uint32_t flags = 0;
const uint64_t what = s.what;
- bool geometryAppliesWithResize =
- what & layer_state_t::eGeometryAppliesWithResize;
// If we are deferring transaction, make sure to push the pending state, as otherwise the
// pending state will also be deferred.
@@ -3402,7 +3404,7 @@
}
if (what & layer_state_t::ePositionChanged) {
- if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
+ if (layer->setPosition(s.x, s.y)) {
flags |= eTraversalNeeded;
}
}
@@ -3493,8 +3495,7 @@
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eCropChanged_legacy) {
- if (layer->setCrop_legacy(s.crop_legacy, !geometryAppliesWithResize))
- flags |= eTraversalNeeded;
+ if (layer->setCrop_legacy(s.crop_legacy)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eCornerRadiusChanged) {
if (layer->setCornerRadius(s.cornerRadius))
@@ -4053,6 +4054,7 @@
{"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)},
{"--dispsync"s,
dumper([this](std::string& s) { mScheduler->getPrimaryDispSync().dump(s); })},
+ {"--edid"s, argsDumper(&SurfaceFlinger::dumpRawDisplayIdentificationData)},
{"--frame-events"s, dumper(&SurfaceFlinger::dumpFrameEventsLocked)},
{"--latency"s, argsDumper(&SurfaceFlinger::dumpStatsLocked)},
{"--latency-clear"s, argsDumper(&SurfaceFlinger::clearStatsLocked)},
@@ -4281,21 +4283,13 @@
}
if (!isEdid(data)) {
- result.append("unknown identification data: ");
- for (uint8_t byte : data) {
- StringAppendF(&result, "%x ", byte);
- }
- result.append("\n");
+ result.append("unknown identification data\n");
continue;
}
const auto edid = parseEdid(data);
if (!edid) {
- result.append("invalid EDID: ");
- for (uint8_t byte : data) {
- StringAppendF(&result, "%x ", byte);
- }
- result.append("\n");
+ result.append("invalid EDID\n");
continue;
}
@@ -4305,6 +4299,18 @@
}
}
+void SurfaceFlinger::dumpRawDisplayIdentificationData(const DumpArgs& args,
+ std::string& result) const {
+ hwc2_display_t hwcDisplayId;
+ uint8_t port;
+ DisplayIdentificationData data;
+
+ if (args.size() > 1 && base::ParseUint(String8(args[1]), &hwcDisplayId) &&
+ getHwComposer().getDisplayIdentificationData(hwcDisplayId, &port, &data)) {
+ result.append(reinterpret_cast<const char*>(data.data()), data.size());
+ }
+}
+
void SurfaceFlinger::dumpWideColorInfo(std::string& result) const {
StringAppendF(&result, "Device has wide color built-in display: %d\n", hasWideColorDisplay);
StringAppendF(&result, "Device uses color management: %d\n", useColorManagement);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f220c26..beb43d0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -865,6 +865,7 @@
std::vector<OccupancyTracker::Segment>&& history);
void dumpBufferingStats(std::string& result) const;
void dumpDisplayIdentificationData(std::string& result) const;
+ void dumpRawDisplayIdentificationData(const DumpArgs&, std::string& result) const;
void dumpWideColorInfo(std::string& result) const;
LayersProto dumpDrawingStateProto(uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
void dumpOffscreenLayersProto(LayersProto& layersProto,
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index acb263a..d765f68 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -136,7 +136,9 @@
int32_t bufferWidth, int32_t bufferHeight) {
ANativeWindow_Buffer buffer;
ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
- fillANativeWindowBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight), color);
+ TransactionUtils::fillANativeWindowBufferColor(buffer,
+ Rect(0, 0, bufferWidth, bufferHeight),
+ color);
postBufferQueueLayerBuffer(layer);
}
@@ -147,7 +149,8 @@
BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
BufferUsage::COMPOSER_OVERLAY,
"test");
- fillGraphicBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight), color);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight),
+ color);
Transaction().setBuffer(layer, buffer).apply();
}
@@ -193,11 +196,15 @@
const int32_t halfW = bufferWidth / 2;
const int32_t halfH = bufferHeight / 2;
- fillANativeWindowBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
- fillANativeWindowBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH), topRight);
- fillANativeWindowBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight), bottomLeft);
- fillANativeWindowBufferColor(buffer, Rect(halfW, halfH, bufferWidth, bufferHeight),
- bottomRight);
+ TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
+ TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
+ topRight);
+ TransactionUtils::fillANativeWindowBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
+ bottomLeft);
+ TransactionUtils::fillANativeWindowBufferColor(buffer,
+ Rect(halfW, halfH, bufferWidth,
+ bufferHeight),
+ bottomRight);
postBufferQueueLayerBuffer(layer);
}
@@ -216,10 +223,14 @@
const int32_t halfW = bufferWidth / 2;
const int32_t halfH = bufferHeight / 2;
- fillGraphicBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
- fillGraphicBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH), topRight);
- fillGraphicBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight), bottomLeft);
- fillGraphicBufferColor(buffer, Rect(halfW, halfH, bufferWidth, bufferHeight), bottomRight);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH),
+ topRight);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight),
+ bottomLeft);
+ TransactionUtils::fillGraphicBufferColor(buffer,
+ Rect(halfW, halfH, bufferWidth, bufferHeight),
+ bottomRight);
Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply();
}
@@ -551,62 +562,6 @@
}
}
-TEST_P(LayerRenderTypeTransactionTest, SetPositionWithNextResize_BufferQueue) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
-
- // request setPosition to be applied with the next resize
- Transaction().setPosition(layer, 5, 10).setGeometryAppliesWithResize(layer).apply();
- {
- SCOPED_TRACE("new position pending");
- getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
- }
-
- Transaction().setPosition(layer, 15, 20).apply();
- {
- SCOPED_TRACE("pending new position modified");
- getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
- }
-
- Transaction().setSize(layer, 64, 64).apply();
- {
- SCOPED_TRACE("resize pending");
- getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
- }
-
- // finally resize and latch the buffer
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 64, 64));
- {
- SCOPED_TRACE("new position applied");
- getScreenCapture()->expectColor(Rect(15, 20, 79, 84), Color::RED);
- }
-}
-
-TEST_P(LayerRenderTypeTransactionTest, SetPositionWithNextResizeScaleToWindow_BufferQueue) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
-
- // setPosition is not immediate even with SCALE_TO_WINDOW override
- Transaction()
- .setPosition(layer, 5, 10)
- .setSize(layer, 64, 64)
- .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)
- .setGeometryAppliesWithResize(layer)
- .apply();
- {
- SCOPED_TRACE("new position pending");
- getScreenCapture()->expectColor(Rect(0, 0, 64, 64), Color::RED);
- }
-
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 64, 64));
- {
- SCOPED_TRACE("new position applied");
- getScreenCapture()->expectColor(Rect(5, 10, 69, 74), Color::RED);
- }
-}
-
TEST_P(LayerRenderTypeTransactionTest, SetSizeBasic_BufferQueue) {
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
@@ -1093,8 +1048,10 @@
ANativeWindow_Buffer buffer;
ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
- ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, top, Color::TRANSPARENT));
- ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, bottom, Color::RED));
+ ASSERT_NO_FATAL_FAILURE(
+ TransactionUtils::fillANativeWindowBufferColor(buffer, top, Color::TRANSPARENT));
+ ASSERT_NO_FATAL_FAILURE(
+ TransactionUtils::fillANativeWindowBufferColor(buffer, bottom, Color::RED));
// setTransparentRegionHint always applies to the following buffer
Transaction().setTransparentRegionHint(layer, Region(top)).apply();
ASSERT_NO_FATAL_FAILURE(postBufferQueueLayerBuffer(layer));
@@ -1114,8 +1071,10 @@
}
ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
- ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, top, Color::RED));
- ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, bottom, Color::TRANSPARENT));
+ ASSERT_NO_FATAL_FAILURE(
+ TransactionUtils::fillANativeWindowBufferColor(buffer, top, Color::RED));
+ ASSERT_NO_FATAL_FAILURE(
+ TransactionUtils::fillANativeWindowBufferColor(buffer, bottom, Color::TRANSPARENT));
ASSERT_NO_FATAL_FAILURE(postBufferQueueLayerBuffer(layer));
{
SCOPED_TRACE("bottom transparent");
@@ -1138,8 +1097,9 @@
BufferUsage::COMPOSER_OVERLAY,
"test");
- ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, top, Color::TRANSPARENT));
- ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, bottom, Color::RED));
+ ASSERT_NO_FATAL_FAILURE(
+ TransactionUtils::fillGraphicBufferColor(buffer, top, Color::TRANSPARENT));
+ ASSERT_NO_FATAL_FAILURE(TransactionUtils::fillGraphicBufferColor(buffer, bottom, Color::RED));
Transaction()
.setTransparentRegionHint(layer, Region(top))
.setBuffer(layer, buffer)
@@ -1165,8 +1125,9 @@
BufferUsage::COMPOSER_OVERLAY,
"test");
- ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, top, Color::RED));
- ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, bottom, Color::TRANSPARENT));
+ ASSERT_NO_FATAL_FAILURE(TransactionUtils::fillGraphicBufferColor(buffer, top, Color::RED));
+ ASSERT_NO_FATAL_FAILURE(
+ TransactionUtils::fillGraphicBufferColor(buffer, bottom, Color::TRANSPARENT));
Transaction().setBuffer(layer, buffer).apply();
{
SCOPED_TRACE("bottom transparent");
@@ -1907,8 +1868,8 @@
BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
BufferUsage::COMPOSER_OVERLAY,
"test");
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 16), Color::BLUE);
- fillGraphicBufferColor(buffer, Rect(0, 16, 32, 64), Color::RED);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 16), Color::BLUE);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 16, 32, 64), Color::RED);
Transaction().setFrame(layer, Rect(0, 0, 64, 64)).apply();
@@ -2008,74 +1969,6 @@
}
}
-TEST_P(LayerRenderTypeTransactionTest, SetCropWithNextResize_BufferQueue) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
-
- // request setCrop_legacy to be applied with the next resize
- Transaction()
- .setCrop_legacy(layer, Rect(8, 8, 24, 24))
- .setGeometryAppliesWithResize(layer)
- .apply();
- {
- SCOPED_TRACE("waiting for next resize");
- getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
- }
-
- Transaction().setCrop_legacy(layer, Rect(4, 4, 12, 12)).apply();
- {
- SCOPED_TRACE("pending crop modified");
- getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
- }
-
- Transaction().setSize(layer, 16, 16).apply();
- {
- SCOPED_TRACE("resize pending");
- getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
- }
-
- // finally resize
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16));
- {
- SCOPED_TRACE("new crop applied");
- auto shot = getScreenCapture();
- shot->expectColor(Rect(4, 4, 12, 12), Color::RED);
- shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK);
- }
-}
-
-TEST_P(LayerRenderTypeTransactionTest, SetCropWithNextResizeScaleToWindow_BufferQueue) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
-
- // setCrop_legacy is not immediate even with SCALE_TO_WINDOW override
- Transaction()
- .setCrop_legacy(layer, Rect(4, 4, 12, 12))
- .setSize(layer, 16, 16)
- .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)
- .setGeometryAppliesWithResize(layer)
- .apply();
- {
- SCOPED_TRACE("new crop pending");
- auto shot = getScreenCapture();
- shot->expectColor(Rect(0, 0, 16, 16), Color::RED);
- shot->expectBorder(Rect(0, 0, 16, 16), Color::BLACK);
- }
-
- // XXX crop is never latched without other geometry change (b/69315677)
- Transaction().setPosition(layer, 1, 0).setGeometryAppliesWithResize(layer).apply();
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16));
- Transaction().setPosition(layer, 0, 0).apply();
- {
- SCOPED_TRACE("new crop applied");
- auto shot = getScreenCapture();
- shot->expectColor(Rect(4, 4, 12, 12), Color::RED);
- shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK);
- }
-}
-
TEST_P(LayerRenderTypeTransactionTest, SetFrameBasic_BufferState) {
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(
@@ -2302,7 +2195,7 @@
BufferUsage::COMPOSER_OVERLAY,
"test");
Color color = colors[idx % colors.size()];
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), color);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), color);
idx++;
}
@@ -2338,7 +2231,7 @@
BufferUsage::COMPOSER_OVERLAY,
"test");
Color color = colors[idx % colors.size()];
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), color);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), color);
idx++;
}
@@ -2374,7 +2267,7 @@
BufferUsage::COMPOSER_OVERLAY,
"test");
Color color = colors[idx % colors.size()];
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), color);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), color);
idx++;
}
@@ -2471,7 +2364,7 @@
BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
BufferUsage::COMPOSER_OVERLAY,
"test");
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
sp<Fence> fence;
if (getBuffer(nullptr, &fence) != NO_ERROR) {
@@ -2500,7 +2393,7 @@
BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
BufferUsage::COMPOSER_OVERLAY,
"test");
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
sp<Fence> fence = Fence::NO_FENCE;
@@ -2524,7 +2417,7 @@
BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
BufferUsage::COMPOSER_OVERLAY,
"test");
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
Transaction()
.setBuffer(layer, buffer)
@@ -2546,7 +2439,7 @@
BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
BufferUsage::COMPOSER_OVERLAY,
"test");
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
HdrMetadata hdrMetadata;
hdrMetadata.validTypes = 0;
@@ -2570,7 +2463,7 @@
BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
BufferUsage::COMPOSER_OVERLAY,
"test");
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
Region region;
region.set(32, 32);
@@ -2594,7 +2487,7 @@
BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
BufferUsage::COMPOSER_OVERLAY,
"test");
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
+ TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
Transaction()
.setBuffer(layer, buffer)
@@ -3661,7 +3554,7 @@
displayHeight, 0);
ASSERT_TRUE(mBGSurfaceControl != nullptr);
ASSERT_TRUE(mBGSurfaceControl->isValid());
- fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
+ TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
// Foreground surface
mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
@@ -3669,14 +3562,14 @@
ASSERT_TRUE(mFGSurfaceControl != nullptr);
ASSERT_TRUE(mFGSurfaceControl->isValid());
- fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
// Synchronization surface
mSyncSurfaceControl = createLayer(String8("Sync Test Surface"), 1, 1, 0);
ASSERT_TRUE(mSyncSurfaceControl != nullptr);
ASSERT_TRUE(mSyncSurfaceControl->isValid());
- fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+ TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
asTransaction([&](Transaction& t) {
t.setDisplayLayerStack(display, 0);
@@ -3705,9 +3598,9 @@
// posting three buffers to it should ensure that at least two
// SurfaceFlinger::handlePageFlip calls have been made, which should
// guaranteed that a buffer posted to another Surface has been retired.
- fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
- fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
- fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+ TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+ TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+ TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
}
@@ -3724,7 +3617,7 @@
std::unique_ptr<ScreenCapture> sc;
sp<SurfaceControl> relative = createLayer(String8("relativeTestSurface"), 10, 10, 0);
- fillSurfaceRGBA8(relative, 10, 10, 10);
+ TransactionUtils::fillSurfaceRGBA8(relative, 10, 10, 10);
waitForPostedBuffers();
Transaction{}
@@ -3765,7 +3658,9 @@
sc->expectBGColor(128, 128);
}
- void lockAndFillFGBuffer() { fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63, false); }
+ void lockAndFillFGBuffer() {
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63, false);
+ }
void unlockFGBuffer() {
sp<Surface> s = mFGSurfaceControl->getSurface();
@@ -3774,7 +3669,7 @@
}
void completeFGResize() {
- fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
waitForPostedBuffers();
}
void restoreInitialState() {
@@ -3842,7 +3737,7 @@
}
// should trigger the first deferred transaction, but not the second one
- fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+ TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
{
SCOPED_TRACE("after first trigger");
ScreenCapture::captureScreen(&sc);
@@ -3855,7 +3750,7 @@
asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 1.0); });
// trigger the second deferred transaction
- fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
+ TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
{
SCOPED_TRACE("after second trigger");
ScreenCapture::captureScreen(&sc);
@@ -3873,7 +3768,7 @@
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
sp<SurfaceControl> childBuffer = createSurface(mClient, "Buffered child", 20, 20,
PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get());
- fillSurfaceRGBA8(childBuffer, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(childBuffer, 200, 200, 200);
SurfaceComposerClient::Transaction{}
.setCrop_legacy(childNoBuffer, Rect(0, 0, 10, 10))
.show(childNoBuffer)
@@ -3948,7 +3843,7 @@
LayerUpdateTest::SetUp();
mChild = createSurface(mClient, "Child surface", 10, 15, PIXEL_FORMAT_RGBA_8888, 0,
mFGSurfaceControl.get());
- fillSurfaceRGBA8(mChild, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
{
SCOPED_TRACE("before anything");
@@ -4079,9 +3974,9 @@
}
TEST_F(ChildLayerTest, ChildLayerAlpha) {
- fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
- fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
- fillSurfaceRGBA8(mChild, 0, 254, 0);
+ TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
+ TransactionUtils::fillSurfaceRGBA8(mChild, 0, 254, 0);
waitForPostedBuffers();
asTransaction([&](Transaction& t) {
@@ -4149,7 +4044,7 @@
TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
sp<SurfaceControl> mGrandChild =
createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
- fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
+ TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
{
SCOPED_TRACE("Grandchild visible");
@@ -4179,7 +4074,7 @@
TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
sp<SurfaceControl> mGrandChild =
createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
- fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
+ TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
// draw grand child behind the foreground surface
asTransaction([&](Transaction& t) {
@@ -4244,7 +4139,7 @@
ASSERT_TRUE(mChildNewClient->isValid());
- fillSurfaceRGBA8(mChildNewClient, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(mChildNewClient, 200, 200, 200);
asTransaction([&](Transaction& t) {
t.hide(mChild);
@@ -4285,7 +4180,7 @@
ASSERT_TRUE(childNewClient != nullptr);
ASSERT_TRUE(childNewClient->isValid());
- fillSurfaceRGBA8(childNewClient, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200);
Transaction()
.hide(mChild)
@@ -4339,7 +4234,7 @@
ASSERT_TRUE(childNewClient != nullptr);
ASSERT_TRUE(childNewClient->isValid());
- fillSurfaceRGBA8(childNewClient, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200);
Transaction()
.hide(mChild)
@@ -4428,7 +4323,7 @@
auto anw = static_cast<ANativeWindow*>(s.get());
native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
native_window_set_buffers_dimensions(anw, 64, 128);
- fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
waitForPostedBuffers();
{
@@ -4448,7 +4343,7 @@
t.setPosition(mFGSurfaceControl, 0, 0);
t.setSize(mChild, 100, 100);
});
- fillSurfaceRGBA8(mChild, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
{
mCapture = screenshot();
@@ -4464,7 +4359,7 @@
// Apply a 90 transform on the buffer.
native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
native_window_set_buffers_dimensions(anw, 64, 128);
- fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
waitForPostedBuffers();
// The child should be cropped by the new parent bounds.
@@ -4485,7 +4380,7 @@
t.setPosition(mFGSurfaceControl, 0, 0);
t.setSize(mChild, 200, 200);
});
- fillSurfaceRGBA8(mChild, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
{
mCapture = screenshot();
@@ -4537,7 +4432,7 @@
// have an effective scale of 2.0 applied to the buffer along with a rotation transform.
native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
native_window_set_buffers_dimensions(anw, 32, 64);
- fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
waitForPostedBuffers();
// The child should ignore the buffer transform but apply the 2.0 scale from parent.
@@ -4570,13 +4465,13 @@
// frame because SurfaceFlinger would never process the deferred transaction and would therefore
// never acquire/release the first buffer
ALOGI("Filling 1");
- fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
ALOGI("Filling 2");
- fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
ALOGI("Filling 3");
- fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
ALOGI("Filling 4");
- fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
+ TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
}
TEST_F(ChildLayerTest, Reparent) {
@@ -4641,7 +4536,7 @@
ASSERT_TRUE(newSurface != nullptr);
ASSERT_TRUE(newSurface->isValid());
- fillSurfaceRGBA8(newSurface, 63, 195, 63);
+ TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
asTransaction([&](Transaction& t) {
t.hide(mChild);
t.show(newSurface);
@@ -4673,7 +4568,7 @@
TEST_F(ChildLayerTest, NestedChildren) {
sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
- fillSurfaceRGBA8(grandchild, 50, 50, 50);
+ TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
{
mCapture = screenshot();
@@ -4685,7 +4580,7 @@
TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
- fillSurfaceRGBA8(relative, 255, 255, 255);
+ TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
Transaction t;
t.setLayer(relative, INT32_MAX)
@@ -4922,7 +4817,7 @@
sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
SurfaceComposerClient::Transaction().show(child).apply(true);
@@ -4937,7 +4832,7 @@
sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
SurfaceComposerClient::Transaction().show(child).apply(true);
@@ -4952,10 +4847,10 @@
sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child2, 200, 0, 200);
+ TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
SurfaceComposerClient::Transaction()
.show(child)
@@ -4976,13 +4871,13 @@
sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child2, 200, 0, 200);
+ TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
sp<SurfaceControl> child3 = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, child2.get());
- fillSurfaceRGBA8(child2, 200, 0, 200);
+ TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
SurfaceComposerClient::Transaction()
.show(child)
@@ -5002,7 +4897,7 @@
sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
SurfaceComposerClient::Transaction().show(child).apply(true);
@@ -5022,8 +4917,8 @@
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
ASSERT_NE(nullptr, child.get()) << "failed to create surface";
sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
- fillSurfaceRGBA8(child, 200, 200, 200);
- fillSurfaceRGBA8(relative, 100, 100, 100);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
SurfaceComposerClient::Transaction()
.show(child)
@@ -5045,8 +4940,8 @@
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child, 200, 200, 200);
- fillSurfaceRGBA8(relative, 100, 100, 100);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
SurfaceComposerClient::Transaction()
.show(child)
@@ -5075,7 +4970,7 @@
mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
mFGSurfaceControl.get());
- fillSurfaceRGBA8(mChild, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
SurfaceComposerClient::Transaction().show(mChild).apply(true);
}
@@ -5138,12 +5033,12 @@
sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
PIXEL_FORMAT_RGBA_8888, 0, child.get());
- fillSurfaceRGBA8(grandchild, 50, 50, 50);
+ TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
SurfaceComposerClient::Transaction()
.show(child)
.setPosition(grandchild, 5, 5)
@@ -5160,7 +5055,7 @@
TEST_F(ScreenCaptureTest, CaptureChildOnly) {
sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
auto childHandle = child->getHandle();
SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
@@ -5174,12 +5069,12 @@
TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
- fillSurfaceRGBA8(child, 200, 200, 200);
+ TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
auto childHandle = child->getHandle();
sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
PIXEL_FORMAT_RGBA_8888, 0, child.get());
- fillSurfaceRGBA8(grandchild, 50, 50, 50);
+ TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
SurfaceComposerClient::Transaction()
.show(child)
@@ -5674,8 +5569,8 @@
ASSERT_NO_FATAL_FAILURE(slotToBuffer(slot1, &buf1));
sp<GraphicBuffer> buf2;
ASSERT_NO_FATAL_FAILURE(slotToBuffer(slot2, &buf2));
- fillGraphicBufferColor(buf1, Rect(width, height), color);
- fillGraphicBufferColor(buf2, Rect(width, height), color);
+ TransactionUtils::fillGraphicBufferColor(buf1, Rect(width, height), color);
+ TransactionUtils::fillGraphicBufferColor(buf2, Rect(width, height), color);
const auto displayTime = systemTime() + milliseconds_to_nanoseconds(100);
ASSERT_NO_FATAL_FAILURE(queue(slot1, Region::INVALID_REGION, displayTime));
diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
index a892a2a..093bcf5 100644
--- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
+++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
@@ -1331,16 +1331,6 @@
restoreInitialState();
- // Now we repeat with setGeometryAppliesWithResize
- // and verify the position DOESN'T latch.
- {
- TransactionScope ts(*sFakeComposer);
- ts.setGeometryAppliesWithResize(mFGSurfaceControl);
- ts.setSize(mFGSurfaceControl, 32, 32);
- ts.setPosition(mFGSurfaceControl, 100, 100);
- }
- EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
-
completeFGResize();
auto referenceFrame2 = mBaseFrame;
@@ -1365,14 +1355,6 @@
restoreInitialState();
- {
- TransactionScope ts(*sFakeComposer);
- ts.setSize(mFGSurfaceControl, 128, 128);
- ts.setGeometryAppliesWithResize(mFGSurfaceControl);
- ts.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 63, 63));
- }
- EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
-
completeFGResize();
auto referenceFrame2 = mBaseFrame;
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 9e4d57e..20dfed6 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -814,9 +814,7 @@
std::vector<std::unique_ptr<compositionengine::OutputLayer>> outputLayers;
outputLayers.emplace_back(test->mDisplay->getCompositionDisplay()
- ->getOrCreateOutputLayer(DEFAULT_DISPLAY_ID,
- layer->getCompositionLayer(),
- layer));
+ ->createOutputLayer(layer->getCompositionLayer(), layer));
outputLayers.back()->editState().visibleRegion = Region(Rect(0, 0, 100, 100));
outputLayers.back()->editState().outputSpaceVisibleRegion = Region(Rect(0, 0, 100, 100));
diff --git a/services/surfaceflinger/tests/utils/ScreenshotUtils.h b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
index 02e7623..5480b00 100644
--- a/services/surfaceflinger/tests/utils/ScreenshotUtils.h
+++ b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
@@ -76,7 +76,7 @@
void expectColor(const Rect& rect, const Color& color, uint8_t tolerance = 0) {
ASSERT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mOutBuffer->getPixelFormat());
- expectBufferColor(mOutBuffer, mPixels, rect, color, tolerance);
+ TransactionUtils::expectBufferColor(mOutBuffer, mPixels, rect, color, tolerance);
}
void expectBorder(const Rect& rect, const Color& color, uint8_t tolerance = 0) {
diff --git a/services/surfaceflinger/tests/utils/TransactionUtils.h b/services/surfaceflinger/tests/utils/TransactionUtils.h
index f6b33a9..22df255 100644
--- a/services/surfaceflinger/tests/utils/TransactionUtils.h
+++ b/services/surfaceflinger/tests/utils/TransactionUtils.h
@@ -16,13 +16,7 @@
#pragma once
-//#include <algorithm>
#include <chrono>
-//#include <cinttypes>
-//#include <functional>
-//#include <limits>
-//#include <ostream>
-//#include <thread>
#include <gtest/gtest.h>
#include <android/native_window.h>
@@ -39,130 +33,131 @@
#include <ui/Rect.h>
#include "ColorUtils.h"
-//#include <sys/types.h>
-//#include <unistd.h>
namespace android {
namespace {
using namespace std::chrono_literals;
+using Transaction = SurfaceComposerClient::Transaction;
std::ostream& operator<<(std::ostream& os, const Color& color) {
os << int(color.r) << ", " << int(color.g) << ", " << int(color.b) << ", " << int(color.a);
return os;
}
-// Fill a region with the specified color.
-void fillANativeWindowBufferColor(const ANativeWindow_Buffer& buffer, const Rect& rect,
- const Color& color) {
- Rect r(0, 0, buffer.width, buffer.height);
- if (!r.intersect(rect, &r)) {
- return;
- }
+class TransactionUtils {
+public:
+ // Fill a region with the specified color.
+ static void fillANativeWindowBufferColor(const ANativeWindow_Buffer& buffer, const Rect& rect,
+ const Color& color) {
+ Rect r(0, 0, buffer.width, buffer.height);
+ if (!r.intersect(rect, &r)) {
+ return;
+ }
- int32_t width = r.right - r.left;
- int32_t height = r.bottom - r.top;
+ int32_t width = r.right - r.left;
+ int32_t height = r.bottom - r.top;
- for (int32_t row = 0; row < height; row++) {
- uint8_t* dst =
- static_cast<uint8_t*>(buffer.bits) + (buffer.stride * (r.top + row) + r.left) * 4;
- for (int32_t column = 0; column < width; column++) {
- dst[0] = color.r;
- dst[1] = color.g;
- dst[2] = color.b;
- dst[3] = color.a;
- dst += 4;
+ for (int32_t row = 0; row < height; row++) {
+ uint8_t* dst = static_cast<uint8_t*>(buffer.bits) +
+ (buffer.stride * (r.top + row) + r.left) * 4;
+ for (int32_t column = 0; column < width; column++) {
+ dst[0] = color.r;
+ dst[1] = color.g;
+ dst[2] = color.b;
+ dst[3] = color.a;
+ dst += 4;
+ }
}
}
-}
-// Fill a region with the specified color.
-void fillGraphicBufferColor(const sp<GraphicBuffer>& buffer, const Rect& rect, const Color& color) {
- Rect r(0, 0, buffer->width, buffer->height);
- if (!r.intersect(rect, &r)) {
- return;
+ // Fill a region with the specified color.
+ static void fillGraphicBufferColor(const sp<GraphicBuffer>& buffer, const Rect& rect,
+ const Color& color) {
+ Rect r(0, 0, buffer->width, buffer->height);
+ if (!r.intersect(rect, &r)) {
+ return;
+ }
+
+ int32_t width = r.right - r.left;
+ int32_t height = r.bottom - r.top;
+
+ uint8_t* pixels;
+ buffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
+
+ for (int32_t row = 0; row < height; row++) {
+ uint8_t* dst = pixels + (buffer->getStride() * (r.top + row) + r.left) * 4;
+ for (int32_t column = 0; column < width; column++) {
+ dst[0] = color.r;
+ dst[1] = color.g;
+ dst[2] = color.b;
+ dst[3] = color.a;
+ dst += 4;
+ }
+ }
+ buffer->unlock();
}
- int32_t width = r.right - r.left;
- int32_t height = r.bottom - r.top;
+ // Check if a region has the specified color.
+ static void expectBufferColor(const sp<GraphicBuffer>& outBuffer, uint8_t* pixels,
+ const Rect& rect, const Color& color, uint8_t tolerance) {
+ int32_t x = rect.left;
+ int32_t y = rect.top;
+ int32_t width = rect.right - rect.left;
+ int32_t height = rect.bottom - rect.top;
- uint8_t* pixels;
- buffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ int32_t bufferWidth = int32_t(outBuffer->getWidth());
+ int32_t bufferHeight = int32_t(outBuffer->getHeight());
+ if (x + width > bufferWidth) {
+ x = std::min(x, bufferWidth);
+ width = bufferWidth - x;
+ }
+ if (y + height > bufferHeight) {
+ y = std::min(y, bufferHeight);
+ height = bufferHeight - y;
+ }
- for (int32_t row = 0; row < height; row++) {
- uint8_t* dst = pixels + (buffer->getStride() * (r.top + row) + r.left) * 4;
- for (int32_t column = 0; column < width; column++) {
- dst[0] = color.r;
- dst[1] = color.g;
- dst[2] = color.b;
- dst[3] = color.a;
- dst += 4;
+ auto colorCompare = [tolerance](uint8_t a, uint8_t b) {
+ uint8_t tmp = a >= b ? a - b : b - a;
+ return tmp <= tolerance;
+ };
+ for (int32_t j = 0; j < height; j++) {
+ const uint8_t* src = pixels + (outBuffer->getStride() * (y + j) + x) * 4;
+ for (int32_t i = 0; i < width; i++) {
+ const uint8_t expected[4] = {color.r, color.g, color.b, color.a};
+ EXPECT_TRUE(std::equal(src, src + 4, expected, colorCompare))
+ << "pixel @ (" << x + i << ", " << y + j << "): "
+ << "expected (" << color << "), "
+ << "got (" << Color{src[0], src[1], src[2], src[3]} << ")";
+ src += 4;
+ }
}
}
- buffer->unlock();
-}
-// Check if a region has the specified color.
-void expectBufferColor(const sp<GraphicBuffer>& outBuffer, uint8_t* pixels, const Rect& rect,
- const Color& color, uint8_t tolerance) {
- int32_t x = rect.left;
- int32_t y = rect.top;
- int32_t width = rect.right - rect.left;
- int32_t height = rect.bottom - rect.top;
-
- int32_t bufferWidth = int32_t(outBuffer->getWidth());
- int32_t bufferHeight = int32_t(outBuffer->getHeight());
- if (x + width > bufferWidth) {
- x = std::min(x, bufferWidth);
- width = bufferWidth - x;
- }
- if (y + height > bufferHeight) {
- y = std::min(y, bufferHeight);
- height = bufferHeight - y;
- }
-
- auto colorCompare = [tolerance](uint8_t a, uint8_t b) {
- uint8_t tmp = a >= b ? a - b : b - a;
- return tmp <= tolerance;
- };
- for (int32_t j = 0; j < height; j++) {
- const uint8_t* src = pixels + (outBuffer->getStride() * (y + j) + x) * 4;
- for (int32_t i = 0; i < width; i++) {
- const uint8_t expected[4] = {color.r, color.g, color.b, color.a};
- EXPECT_TRUE(std::equal(src, src + 4, expected, colorCompare))
- << "pixel @ (" << x + i << ", " << y + j << "): "
- << "expected (" << color << "), "
- << "got (" << Color{src[0], src[1], src[2], src[3]} << ")";
- src += 4;
+ // Fill an RGBA_8888 formatted surface with a single color.
+ static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, uint8_t r, uint8_t g, uint8_t b,
+ bool unlock = true) {
+ ANativeWindow_Buffer outBuffer;
+ sp<Surface> s = sc->getSurface();
+ ASSERT_TRUE(s != nullptr);
+ ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, nullptr));
+ uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits);
+ for (int y = 0; y < outBuffer.height; y++) {
+ for (int x = 0; x < outBuffer.width; x++) {
+ uint8_t* pixel = img + (4 * (y * outBuffer.stride + x));
+ pixel[0] = r;
+ pixel[1] = g;
+ pixel[2] = b;
+ pixel[3] = 255;
+ }
+ }
+ if (unlock) {
+ ASSERT_EQ(NO_ERROR, s->unlockAndPost());
}
}
-}
-
-using Transaction = SurfaceComposerClient::Transaction;
-
-// Fill an RGBA_8888 formatted surface with a single color.
-static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, uint8_t r, uint8_t g, uint8_t b,
- bool unlock = true) {
- ANativeWindow_Buffer outBuffer;
- sp<Surface> s = sc->getSurface();
- ASSERT_TRUE(s != nullptr);
- ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, nullptr));
- uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits);
- for (int y = 0; y < outBuffer.height; y++) {
- for (int x = 0; x < outBuffer.width; x++) {
- uint8_t* pixel = img + (4 * (y * outBuffer.stride + x));
- pixel[0] = r;
- pixel[1] = g;
- pixel[2] = b;
- pixel[3] = 255;
- }
- }
- if (unlock) {
- ASSERT_EQ(NO_ERROR, s->unlockAndPost());
- }
-}
+};
enum class RenderPath { SCREENSHOT, VIRTUAL_DISPLAY };