Merge "Rename snapshotProfile to createProfileSnapshot for better consistency"
diff --git a/cmds/cmd/Android.mk b/cmds/cmd/Android.mk
index d565e57..4868555 100644
--- a/cmds/cmd/Android.mk
+++ b/cmds/cmd/Android.mk
@@ -10,6 +10,8 @@
libselinux \
libbinder
+LOCAL_CFLAGS := -Wall -Werror
+
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE)
diff --git a/cmds/cmd/cmd.cpp b/cmds/cmd/cmd.cpp
index 6511b44..48d5d4a 100644
--- a/cmds/cmd/cmd.cpp
+++ b/cmds/cmd/cmd.cpp
@@ -104,7 +104,7 @@
if (is_selinux_enabled() && seLinuxContext.size() > 0) {
String8 seLinuxContext8(seLinuxContext);
security_context_t tmp = NULL;
- int ret = getfilecon(fullPath.string(), &tmp);
+ getfilecon(fullPath.string(), &tmp);
Unique_SecurityContext context(tmp);
if (checkWrite) {
int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(),
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 4b67d8f..2e3e3ca 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -691,7 +691,9 @@
printf("Kernel: ");
DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
- ds.RunCommand("UPTIME", {"uptime"}, CommandOptions::DEFAULT);
+ printf("Uptime: ");
+ RunCommandToFd(STDOUT_FILENO, "", {"uptime", "-p"},
+ CommandOptions::WithTimeout(1).Always().Build());
printf("Bugreport format version: %s\n", version_.c_str());
printf("Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n", id_, pid_,
PropertiesHelper::IsDryRun(), args_.c_str(), extra_options_.c_str());
@@ -1093,7 +1095,6 @@
DurationReporter duration_reporter("DUMPSTATE");
dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
- /* TODO: Remove duplicate uptime call when tools use it from header */
RunCommand("UPTIME", {"uptime"});
DumpBlockStatFiles();
dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
diff --git a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
index 3264666..5b66b92 100644
--- a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
+++ b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
@@ -52,6 +52,6 @@
* Unknown or unknowable versions are returned as 0.
*/
- int getVersionCodeForPackage(in String packageName);
+ long getVersionCodeForPackage(in String packageName);
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 0dbe786..939a209 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -543,9 +543,14 @@
{
}
+SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client)
+ : mStatus(NO_ERROR), mClient(client)
+{
+}
+
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- if (sf != 0) {
+ if (sf != 0 && mStatus == NO_INIT) {
auto rootProducer = mParent.promote();
sp<ISurfaceComposerClient> conn;
conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index f6a2b8f..f5fb8ac 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -166,5 +166,28 @@
return mClient;
}
+void SurfaceControl::writeToParcel(Parcel* parcel)
+{
+ parcel->writeStrongBinder(ISurfaceComposerClient::asBinder(mClient->getClient()));
+ parcel->writeStrongBinder(mHandle);
+ parcel->writeStrongBinder(IGraphicBufferProducer::asBinder(mGraphicBufferProducer));
+}
+
+sp<SurfaceControl> SurfaceControl::readFromParcel(Parcel* parcel)
+{
+ sp<IBinder> client = parcel->readStrongBinder();
+ sp<IBinder> handle = parcel->readStrongBinder();
+ if (client == nullptr || handle == nullptr)
+ {
+ ALOGE("Invalid parcel");
+ return nullptr;
+ }
+ sp<IBinder> gbp;
+ parcel->readNullableStrongBinder(&gbp);
+ return new SurfaceControl(new SurfaceComposerClient(
+ interface_cast<ISurfaceComposerClient>(client)),
+ handle.get(), interface_cast<IGraphicBufferProducer>(gbp));
+}
+
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 3f13946..55b96ac 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -52,6 +52,7 @@
friend class Composer;
public:
SurfaceComposerClient();
+ SurfaceComposerClient(const sp<ISurfaceComposerClient>& client);
SurfaceComposerClient(const sp<IGraphicBufferProducer>& parent);
virtual ~SurfaceComposerClient();
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index 384815d..1416d87 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -44,6 +44,9 @@
class SurfaceControl : public RefBase
{
public:
+ static sp<SurfaceControl> readFromParcel(Parcel* parcel);
+ void writeToParcel(Parcel* parcel);
+
static bool isValid(const sp<SurfaceControl>& surface) {
return (surface != 0) && surface->isValid();
}
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index abeb719..5eba913 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -68,6 +68,8 @@
"-DLOG_TAG=\"buffer_transport_benchmark\"",
"-DTRACE=0",
"-O2",
+ "-Wall",
+ "-Werror",
],
name: "buffer_transport_benchmark",
tags: ["optional"],
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp b/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
index 658b496..d4d25b0 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
+++ b/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
@@ -34,7 +34,6 @@
static const String16 kBinderService = String16("bufferTransport");
static const uint32_t kBufferWidth = 100;
static const uint32_t kBufferHeight = 1;
-static const uint32_t kBufferLayerCount = 1;
static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
static const uint64_t kBufferUsage =
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
@@ -75,10 +74,9 @@
private:
struct FrameListener : public ConsumerBase::FrameAvailableListener {
public:
- FrameListener(BufferTransportService* service,
+ FrameListener(BufferTransportService* /*service*/,
sp<BufferItemConsumer> buffer_item_consumer)
- : service_(service),
- buffer_item_consumer_(buffer_item_consumer) {}
+ : buffer_item_consumer_(buffer_item_consumer) {}
void onFrameAvailable(const BufferItem& /*item*/) override {
BufferItem buffer;
@@ -106,7 +104,6 @@
}
private:
- BufferTransportService* service_ = nullptr;
sp<BufferItemConsumer> buffer_item_consumer_;
};
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
index c21deb0..5c837e7 100644
--- a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
@@ -5,7 +5,6 @@
#include <dvr/dvr_surface.h>
#include <system/graphics.h>
-#include <base/logging.h>
#include <gtest/gtest.h>
namespace android {
@@ -22,7 +21,7 @@
DvrBuffer* buffer2 = nullptr;
int ret2 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer2);
- ASSERT_EQ(0, ret1);
+ ASSERT_EQ(0, ret2);
ASSERT_NE(nullptr, buffer2);
AHardwareBuffer* hardware_buffer1 = nullptr;
@@ -159,7 +158,7 @@
ASSERT_EQ(0, e3);
ASSERT_NE(nullptr, buffer);
// Verify that the buffer pointer is at least 16 byte aligned.
- ASSERT_EQ(0, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
uint64_t* data = static_cast<uint64_t*>(buffer);
constexpr size_t num_values = size / sizeof(uint64_t);
@@ -192,7 +191,7 @@
ASSERT_EQ(0, e3);
ASSERT_NE(nullptr, buffer);
// Verify that the buffer pointer is at least 16 byte aligned.
- ASSERT_EQ(0, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
uint64_t* data = static_cast<uint64_t*>(buffer);
constexpr size_t num_values = size / sizeof(uint64_t);
@@ -233,7 +232,7 @@
ASSERT_EQ(0, e3);
ASSERT_NE(nullptr, buffer);
// Verify that the buffer pointer is at least 16 byte aligned.
- ASSERT_EQ(0, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
uint64_t* data = static_cast<uint64_t*>(buffer);
constexpr size_t num_values = size / sizeof(uint64_t);
@@ -241,7 +240,7 @@
for (size_t i = 0; i < num_values; ++i) {
zero |= data[i];
}
- ASSERT_EQ(0, zero);
+ ASSERT_EQ(0U, zero);
int32_t fence = -1;
int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 0d947b1..e8f4150 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -109,14 +109,14 @@
}
bool BufferLayer::isProtected() const {
- const sp<GraphicBuffer>& buffer(getBE().mBuffer);
+ const sp<GraphicBuffer>& buffer(getBE().compositionInfo.mBuffer);
return (buffer != 0) &&
(buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
}
bool BufferLayer::isVisible() const {
return !(isHiddenByPolicy()) && getAlpha() > 0.0f &&
- (getBE().mBuffer != NULL || getBE().mSidebandStream != NULL);
+ (getBE().compositionInfo.mBuffer != NULL || getBE().compositionInfo.hwc.sidebandStream != NULL);
}
bool BufferLayer::isFixedSize() const {
@@ -172,7 +172,7 @@
bool useIdentityTransform) const {
ATRACE_CALL();
- if (CC_UNLIKELY(getBE().mBuffer == 0)) {
+ if (CC_UNLIKELY(getBE().compositionInfo.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
@@ -250,8 +250,8 @@
}
// Set things up for texturing.
- mTexture.setDimensions(getBE().mBuffer->getWidth(),
- getBE().mBuffer->getHeight());
+ mTexture.setDimensions(getBE().compositionInfo.mBuffer->getWidth(),
+ getBE().compositionInfo.mBuffer->getHeight());
mTexture.setFiltering(useFiltering);
mTexture.setMatrix(textureMatrix);
@@ -387,8 +387,8 @@
// mSidebandStreamChanged was true
mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
// replicated in LayerBE until FE/BE is ready to be synchronized
- getBE().mSidebandStream = mSidebandStream;
- if (getBE().mSidebandStream != NULL) {
+ getBE().compositionInfo.hwc.sidebandStream = mSidebandStream;
+ if (getBE().compositionInfo.hwc.sidebandStream != NULL) {
setTransactionFlags(eTransactionNeeded);
mFlinger->setTransactionFlags(eTraversalNeeded);
}
@@ -422,7 +422,7 @@
// Capture the old state of the layer for comparisons later
const State& s(getDrawingState());
const bool oldOpacity = isOpaque(s);
- sp<GraphicBuffer> oldBuffer = getBE().mBuffer;
+ sp<GraphicBuffer> oldBuffer = getBE().compositionInfo.mBuffer;
if (!allTransactionsSignaled()) {
mFlinger->signalLayerUpdate();
@@ -499,11 +499,11 @@
}
// update the active buffer
- getBE().mBuffer =
- mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().mBufferSlot);
+ getBE().compositionInfo.mBuffer =
+ mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot);
// replicated in LayerBE until FE/BE is ready to be synchronized
- mActiveBuffer = getBE().mBuffer;
- if (getBE().mBuffer == NULL) {
+ mActiveBuffer = getBE().compositionInfo.mBuffer;
+ if (getBE().compositionInfo.mBuffer == NULL) {
// this can only happen if the very first buffer was rejected.
return outDirtyRegion;
}
@@ -540,15 +540,15 @@
}
if (oldBuffer != NULL) {
- uint32_t bufWidth = getBE().mBuffer->getWidth();
- uint32_t bufHeight = getBE().mBuffer->getHeight();
+ uint32_t bufWidth = getBE().compositionInfo.mBuffer->getWidth();
+ uint32_t bufHeight = getBE().compositionInfo.mBuffer->getHeight();
if (bufWidth != uint32_t(oldBuffer->width) ||
bufHeight != uint32_t(oldBuffer->height)) {
recomputeVisibleRegions = true;
}
}
- mCurrentOpacity = getOpacityForFormat(getBE().mBuffer->format);
+ mCurrentOpacity = getOpacityForFormat(getBE().compositionInfo.mBuffer->format);
if (oldOpacity != isOpaque(s)) {
recomputeVisibleRegions = true;
}
@@ -611,13 +611,13 @@
}
// Sideband layers
- if (getBE().mSidebandStream.get()) {
+ if (getBE().compositionInfo.hwc.sidebandStream.get()) {
setCompositionType(hwcId, HWC2::Composition::Sideband);
ALOGV("[%s] Requesting Sideband composition", mName.string());
- error = hwcLayer->setSidebandStream(getBE().mSidebandStream->handle());
+ error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
- getBE().mSidebandStream->handle(), to_string(error).c_str(),
+ getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
return;
@@ -641,14 +641,14 @@
uint32_t hwcSlot = 0;
sp<GraphicBuffer> hwcBuffer;
- hwcInfo.bufferCache.getHwcBuffer(getBE().mBufferSlot,
- getBE().mBuffer, &hwcSlot, &hwcBuffer);
+ hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot,
+ getBE().compositionInfo.mBuffer, &hwcSlot, &hwcBuffer);
auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
- getBE().mBuffer->handle, to_string(error).c_str(),
+ getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
static_cast<int32_t>(error));
}
}
@@ -656,7 +656,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 ((getBE().mSidebandStream == nullptr) && (getBE().mBuffer == nullptr)) {
+ if ((getBE().compositionInfo.hwc.sidebandStream == nullptr) && (getBE().compositionInfo.mBuffer == nullptr)) {
return false;
}
diff --git a/services/surfaceflinger/Effects/Daltonizer.cpp b/services/surfaceflinger/Effects/Daltonizer.cpp
index c953c68..01c9c0f 100644
--- a/services/surfaceflinger/Effects/Daltonizer.cpp
+++ b/services/surfaceflinger/Effects/Daltonizer.cpp
@@ -133,8 +133,6 @@
0.7, 0.7, 1.0, 0,
0, 0, 0, 1);
- const mat4 identity;
-
// And the magic happens here...
// We construct the matrix that will perform the whole correction.
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2a4abcb..fa4d289 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -39,7 +39,6 @@
#include <ui/PixelFormat.h>
#include <gui/BufferItem.h>
-#include <gui/BufferQueue.h>
#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
@@ -63,9 +62,7 @@
namespace android {
LayerBE::LayerBE()
- : mBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
- mBuffer(nullptr),
- mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) {
+ : mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) {
}
@@ -257,9 +254,9 @@
if (!mCurrentCrop.isEmpty()) {
// if the buffer crop is defined, we use that
crop = mCurrentCrop;
- } else if (getBE().mBuffer != NULL) {
+ } else if (getBE().compositionInfo.mBuffer != NULL) {
// otherwise we use the whole buffer
- crop = getBE().mBuffer->getBounds();
+ crop = getBE().compositionInfo.mBuffer->getBounds();
} else {
// if we don't have a buffer yet, we use an empty/invalid crop
crop.makeInvalid();
@@ -1002,9 +999,9 @@
// to the old buffer. However in the state where we don't have an old buffer
// there is no such concern but we may still be being used as a parent layer.
const bool resizePending = ((c.requested.w != c.active.w) || (c.requested.h != c.active.h)) &&
- (getBE().mBuffer != nullptr);
+ (getBE().compositionInfo.mBuffer != nullptr);
if (!isFixedSize()) {
- if (resizePending && getBE().mSidebandStream == NULL) {
+ if (resizePending && getBE().compositionInfo.hwc.sidebandStream == nullptr) {
flags |= eDontUpdateGeometryState;
}
}
@@ -1401,7 +1398,7 @@
info.mMatrix[1][0] = ds.active.transform[1][0];
info.mMatrix[1][1] = ds.active.transform[1][1];
{
- sp<const GraphicBuffer> buffer = getBE().mBuffer;
+ sp<const GraphicBuffer> buffer = getBE().compositionInfo.mBuffer;
if (buffer != 0) {
info.mActiveBufferWidth = buffer->getWidth();
info.mActiveBufferHeight = buffer->getHeight();
@@ -1616,14 +1613,25 @@
return mDrawingState.z;
}
+bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) {
+ const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
+ const State& state = useDrawing ? mDrawingState : mCurrentState;
+ return state.zOrderRelativeOf != nullptr;
+}
+
__attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::makeTraversalList(
- LayerVector::StateSet stateSet) {
+ LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers) {
LOG_ALWAYS_FATAL_IF(stateSet == LayerVector::StateSet::Invalid,
"makeTraversalList received invalid stateSet");
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
const State& state = useDrawing ? mDrawingState : mCurrentState;
+ if (state.zOrderRelatives.size() == 0) {
+ *outSkipRelativeZUsers = true;
+ return children;
+ }
+
LayerVector traverse;
for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
sp<Layer> strongRelative = weakRelative.promote();
@@ -1647,19 +1655,35 @@
* Negatively signed relatives are before 'this' in Z-order.
*/
void Layer::traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor) {
- LayerVector list = makeTraversalList(stateSet);
+ // In the case we have other layers who are using a relative Z to us, makeTraversalList will
+ // produce a new list for traversing, including our relatives, and not including our children
+ // who are relatives of another surface. In the case that there are no relative Z,
+ // makeTraversalList returns our children directly to avoid significant overhead.
+ // However in this case we need to take the responsibility for filtering children which
+ // are relatives of another surface here.
+ bool skipRelativeZUsers = false;
+ const LayerVector list = makeTraversalList(stateSet, &skipRelativeZUsers);
size_t i = 0;
for (; i < list.size(); i++) {
const auto& relative = list[i];
+ if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
+ continue;
+ }
+
if (relative->getZ() >= 0) {
break;
}
relative->traverseInZOrder(stateSet, visitor);
}
+
visitor(this);
for (; i < list.size(); i++) {
const auto& relative = list[i];
+
+ if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
+ continue;
+ }
relative->traverseInZOrder(stateSet, visitor);
}
}
@@ -1669,11 +1693,18 @@
*/
void Layer::traverseInReverseZOrder(LayerVector::StateSet stateSet,
const LayerVector::Visitor& visitor) {
- LayerVector list = makeTraversalList(stateSet);
+ // See traverseInZOrder for documentation.
+ bool skipRelativeZUsers = false;
+ LayerVector list = makeTraversalList(stateSet, &skipRelativeZUsers);
int32_t i = 0;
for (i = int32_t(list.size()) - 1; i >= 0; i--) {
const auto& relative = list[i];
+
+ if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
+ continue;
+ }
+
if (relative->getZ() < 0) {
break;
}
@@ -1682,6 +1713,11 @@
visitor(this);
for (; i >= 0; i--) {
const auto& relative = list[i];
+
+ if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
+ continue;
+ }
+
relative->traverseInReverseZOrder(stateSet, visitor);
}
}
@@ -1720,15 +1756,15 @@
// for in the transform. We need to mirror this scaling in child surfaces
// or we will break the contract where WM can treat child surfaces as
// pixels in the parent surface.
- if (p->isFixedSize() && p->getBE().mBuffer != nullptr) {
+ if (p->isFixedSize() && p->getBE().compositionInfo.mBuffer != nullptr) {
int bufferWidth;
int bufferHeight;
if ((p->mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) == 0) {
- bufferWidth = p->getBE().mBuffer->getWidth();
- bufferHeight = p->getBE().mBuffer->getHeight();
+ bufferWidth = p->getBE().compositionInfo.mBuffer->getWidth();
+ bufferHeight = p->getBE().compositionInfo.mBuffer->getHeight();
} else {
- bufferHeight = p->getBE().mBuffer->getWidth();
- bufferWidth = p->getBE().mBuffer->getHeight();
+ bufferHeight = p->getBE().compositionInfo.mBuffer->getWidth();
+ bufferWidth = p->getBE().compositionInfo.mBuffer->getHeight();
}
float sx = p->getDrawingState().active.w / static_cast<float>(bufferWidth);
float sy = p->getDrawingState().active.h / static_cast<float>(bufferHeight);
@@ -1828,7 +1864,7 @@
layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
}
- auto buffer = getBE().mBuffer;
+ auto buffer = getBE().compositionInfo.mBuffer;
if (buffer != nullptr) {
LayerProtoHelper::writeToProto(buffer, layerInfo->mutable_active_buffer());
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 8ac5094..cf7fc50 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -31,6 +31,7 @@
#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerState.h>
+#include <gui/BufferQueue.h>
#include <list>
@@ -66,15 +67,37 @@
// ---------------------------------------------------------------------------
+struct CompositionInfo {
+ HWC2::Composition compositionType;
+ sp<GraphicBuffer> mBuffer = nullptr;
+ int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
+ struct {
+ HWComposer* hwc;
+ sp<Fence> fence;
+ HWC2::BlendMode blendMode;
+ Rect displayFrame;
+ float alpha;
+ FloatRect sourceCrop;
+ HWC2::Transform transform;
+ int z;
+ int type;
+ int appId;
+ Region visibleRegion;
+ Region surfaceDamage;
+ sp<NativeHandle> sidebandStream;
+ android_dataspace dataspace;
+ hwc_color_t color;
+ } hwc;
+ struct {
+ RenderEngine* renderEngine;
+ Mesh* mesh;
+ } renderEngine;
+};
+
class LayerBE {
public:
LayerBE();
- // main thread
- int mBufferSlot;
- sp<GraphicBuffer> mBuffer;
- sp<NativeHandle> mSidebandStream;
-
// The mesh used to draw the layer in GLES composition mode
Mesh mMesh;
@@ -102,6 +125,8 @@
// case we need to keep track. In non-mirror mode, a layer will have only one
// HWCInfo. This map key is a display layerStack.
std::unordered_map<int32_t, HWCInfo> mHwcLayers;
+
+ CompositionInfo compositionInfo;
};
class Layer : public virtual RefBase {
@@ -571,7 +596,7 @@
void setParent(const sp<Layer>& layer);
- LayerVector makeTraversalList(LayerVector::StateSet stateSet);
+ LayerVector makeTraversalList(LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers);
void addZOrderRelative(const wp<Layer>& relative);
void removeZOrderRelative(const wp<Layer>& relative);
@@ -645,6 +670,7 @@
protected:
// -----------------------------------------------------------------------
+ bool usingRelativeZ(LayerVector::StateSet stateSet);
bool mPremultipliedAlpha;
String8 mName;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 142892e..54695b5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -153,6 +153,15 @@
return std::string(value) == "true";
}
+SurfaceFlingerBE::SurfaceFlingerBE()
+ : mHwcServiceName(getHwcServiceName()),
+ mRenderEngine(nullptr),
+ mFrameBuckets(),
+ mTotalTime(0),
+ mLastSwapTime(0),
+ mComposerSequenceId(0) {
+}
+
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(),
mTransactionFlags(0),
@@ -161,8 +170,6 @@
mLayersRemoved(false),
mLayersAdded(false),
mRepaintEverything(0),
- mHwcServiceName(getHwcServiceName()),
- mRenderEngine(nullptr),
mBootTime(systemTime()),
mBuiltinDisplays(),
mVisibleRegionsDirty(false),
@@ -184,13 +191,9 @@
mHWVsyncAvailable(false),
mHasColorMatrix(false),
mHasPoweredOff(false),
- mFrameBuckets(),
- mTotalTime(0),
- mLastSwapTime(0),
mNumLayers(0),
mVrFlingerRequestsDisplay(false),
- mMainThreadId(std::this_thread::get_id()),
- mComposerSequenceId(0)
+ mMainThreadId(std::this_thread::get_id())
{
ALOGI("SurfaceFlinger is starting");
@@ -225,7 +228,7 @@
hasWideColorDisplay =
getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
- mPrimaryDispSync.init(hasSyncFramework, dispSyncPresentTimeOffset);
+ mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset);
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
@@ -588,11 +591,11 @@
Mutex::Autolock _l(mStateLock);
// start the EventThread
- sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- vsyncPhaseOffsetNs, true, "app");
+ sp<VSyncSource> vsyncSrc =
+ new DispSyncSource(&mPrimaryDispSync, SurfaceFlinger::vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc, *this, false);
- sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- sfVsyncPhaseOffsetNs, true, "sf");
+ sp<VSyncSource> sfVsyncSrc =
+ new DispSyncSource(&mPrimaryDispSync, SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
mEventQueue.setEventThread(mSFEventThread);
@@ -607,14 +610,14 @@
}
// Get a RenderEngine for the given display / config (can't fail)
- mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
+ getBE().mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
hasWideColorDisplay ? RenderEngine::WIDE_COLOR_SUPPORT : 0);
- LOG_ALWAYS_FATAL_IF(mRenderEngine == nullptr, "couldn't create RenderEngine");
+ LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
"Starting with vr flinger active is not currently supported.");
- mHwc.reset(new HWComposer(mHwcServiceName));
- mHwc->registerCallback(this, mComposerSequenceId);
+ getBE().mHwc.reset(new HWComposer(getBE().mHwcServiceName));
+ getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);
if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
@@ -631,8 +634,8 @@
});
postMessageAsync(message);
};
- mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
- mHwc->getHwcDisplayId(HWC_DISPLAY_PRIMARY).value_or(0),
+ mVrFlinger = dvr::VrFlinger::Create(getBE().mHwc->getComposer(),
+ getBE().mHwc->getHwcDisplayId(HWC_DISPLAY_PRIMARY).value_or(0),
vrFlingerRequestDisplayCallback);
if (!mVrFlinger) {
ALOGE("Failed to start vrflinger");
@@ -648,7 +651,7 @@
// set initial conditions (e.g. unblank default device)
initializeDisplays();
- mRenderEngine->primeCache();
+ getBE().mRenderEngine->primeCache();
// Inform native graphics APIs whether the present timestamp is supported:
if (getHwComposer().hasCapability(
@@ -690,11 +693,11 @@
}
size_t SurfaceFlinger::getMaxTextureSize() const {
- return mRenderEngine->getMaxTextureSize();
+ return getBE().mRenderEngine->getMaxTextureSize();
}
size_t SurfaceFlinger::getMaxViewportDims() const {
- return mRenderEngine->getMaxViewportDims();
+ return getBE().mRenderEngine->getMaxViewportDims();
}
// ----------------------------------------------------------------------------
@@ -1042,7 +1045,7 @@
}
std::unique_ptr<HdrCapabilities> capabilities =
- mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
+ getBE().mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
if (capabilities) {
std::swap(*outCapabilities, *capabilities);
} else {
@@ -1190,7 +1193,7 @@
return;
}
- const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+ const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
const nsecs_t period = activeConfig->getVsyncPeriod();
mPrimaryDispSync.reset();
@@ -1233,12 +1236,12 @@
hwc2_display_t displayId, int64_t timestamp) {
Mutex::Autolock lock(mStateLock);
// Ignore any vsyncs from a previous hardware composer.
- if (sequenceId != mComposerSequenceId) {
+ if (sequenceId != getBE().mComposerSequenceId) {
return;
}
int32_t type;
- if (!mHwc->onVsync(displayId, timestamp, &type)) {
+ if (!getBE().mHwc->onVsync(displayId, timestamp, &type)) {
return;
}
@@ -1259,8 +1262,8 @@
}
void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
- std::lock_guard<std::mutex> lock(mCompositorTimingLock);
- *compositorTiming = mCompositorTiming;
+ std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
+ *compositorTiming = getBE().mCompositorTiming;
}
void SurfaceFlinger::createDefaultDisplayDevice() {
@@ -1274,7 +1277,7 @@
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
- sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);
+ sp<FramebufferSurface> fbs = new FramebufferSurface(*getBE().mHwc, type, consumer);
bool hasWideColorModes = false;
std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
@@ -1326,20 +1329,20 @@
std::this_thread::get_id() != mMainThreadId);
if (primaryDisplay) {
- mHwc->onHotplug(display, connection);
+ getBE().mHwc->onHotplug(display, connection);
if (!mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY].get()) {
createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
}
createDefaultDisplayDevice();
} else {
- if (sequenceId != mComposerSequenceId) {
+ if (sequenceId != getBE().mComposerSequenceId) {
return;
}
- if (mHwc->isUsingVrComposer()) {
+ if (getBE().mHwc->isUsingVrComposer()) {
ALOGE("External displays are not supported by the vr hardware composer.");
return;
}
- mHwc->onHotplug(display, connection);
+ getBE().mHwc->onHotplug(display, connection);
auto type = DisplayDevice::DISPLAY_EXTERNAL;
if (connection == HWC2::Connection::Connected) {
createBuiltinDisplayLocked(type);
@@ -1356,7 +1359,7 @@
void SurfaceFlinger::onRefreshReceived(int sequenceId,
hwc2_display_t /*display*/) {
Mutex::Autolock lock(mStateLock);
- if (sequenceId != mComposerSequenceId) {
+ if (sequenceId != getBE().mComposerSequenceId) {
return;
}
repaintEverythingLocked();
@@ -1385,11 +1388,11 @@
if (!mVrFlinger)
return;
bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay;
- if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
+ if (vrFlingerRequestsDisplay == getBE().mHwc->isUsingVrComposer()) {
return;
}
- if (vrFlingerRequestsDisplay && !mHwc->getComposer()->isRemote()) {
+ if (vrFlingerRequestsDisplay && !getBE().mHwc->getComposer()->isRemote()) {
ALOGE("Vr flinger is only supported for remote hardware composer"
" service connections. Ignoring request to transition to vr"
" flinger.");
@@ -1407,13 +1410,12 @@
}
resetDisplayState();
- mHwc.reset(); // Delete the current instance before creating the new one
- mHwc.reset(new HWComposer(
- vrFlingerRequestsDisplay ? "vr" : mHwcServiceName));
- mHwc->registerCallback(this, ++mComposerSequenceId);
+ getBE().mHwc.reset(); // Delete the current instance before creating the new one
+ getBE().mHwc.reset(new HWComposer(vrFlingerRequestsDisplay ? "vr" : getBE().mHwcServiceName));
+ getBE().mHwc->registerCallback(this, ++getBE().mComposerSequenceId);
- LOG_ALWAYS_FATAL_IF(!mHwc->getComposer()->isRemote(),
- "Switched to non-remote hardware composer");
+ LOG_ALWAYS_FATAL_IF(!getBE().mHwc->getComposer()->isRemote(),
+ "Switched to non-remote hardware composer");
if (vrFlingerRequestsDisplay) {
mVrFlinger->GrantDisplayOwnership();
@@ -1430,7 +1432,7 @@
setPowerModeInternal(hw, currentDisplayPowerMode, /*stateLockHeld*/ true);
// Reset the timing values to account for the period of the swapped in HWC
- const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+ const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
const nsecs_t period = activeConfig->getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(period);
@@ -1508,13 +1510,13 @@
doComposition();
postComposition(refreshStartTime);
- mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
+ mPreviousPresentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
mHadClientComposition = false;
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
mHadClientComposition = mHadClientComposition ||
- mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
+ getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
}
mLayersWithQueuedFrames.clear();
@@ -1558,9 +1560,11 @@
continue;
}
- status_t result = displayDevice->prepareFrame(*mHwc);
- ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
- " %d (%s)", displayId, result, strerror(-result));
+ status_t result = displayDevice->prepareFrame(*getBE().mHwc);
+ ALOGE_IF(result != NO_ERROR,
+ "prepareFrame for display %zd failed:"
+ " %d (%s)",
+ displayId, result, strerror(-result));
}
}
@@ -1594,10 +1598,10 @@
std::shared_ptr<FenceTime>& presentFenceTime) {
// Update queue of past composite+present times and determine the
// most recently known composite to present latency.
- mCompositePresentTimes.push({compositeTime, presentFenceTime});
+ getBE().mCompositePresentTimes.push({compositeTime, presentFenceTime});
nsecs_t compositeToPresentLatency = -1;
- while (!mCompositePresentTimes.empty()) {
- CompositePresentTime& cpt = mCompositePresentTimes.front();
+ while (!getBE().mCompositePresentTimes.empty()) {
+ SurfaceFlingerBE::CompositePresentTime& cpt = getBE().mCompositePresentTimes.front();
// Cached values should have been updated before calling this method,
// which helps avoid duplicate syscalls.
nsecs_t displayTime = cpt.display->getCachedSignalTime();
@@ -1605,12 +1609,12 @@
break;
}
compositeToPresentLatency = displayTime - cpt.composite;
- mCompositePresentTimes.pop();
+ getBE().mCompositePresentTimes.pop();
}
// Don't let mCompositePresentTimes grow unbounded, just in case.
- while (mCompositePresentTimes.size() > 16) {
- mCompositePresentTimes.pop();
+ while (getBE().mCompositePresentTimes.size() > 16) {
+ getBE().mCompositePresentTimes.pop();
}
setCompositorTimingSnapped(
@@ -1642,10 +1646,10 @@
nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
- std::lock_guard<std::mutex> lock(mCompositorTimingLock);
- mCompositorTiming.deadline = vsyncPhase - idealLatency;
- mCompositorTiming.interval = vsyncInterval;
- mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
+ std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
+ getBE().mCompositorTiming.deadline = vsyncPhase - idealLatency;
+ getBE().mCompositorTiming.interval = vsyncInterval;
+ getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
}
void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
@@ -1662,20 +1666,20 @@
// |mStateLock| not needed as we are on the main thread
const sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
- mGlCompositionDoneTimeline.updateSignalTimes();
+ getBE().mGlCompositionDoneTimeline.updateSignalTimes();
std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
- if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
+ if (getBE().mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
glCompositionDoneFenceTime =
std::make_shared<FenceTime>(hw->getClientTargetAcquireFence());
- mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
+ getBE().mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
} else {
glCompositionDoneFenceTime = FenceTime::NO_FENCE;
}
- mDisplayTimeline.updateSignalTimes();
- sp<Fence> presentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
+ getBE().mDisplayTimeline.updateSignalTimes();
+ sp<Fence> presentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
auto presentFenceTime = std::make_shared<FenceTime>(presentFence);
- mDisplayTimeline.push(presentFenceTime);
+ getBE().mDisplayTimeline.push(presentFenceTime);
nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod();
@@ -1687,8 +1691,8 @@
vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime);
CompositorTiming compositorTiming;
{
- std::lock_guard<std::mutex> lock(mCompositorTimingLock);
- compositorTiming = mCompositorTiming;
+ std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
+ compositorTiming = getBE().mCompositorTiming;
}
mDrawingState.traverseInZOrder([&](Layer* layer) {
@@ -1724,7 +1728,7 @@
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
nsecs_t presentTime =
- mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
+ getBE().mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
mAnimFrameTracker.setActualPresentTime(presentTime);
}
mAnimFrameTracker.advanceFrame();
@@ -1738,16 +1742,16 @@
if (mHasPoweredOff) {
mHasPoweredOff = false;
} else {
- nsecs_t elapsedTime = currentTime - mLastSwapTime;
+ nsecs_t elapsedTime = currentTime - getBE().mLastSwapTime;
size_t numPeriods = static_cast<size_t>(elapsedTime / vsyncInterval);
- if (numPeriods < NUM_BUCKETS - 1) {
- mFrameBuckets[numPeriods] += elapsedTime;
+ if (numPeriods < SurfaceFlingerBE::NUM_BUCKETS - 1) {
+ getBE().mFrameBuckets[numPeriods] += elapsedTime;
} else {
- mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
+ getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1] += elapsedTime;
}
- mTotalTime += elapsedTime;
+ getBE().mTotalTime += elapsedTime;
}
- mLastSwapTime = currentTime;
+ getBE().mLastSwapTime = currentTime;
}
void SurfaceFlinger::rebuildLayerStacks() {
@@ -1923,7 +1927,7 @@
for (size_t i = 0; i < currentLayers.size(); i++) {
const auto& layer = currentLayers[i];
if (!layer->hasHwcLayer(hwcId)) {
- if (!layer->createHwcLayer(mHwc.get(), hwcId)) {
+ if (!layer->createHwcLayer(getBE().mHwc.get(), hwcId)) {
layer->forceClientComposition(hwcId);
continue;
}
@@ -1950,7 +1954,7 @@
continue;
}
if (colorMatrix != mPreviousColorMatrix) {
- status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
+ status_t result = getBE().mHwc->setColorTransform(hwcId, colorMatrix);
ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
"display %zd: %d", displayId, result);
}
@@ -1988,7 +1992,7 @@
continue;
}
- status_t result = displayDevice->prepareFrame(*mHwc);
+ status_t result = displayDevice->prepareFrame(*getBE().mHwc);
ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
" %d (%s)", displayId, result, strerror(-result));
}
@@ -2030,7 +2034,7 @@
}
const auto hwcId = displayDevice->getHwcDisplayId();
if (hwcId >= 0) {
- mHwc->presentAndGetReleaseFences(hwcId);
+ getBE().mHwc->presentAndGetReleaseFences(hwcId);
}
displayDevice->onSwapBuffersCompleted();
displayDevice->makeCurrent();
@@ -2039,7 +2043,7 @@
// by HWC only when the release fence from this frame (if any) is
// signaled. Always get the release fence from HWC first.
auto hwcLayer = layer->getHwcLayer(hwcId);
- sp<Fence> releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
+ sp<Fence> releaseFence = getBE().mHwc->getLayerReleaseFence(hwcId, hwcLayer);
// If the layer was client composited in the previous frame, we
// need to merge with the previous client target acquire fence.
@@ -2058,14 +2062,14 @@
// displayDevice->getVisibleLayersSortedByZ. The best we can do is to
// supply them with the present fence.
if (!displayDevice->getLayersNeedingFences().isEmpty()) {
- sp<Fence> presentFence = mHwc->getPresentFence(hwcId);
+ sp<Fence> presentFence = getBE().mHwc->getPresentFence(hwcId);
for (auto& layer : displayDevice->getLayersNeedingFences()) {
layer->onLayerDisplayed(presentFence);
}
}
if (hwcId >= 0) {
- mHwc->clearReleaseFences(hwcId);
+ getBE().mHwc->clearReleaseFences(hwcId);
}
}
@@ -2229,7 +2233,7 @@
if (state.surface != NULL) {
// Allow VR composer to use virtual displays.
- if (mUseHwcVirtualDisplays || mHwc->isUsingVrComposer()) {
+ if (mUseHwcVirtualDisplays || getBE().mHwc->isUsingVrComposer()) {
int width = 0;
int status = state.surface->query(
NATIVE_WINDOW_WIDTH, &width);
@@ -2248,14 +2252,14 @@
auto format = static_cast<android_pixel_format_t>(
intFormat);
- mHwc->allocateVirtualDisplay(width, height, &format,
+ getBE().mHwc->allocateVirtualDisplay(width, height, &format,
&hwcId);
}
// TODO: Plumb requested format back up to consumer
sp<VirtualDisplaySurface> vds =
- new VirtualDisplaySurface(*mHwc,
+ new VirtualDisplaySurface(*getBE().mHwc,
hwcId, state.surface, bqProducer,
bqConsumer, state.displayName);
@@ -2269,7 +2273,7 @@
state.surface.get());
hwcId = state.type;
- dispSurface = new FramebufferSurface(*mHwc, hwcId, bqConsumer);
+ dispSurface = new FramebufferSurface(*getBE().mHwc, hwcId, bqConsumer);
producer = bqProducer;
}
@@ -2657,20 +2661,20 @@
const auto hwcId = displayDevice->getHwcDisplayId();
mat4 oldColorMatrix;
- const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
- !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
+ const bool applyColorMatrix = !getBE().mHwc->hasDeviceComposition(hwcId) &&
+ !getBE().mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
if (applyColorMatrix) {
mat4 colorMatrix = mColorMatrix * mDaltonizer();
oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
}
- bool hasClientComposition = mHwc->hasClientComposition(hwcId);
+ bool hasClientComposition = getBE().mHwc->hasClientComposition(hwcId);
if (hasClientComposition) {
ALOGV("hasClientComposition");
- mRenderEngine->setWideColor(
+ getBE().mRenderEngine->setWideColor(
displayDevice->getWideColorSupport() && !mForceNativeColorMode);
- mRenderEngine->setColorMode(mForceNativeColorMode ?
+ getBE().mRenderEngine->setColorMode(mForceNativeColorMode ?
HAL_COLOR_MODE_NATIVE : displayDevice->getActiveColorMode());
if (!displayDevice->makeCurrent()) {
ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
@@ -2685,14 +2689,14 @@
}
// Never touch the framebuffer if we don't have any framebuffer layers
- const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
+ const bool hasDeviceComposition = getBE().mHwc->hasDeviceComposition(hwcId);
if (hasDeviceComposition) {
// when using overlays, we assume a fully transparent framebuffer
// NOTE: we could reduce how much we need to clear, for instance
// remove where there are opaque FB layers. however, on some
// GPUs doing a "clean slate" clear might be more efficient.
// We'll revisit later if needed.
- mRenderEngine->clearWithColor(0, 0, 0, 0);
+ getBE().mRenderEngine->clearWithColor(0, 0, 0, 0);
} else {
// we start with the whole screen area and remove the scissor part
// we're left with the letterbox region
@@ -2722,7 +2726,7 @@
// enable scissor for this frame
const uint32_t height = displayDevice->getHeight();
- mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
+ getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
scissor.getWidth(), scissor.getHeight());
}
}
@@ -2787,7 +2791,7 @@
}
// disable scissor at the end of the frame
- mRenderEngine->disableScissor();
+ getBE().mRenderEngine->disableScissor();
return true;
}
@@ -3359,7 +3363,7 @@
setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL,
/*stateLockHeld*/ false);
- const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+ const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
const nsecs_t period = activeConfig->getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(period);
@@ -3612,7 +3616,7 @@
index++;
}
- const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+ const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
const nsecs_t period = activeConfig->getVsyncPeriod();
result.appendFormat("%" PRId64 "\n", period);
@@ -3675,24 +3679,24 @@
void SurfaceFlinger::dumpStaticScreenStats(String8& result) const
{
result.appendFormat("Static screen stats:\n");
- for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
- float bucketTimeSec = mFrameBuckets[b] / 1e9;
+ for (size_t b = 0; b < SurfaceFlingerBE::NUM_BUCKETS - 1; ++b) {
+ float bucketTimeSec = getBE().mFrameBuckets[b] / 1e9;
float percent = 100.0f *
- static_cast<float>(mFrameBuckets[b]) / mTotalTime;
+ static_cast<float>(getBE().mFrameBuckets[b]) / getBE().mTotalTime;
result.appendFormat(" < %zd frames: %.3f s (%.1f%%)\n",
b + 1, bucketTimeSec, percent);
}
- float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
+ float bucketTimeSec = getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1] / 1e9;
float percent = 100.0f *
- static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
+ static_cast<float>(getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1]) / getBE().mTotalTime;
result.appendFormat(" %zd+ frames: %.3f s (%.1f%%)\n",
- NUM_BUCKETS - 1, bucketTimeSec, percent);
+ SurfaceFlingerBE::NUM_BUCKETS - 1, bucketTimeSec, percent);
}
void SurfaceFlinger::recordBufferingStats(const char* layerName,
std::vector<OccupancyTracker::Segment>&& history) {
- Mutex::Autolock lock(mBufferingStatsMutex);
- auto& stats = mBufferingStats[layerName];
+ Mutex::Autolock lock(getBE().mBufferingStatsMutex);
+ auto& stats = getBE().mBufferingStats[layerName];
for (const auto& segment : history) {
if (!segment.usedThirdBuffer) {
stats.twoBufferTime += segment.totalTime;
@@ -3721,12 +3725,12 @@
result.append("Buffering stats:\n");
result.append(" [Layer name] <Active time> <Two buffer> "
"<Double buffered> <Triple buffered>\n");
- Mutex::Autolock lock(mBufferingStatsMutex);
+ Mutex::Autolock lock(getBE().mBufferingStatsMutex);
typedef std::tuple<std::string, float, float, float> BufferTuple;
std::map<float, BufferTuple, std::greater<float>> sorted;
- for (const auto& statsPair : mBufferingStats) {
+ for (const auto& statsPair : getBE().mBufferingStats) {
const char* name = statsPair.first.c_str();
- const BufferingStats& stats = statsPair.second;
+ const SurfaceFlingerBE::BufferingStats& stats = statsPair.second;
if (stats.numSegments == 0) {
continue;
}
@@ -3829,7 +3833,7 @@
result.append(SyncFeatures::getInstance().toString());
result.append("\n");
- const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
+ const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
colorizer.bold(result);
result.append("DispSync configuration: ");
@@ -3881,7 +3885,7 @@
HWComposer& hwc(getHwComposer());
sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
- mRenderEngine->dump(result);
+ getBE().mRenderEngine->dump(result);
hw->undefinedRegion.dump(result, "undefinedRegion");
result.appendFormat(" orientation=%d, isDisplayOn=%d\n",
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 974de94..2477bdc 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -92,6 +92,7 @@
class EventControlThread;
class VSyncSource;
class InjectVSyncSource;
+class SurfaceFlingerBE;
typedef std::function<void(const LayerVector::Visitor&)> TraverseLayersFunction;
@@ -108,12 +109,97 @@
eTransactionMask = 0x07
};
+class SurfaceFlingerBE
+{
+public:
+ SurfaceFlingerBE();
+
+ // The current hardware composer interface.
+ //
+ // The following thread safety rules apply when accessing mHwc, either
+ // directly or via getHwComposer():
+ //
+ // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
+ // only when switching into and out of vr. Recreating mHwc must only be
+ // done on the main thread.
+ //
+ // 2. When accessing mHwc on the main thread, it's not necessary to acquire
+ // mStateLock.
+ //
+ // 3. When accessing mHwc on a thread other than the main thread, we always
+ // need to acquire mStateLock. This is because the main thread could be
+ // in the process of destroying the current mHwc instance.
+ //
+ // The above thread safety rules only apply to SurfaceFlinger.cpp. In
+ // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
+ // destroy it, so it's always safe to access mHwc from any thread without
+ // acquiring mStateLock.
+ std::unique_ptr<HWComposer> mHwc;
+
+ const std::string mHwcServiceName; // "default" for real use, something else for testing.
+
+ // constant members (no synchronization needed for access)
+ std::unique_ptr<RenderEngine> mRenderEngine;
+ EGLContext mEGLContext;
+ EGLDisplay mEGLDisplay;
+
+ FenceTimeline mGlCompositionDoneTimeline;
+ FenceTimeline mDisplayTimeline;
+
+ // protected by mCompositorTimingLock;
+ mutable std::mutex mCompositorTimingLock;
+ CompositorTiming mCompositorTiming;
+
+ // Only accessed from the main thread.
+ struct CompositePresentTime {
+ nsecs_t composite { -1 };
+ std::shared_ptr<FenceTime> display { FenceTime::NO_FENCE };
+ };
+ std::queue<CompositePresentTime> mCompositePresentTimes;
+
+ static const size_t NUM_BUCKETS = 8; // < 1-7, 7+
+ nsecs_t mFrameBuckets[NUM_BUCKETS];
+ nsecs_t mTotalTime;
+ std::atomic<nsecs_t> mLastSwapTime;
+
+ // Double- vs. triple-buffering stats
+ struct BufferingStats {
+ BufferingStats()
+ : numSegments(0),
+ totalTime(0),
+ twoBufferTime(0),
+ doubleBufferedTime(0),
+ tripleBufferedTime(0) {}
+
+ size_t numSegments;
+ nsecs_t totalTime;
+
+ // "Two buffer" means that a third buffer was never used, whereas
+ // "double-buffered" means that on average the segment only used two
+ // buffers (though it may have used a third for some part of the
+ // segment)
+ nsecs_t twoBufferTime;
+ nsecs_t doubleBufferedTime;
+ nsecs_t tripleBufferedTime;
+ };
+ mutable Mutex mBufferingStatsMutex;
+ std::unordered_map<std::string, BufferingStats> mBufferingStats;
+
+ // The composer sequence id is a monotonically increasing integer that we
+ // use to differentiate callbacks from different hardware composer
+ // instances. Each hardware composer instance gets a different sequence id.
+ int32_t mComposerSequenceId;
+};
+
+
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback
{
public:
+ SurfaceFlingerBE& getBE() { return mBE; }
+ const SurfaceFlingerBE& getBE() const { return mBE; }
// This is the phase offset in nanoseconds of the software vsync event
// relative to the vsync event reported by HWComposer. The software vsync
@@ -219,7 +305,7 @@
const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int id);
RenderEngine& getRenderEngine() const {
- return *mRenderEngine;
+ return *getBE().mRenderEngine;
}
bool authenticateSurfaceTextureLocked(
@@ -509,7 +595,7 @@
* H/W composer
*/
- HWComposer& getHwComposer() const { return *mHwc; }
+ HWComposer& getHwComposer() const { return *getBE().mHwc; }
/* ------------------------------------------------------------------------
* Compositing
@@ -632,32 +718,7 @@
// access must be protected by mInvalidateLock
volatile int32_t mRepaintEverything;
- // The current hardware composer interface.
- //
- // The following thread safety rules apply when accessing mHwc, either
- // directly or via getHwComposer():
- //
- // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
- // only when switching into and out of vr. Recreating mHwc must only be
- // done on the main thread.
- //
- // 2. When accessing mHwc on the main thread, it's not necessary to acquire
- // mStateLock.
- //
- // 3. When accessing mHwc on a thread other than the main thread, we always
- // need to acquire mStateLock. This is because the main thread could be
- // in the process of destroying the current mHwc instance.
- //
- // The above thread safety rules only apply to SurfaceFlinger.cpp. In
- // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
- // destroy it, so it's always safe to access mHwc from any thread without
- // acquiring mStateLock.
- std::unique_ptr<HWComposer> mHwc;
-
- const std::string mHwcServiceName; // "default" for real use, something else for testing.
-
// constant members (no synchronization needed for access)
- std::unique_ptr<RenderEngine> mRenderEngine;
nsecs_t mBootTime;
bool mGpuToCpuSupported;
sp<EventThread> mEventThread;
@@ -676,8 +737,6 @@
std::vector<sp<Layer>> mLayersWithQueuedFrames;
sp<Fence> mPreviousPresentFence = Fence::NO_FENCE;
bool mHadClientComposition = false;
- FenceTimeline mGlCompositionDoneTimeline;
- FenceTimeline mDisplayTimeline;
// this may only be written from the main thread with mStateLock held
// it may be read from other threads with mStateLock held
@@ -716,17 +775,6 @@
bool mPrimaryHWVsyncEnabled;
bool mHWVsyncAvailable;
- // protected by mCompositorTimingLock;
- mutable std::mutex mCompositorTimingLock;
- CompositorTiming mCompositorTiming;
-
- // Only accessed from the main thread.
- struct CompositePresentTime {
- nsecs_t composite { -1 };
- std::shared_ptr<FenceTime> display { FenceTime::NO_FENCE };
- };
- std::queue<CompositePresentTime> mCompositePresentTimes;
-
std::atomic<bool> mRefreshPending{false};
/* ------------------------------------------------------------------------
@@ -743,35 +791,9 @@
// Static screen stats
bool mHasPoweredOff;
- static const size_t NUM_BUCKETS = 8; // < 1-7, 7+
- nsecs_t mFrameBuckets[NUM_BUCKETS];
- nsecs_t mTotalTime;
- std::atomic<nsecs_t> mLastSwapTime;
size_t mNumLayers;
- // Double- vs. triple-buffering stats
- struct BufferingStats {
- BufferingStats()
- : numSegments(0),
- totalTime(0),
- twoBufferTime(0),
- doubleBufferedTime(0),
- tripleBufferedTime(0) {}
-
- size_t numSegments;
- nsecs_t totalTime;
-
- // "Two buffer" means that a third buffer was never used, whereas
- // "double-buffered" means that on average the segment only used two
- // buffers (though it may have used a third for some part of the
- // segment)
- nsecs_t twoBufferTime;
- nsecs_t doubleBufferedTime;
- nsecs_t tripleBufferedTime;
- };
- mutable Mutex mBufferingStatsMutex;
- std::unordered_map<std::string, BufferingStats> mBufferingStats;
// Verify that transaction is being called by an approved process:
// either AID_GRAPHICS or AID_SYSTEM.
@@ -781,13 +803,11 @@
std::atomic<bool> mVrFlingerRequestsDisplay;
static bool useVrFlinger;
std::thread::id mMainThreadId;
- // The composer sequence id is a monotonically increasing integer that we
- // use to differentiate callbacks from different hardware composer
- // instances. Each hardware composer instance gets a different sequence id.
- int32_t mComposerSequenceId;
float mSaturation = 1.0f;
bool mForceNativeColorMode = false;
+
+ SurfaceFlingerBE mBE;
};
}; // namespace android
diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
index d97ffa3..d949d48 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
@@ -581,7 +581,7 @@
}
void FakeComposerClient::onSurfaceFlingerStart() {
- mSurfaceComposer == nullptr;
+ mSurfaceComposer = nullptr;
do {
mSurfaceComposer = new android::SurfaceComposerClient;
android::status_t initResult = mSurfaceComposer->initCheck();
diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
index 7f4c58a..8a97ea4 100644
--- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
+++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
@@ -165,7 +165,7 @@
sp<ComposerClient> client = new ComposerClient(*mMockComposer);
mMockComposer->setClient(client.get());
mFakeService = new FakeComposerService(client);
- mFakeService->registerAsService("mock");
+ (void)mFakeService->registerAsService("mock");
android::hardware::ProcessState::self()->startThreadPool();
android::ProcessState::self()->startThreadPool();
@@ -323,7 +323,7 @@
sp<ComposerClient> client = new ComposerClient(*sFakeComposer);
sFakeComposer->setClient(client.get());
sp<IComposer> fakeService = new FakeComposerService(client);
- fakeService->registerAsService("mock");
+ (void)fakeService->registerAsService("mock");
android::hardware::ProcessState::self()->startThreadPool();
android::ProcessState::self()->startThreadPool();