Merge "[Mirror Layers] Added clone function to layers (1/4)"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 86558ef..d9c9e4a 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1057,7 +1057,7 @@
std::string path(title);
path.append(" - ").append(String8(service).c_str());
size_t bytes_written = 0;
- status_t status = dumpsys.startDumpThread(service, args);
+ status_t status = dumpsys.startDumpThread(service, /* dumpPid = */ true, args);
if (status == OK) {
dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
std::chrono::duration<double> elapsed_seconds;
@@ -1129,7 +1129,7 @@
path.append("_HIGH");
}
path.append(kProtoExt);
- status_t status = dumpsys.startDumpThread(service, args);
+ status_t status = dumpsys.startDumpThread(service, /* dumpPid = */ false, args);
if (status == OK) {
status = ds.AddZipEntryFromFd(path, dumpsys.getDumpFd(), service_timeout);
bool dumpTerminated = (status == OK);
@@ -2708,7 +2708,7 @@
}
/* tell activity manager we're done */
- if (options_->do_broadcast) {
+ if (options_->do_broadcast && !CalledByApi()) {
SendBugreportFinishedBroadcast();
// Note that listener_ is notified in Run();
}
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 4811927..68b3907 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -236,11 +236,13 @@
return 0;
}
+ const bool dumpPid = !asProto;
+
for (size_t i = 0; i < N; i++) {
const String16& serviceName = services[i];
if (IsSkipped(skippedServices, serviceName)) continue;
- if (startDumpThread(serviceName, args) == OK) {
+ if (startDumpThread(serviceName, dumpPid, args) == OK) {
bool addSeparator = (N > 1);
if (addSeparator) {
writeDumpHeader(STDOUT_FILENO, serviceName, priorityFlags);
@@ -307,7 +309,7 @@
}
}
-status_t Dumpsys::startDumpThread(const String16& serviceName, const Vector<String16>& args) {
+status_t Dumpsys::startDumpThread(const String16& serviceName, bool dumpPid, const Vector<String16>& args) {
sp<IBinder> service = sm_->checkService(serviceName);
if (service == nullptr) {
aerr << "Can't find service: " << serviceName << endl;
@@ -327,7 +329,20 @@
// dump blocks until completion, so spawn a thread..
activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable {
- int err = service->dump(remote_end.get(), args);
+ if (dumpPid) {
+ pid_t pid;
+ status_t status = service->getDebugPid(&pid);
+ if (status == OK) {
+ std::ostringstream pidinfo;
+ pidinfo << "Pid: " << pid << std::endl;
+ WriteStringToFd(pidinfo.str(), remote_end.get());
+ } else {
+ aerr << "Error getting pid status_t (" << status << "): "
+ << serviceName << endl;
+ }
+ }
+
+ status_t err = service->dump(remote_end.get(), args);
// It'd be nice to be able to close the remote end of the socketpair before the dump
// call returns, to terminate our reads if the other end closes their copy of the
@@ -335,8 +350,8 @@
// way to do this, though.
remote_end.reset();
- if (err != 0) {
- aerr << "Error dumping service info: (" << strerror(err) << ") "
+ if (err != OK) {
+ aerr << "Error dumping service info status_t (" << err << "): "
<< serviceName << endl;
}
});
diff --git a/cmds/dumpsys/dumpsys.h b/cmds/dumpsys/dumpsys.h
index c48a1e9..8d1291a 100644
--- a/cmds/dumpsys/dumpsys.h
+++ b/cmds/dumpsys/dumpsys.h
@@ -56,12 +56,13 @@
* the output to a pipe. Thread must be stopped by a subsequent callto {@code
* stopDumpThread}.
* @param serviceName
+ * @param dumpPid whether to include a header with service PID information
* @param args list of arguments to pass to service dump method.
* @return {@code OK} thread is started successfully.
* {@code NAME_NOT_FOUND} service could not be found.
* {@code != OK} error
*/
- status_t startDumpThread(const String16& serviceName, const Vector<String16>& args);
+ status_t startDumpThread(const String16& serviceName, bool dumpPid, const Vector<String16>& args);
/**
* Writes a section header to a file descriptor.
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index cbac839..d0b167e 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -188,22 +188,6 @@
EXPECT_THAT(status, Eq(0));
}
- void CallSingleService(const String16& serviceName, Vector<String16>& args, int priorityFlags,
- bool supportsProto, std::chrono::duration<double>& elapsedDuration,
- size_t& bytesWritten) {
- CaptureStdout();
- CaptureStderr();
- dump_.setServiceArgs(args, supportsProto, priorityFlags);
- status_t status = dump_.startDumpThread(serviceName, args);
- EXPECT_THAT(status, Eq(0));
- status = dump_.writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(500), false,
- elapsedDuration, bytesWritten);
- EXPECT_THAT(status, Eq(0));
- dump_.stopDumpThread(/* dumpCompleted = */ true);
- stdout_ = GetCapturedStdout();
- stderr_ = GetCapturedStderr();
- }
-
void AssertRunningServices(const std::vector<std::string>& services) {
std::string expected;
if (services.size() > 1) {
@@ -215,16 +199,13 @@
EXPECT_THAT(stdout_, HasSubstr(expected));
}
- void AssertOutput(const std::string& expected) {
- EXPECT_THAT(stdout_, StrEq(expected));
- }
-
void AssertOutputContains(const std::string& expected) {
EXPECT_THAT(stdout_, HasSubstr(expected));
}
void AssertDumped(const std::string& service, const std::string& dump) {
- EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n" + dump));
+ EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n"));
+ EXPECT_THAT(stdout_, HasSubstr(dump));
EXPECT_THAT(stdout_, HasSubstr("was the duration of dumpsys " + service + ", ending at: "));
}
@@ -232,7 +213,8 @@
const char16_t* priorityType) {
std::string priority = String8(priorityType).c_str();
EXPECT_THAT(stdout_,
- HasSubstr("DUMP OF SERVICE " + priority + " " + service + ":\n" + dump));
+ HasSubstr("DUMP OF SERVICE " + priority + " " + service + ":\n"));
+ EXPECT_THAT(stdout_, HasSubstr(dump));
EXPECT_THAT(stdout_, HasSubstr("was the duration of dumpsys " + service + ", ending at: "));
}
@@ -313,7 +295,8 @@
CallMain({"Valet"});
- AssertOutput("Here's your car");
+ AssertOutputContains("Pid: " + std::to_string(getpid()));
+ AssertOutputContains("Here's your car");
}
// Tests 'dumpsys -t 1 service_name' on a service that times out after 2s
@@ -348,7 +331,7 @@
CallMain({"SERVICE", "Y", "U", "NO", "HANDLE", "ARGS"});
- AssertOutput("I DO!");
+ AssertOutputContains("I DO!");
}
// Tests dumpsys passes the -a flag when called on all services
@@ -539,23 +522,6 @@
AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH);
}
-TEST_F(DumpsysTest, GetBytesWritten) {
- const char* serviceName = "service2";
- const char* dumpContents = "dump1";
- ExpectDump(serviceName, dumpContents);
-
- String16 service(serviceName);
- Vector<String16> args;
- std::chrono::duration<double> elapsedDuration;
- size_t bytesWritten;
-
- CallSingleService(service, args, IServiceManager::DUMP_FLAG_PRIORITY_ALL,
- /* as_proto = */ false, elapsedDuration, bytesWritten);
-
- AssertOutput(dumpContents);
- EXPECT_THAT(bytesWritten, Eq(strlen(dumpContents)));
-}
-
TEST_F(DumpsysTest, WriteDumpWithoutThreadStart) {
std::chrono::duration<double> elapsedDuration;
size_t bytesWritten;
@@ -563,4 +529,4 @@
dump_.writeDump(STDOUT_FILENO, String16("service"), std::chrono::milliseconds(500),
/* as_proto = */ false, elapsedDuration, bytesWritten);
EXPECT_THAT(status, Eq(INVALID_OPERATION));
-}
\ No newline at end of file
+}
diff --git a/include/android/bitmap.h b/include/android/bitmap.h
index 6fba0ac..01cf2f8 100644
--- a/include/android/bitmap.h
+++ b/include/android/bitmap.h
@@ -64,6 +64,20 @@
ANDROID_BITMAP_FORMAT_RGBA_F16 = 9,
};
+/** Bitmap alpha format */
+enum {
+ /** Pixel components are premultiplied by alpha. */
+ ANDROID_BITMAP_FLAGS_ALPHA_PREMUL = 0,
+ /** Pixels are opaque. */
+ ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE = 1,
+ /** Pixel components are independent of alpha. */
+ ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL = 2,
+ /** Bit mask for AndroidBitmapFormat.flags to isolate the alpha. */
+ ANDROID_BITMAP_FLAGS_ALPHA_MASK = 0x3,
+ /** Shift for AndroidBitmapFormat.flags to isolate the alpha. */
+ ANDROID_BITMAP_FLAGS_ALPHA_SHIFT = 0,
+};
+
/** Bitmap info, see AndroidBitmap_getInfo(). */
typedef struct {
/** The bitmap width in pixels. */
@@ -74,8 +88,9 @@
uint32_t stride;
/** The bitmap pixel format. See {@link AndroidBitmapFormat} */
int32_t format;
- /** Unused. */
- uint32_t flags; // 0 for now
+ /** Two bits are used to encode alpha. Use ANDROID_BITMAP_FLAGS_ALPHA_MASK
+ * and ANDROID_BITMAP_FLAGS_ALPHA_SHIFT to retrieve them. */
+ uint32_t flags;
} AndroidBitmapInfo;
/**
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 28b8d80..c056c97 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -35,7 +35,6 @@
#include <binder/IBinder.h>
#include <input/Input.h>
-#include <input/LatencyStatistics.h>
#include <utils/BitSet.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -289,12 +288,8 @@
status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled);
private:
- static constexpr std::chrono::duration TOUCH_STATS_REPORT_PERIOD = 5min;
sp<InputChannel> mChannel;
- LatencyStatistics mTouchStatistics{TOUCH_STATS_REPORT_PERIOD};
-
- void reportTouchEventForStatistics(nsecs_t evdevTime);
};
/*
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 693045e..34b6ea5 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -99,6 +99,32 @@
return reply.readNullableStrongBinder(out);
}
+status_t IBinder::getDebugPid(pid_t* out) {
+ BBinder* local = this->localBinder();
+ if (local != nullptr) {
+ *out = local->getDebugPid();
+ return OK;
+ }
+
+ BpBinder* proxy = this->remoteBinder();
+ LOG_ALWAYS_FATAL_IF(proxy == nullptr);
+
+ Parcel data;
+ Parcel reply;
+ status_t status = transact(DEBUG_PID_TRANSACTION, data, &reply);
+ if (status != OK) return status;
+
+ int32_t pid;
+ status = reply.readInt32(&pid);
+ if (status != OK) return status;
+
+ if (pid < 0 || pid > std::numeric_limits<pid_t>::max()) {
+ return BAD_VALUE;
+ }
+ *out = pid;
+ return OK;
+}
+
// ---------------------------------------------------------------------------
class BBinder::Extras
@@ -152,6 +178,9 @@
case EXTENSION_TRANSACTION:
err = reply->writeStrongBinder(getExtension());
break;
+ case DEBUG_PID_TRANSACTION:
+ err = reply->writeInt32(getDebugPid());
+ break;
default:
err = onTransact(code, data, reply, flags);
break;
@@ -250,6 +279,10 @@
return e->mExtension;
}
+pid_t BBinder::getDebugPid() {
+ return getpid();
+}
+
void BBinder::setExtension(const sp<IBinder>& extension) {
Extras* e = getOrCreateExtras();
e->mExtension = extension;
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 7c45c77..c666097 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -597,9 +597,8 @@
result = getAndExecuteCommand();
if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
- ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
+ LOG_ALWAYS_FATAL("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
mProcess->mDriverFD, result);
- abort();
}
// Let this thread exit the thread pool if it is no longer
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 2a75619..36dc810 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -68,7 +68,7 @@
static size_t pad_size(size_t s) {
if (s > (std::numeric_limits<size_t>::max() - 3)) {
- abort();
+ LOG_ALWAYS_FATAL("pad size too big %zu", s);
}
return PAD_SIZE_UNSAFE(s);
}
@@ -295,7 +295,7 @@
{
size_t result = dataSize() - dataPosition();
if (result > INT32_MAX) {
- abort();
+ LOG_ALWAYS_FATAL("result too big: %zu", result);
}
return result;
}
@@ -332,7 +332,7 @@
if (pos > INT32_MAX) {
// don't accept size_t values which may have come from an
// inadvertent conversion from a negative int.
- abort();
+ LOG_ALWAYS_FATAL("pos too big: %zu", pos);
}
mDataPos = pos;
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index 1095c7f..5673d5a 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -68,6 +68,8 @@
// This must be called before the object is sent to another process. Not thread safe.
void setExtension(const sp<IBinder>& extension);
+ pid_t getDebugPid();
+
protected:
virtual ~BBinder();
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index 027e088..b127234 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -59,6 +59,7 @@
INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'),
EXTENSION_TRANSACTION = B_PACK_CHARS('_', 'E', 'X', 'T'),
+ DEBUG_PID_TRANSACTION = B_PACK_CHARS('_', 'P', 'I', 'D'),
// Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY = 0x00000001
@@ -129,6 +130,11 @@
*/
status_t getExtension(sp<IBinder>* out);
+ /**
+ * Dump PID for a binder, for debugging.
+ */
+ status_t getDebugPid(pid_t* outPid);
+
// NOLINTNEXTLINE(google-default-arguments)
virtual status_t transact( uint32_t code,
const Parcel& data,
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 7749e66..8efaf3d 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -57,7 +57,6 @@
"libutils",
"libbinder",
"libui",
- "libstatslog",
],
sanitize: {
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 8a2fc2a..366c93c 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -34,7 +34,6 @@
#include <utils/Trace.h>
#include <input/InputTransport.h>
-#include <statslog.h>
using android::base::StringPrintf;
@@ -538,9 +537,6 @@
msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
}
- if (source == AINPUT_SOURCE_TOUCHSCREEN) {
- reportTouchEventForStatistics(eventTime);
- }
return mChannel->sendMessage(&msg);
}
@@ -567,17 +563,6 @@
return OK;
}
-void InputPublisher::reportTouchEventForStatistics(nsecs_t evdevTime) {
- if (mTouchStatistics.shouldReport()) {
- android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
- mTouchStatistics.getMax(), mTouchStatistics.getMean(),
- mTouchStatistics.getStDev(), mTouchStatistics.getCount());
- mTouchStatistics.reset();
- }
- nsecs_t latency = nanoseconds_to_microseconds(systemTime(CLOCK_MONOTONIC) - evdevTime);
- mTouchStatistics.addValue(latency);
-}
-
// --- InputConsumer ---
InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
diff --git a/libs/input/LatencyStatistics.cpp b/libs/input/LatencyStatistics.cpp
index e343578..394da22 100644
--- a/libs/input/LatencyStatistics.cpp
+++ b/libs/input/LatencyStatistics.cpp
@@ -84,7 +84,7 @@
bool LatencyStatistics::shouldReport() {
std::chrono::duration timeSinceReport = std::chrono::steady_clock::now() - mLastReportTime;
- return mCount != 0 && timeSinceReport > mReportPeriod;
+ return mCount != 0 && timeSinceReport >= mReportPeriod;
}
} // namespace android
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 11578c3..f6b5935 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -44,6 +44,7 @@
"libhidlbase",
"libinput",
"liblog",
+ "libstatslog",
"libutils",
"libui",
"server_configurable_flags",
diff --git a/services/inputflinger/InputReaderBase.cpp b/services/inputflinger/InputReaderBase.cpp
index bc53cf5..0422d83 100644
--- a/services/inputflinger/InputReaderBase.cpp
+++ b/services/inputflinger/InputReaderBase.cpp
@@ -114,8 +114,10 @@
std::optional<DisplayViewport> result = std::nullopt;
for (const DisplayViewport& currentViewport : mDisplays) {
// Return the first match
- if (currentViewport.type == type && !result) {
- result = std::make_optional(currentViewport);
+ if (currentViewport.type == type) {
+ if (!result) {
+ result = std::make_optional(currentViewport);
+ }
count++;
}
}
diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp
index b8c3a80..9185e00 100644
--- a/services/inputflinger/dispatcher/Android.bp
+++ b/services/inputflinger/dispatcher/Android.bp
@@ -34,6 +34,7 @@
"libinputreporter",
"libinputflinger_base",
"liblog",
+ "libstatslog",
"libui",
"libutils",
],
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index a9e22f1..28c2799 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -29,6 +29,9 @@
namespace android::inputdispatcher {
+// Sequence number for synthesized or injected events.
+constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
+
struct EventEntry {
enum { TYPE_CONFIGURATION_CHANGED, TYPE_DEVICE_RESET, TYPE_KEY, TYPE_MOTION };
@@ -41,8 +44,23 @@
bool dispatchInProgress; // initially false, set to true while dispatching
+ /**
+ * Injected keys are events from an external (probably untrusted) application
+ * and are not related to real hardware state. They come in via
+ * InputDispatcher::injectInputEvent, which sets policy flag POLICY_FLAG_INJECTED.
+ */
inline bool isInjected() const { return injectionState != nullptr; }
+ /**
+ * Synthesized events are either injected events, or events that come
+ * from real hardware, but aren't directly attributable to a specific hardware event.
+ * Key repeat is a synthesized event, because it is related to an actual hardware state
+ * (a key is currently pressed), but the repeat itself is generated by the framework.
+ */
+ inline bool isSynthesized() const {
+ return isInjected() || sequenceNum == SYNTHESIZED_EVENT_SEQUENCE_NUM;
+ }
+
void release();
virtual void appendDescription(std::string& msg) const = 0;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index e161e8c..aa51e23 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -50,6 +50,7 @@
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
+#include <statslog.h>
#include <stddef.h>
#include <time.h>
#include <unistd.h>
@@ -2276,6 +2277,7 @@
motionEntry->downTime, motionEntry->eventTime,
motionEntry->pointerCount,
motionEntry->pointerProperties, usingCoords);
+ reportTouchEventForStatistics(*motionEntry);
break;
}
@@ -4481,6 +4483,34 @@
// TODO Write some statistics about how long we spend waiting.
}
+/**
+ * Report the touch event latency to the statsd server.
+ * Input events are reported for statistics if:
+ * - This is a touchscreen event
+ * - InputFilter is not enabled
+ * - Event is not injected or synthesized
+ *
+ * Statistics should be reported before calling addValue, to prevent a fresh new sample
+ * from getting aggregated with the "old" data.
+ */
+void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
+ REQUIRES(mLock) {
+ const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
+ !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
+ if (!reportForStatistics) {
+ return;
+ }
+
+ if (mTouchStatistics.shouldReport()) {
+ android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
+ mTouchStatistics.getMax(), mTouchStatistics.getMean(),
+ mTouchStatistics.getStDev(), mTouchStatistics.getCount());
+ mTouchStatistics.reset();
+ }
+ const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
+ mTouchStatistics.addValue(latencyMicros);
+}
+
void InputDispatcher::traceInboundQueueLengthLocked() {
if (ATRACE_ENABLED()) {
ATRACE_INT("iq", mInboundQueue.size());
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index f2c0402..0d9d6b0 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -33,6 +33,7 @@
#include <input/InputApplication.h>
#include <input/InputTransport.h>
#include <input/InputWindow.h>
+#include <input/LatencyStatistics.h>
#include <limits.h>
#include <stddef.h>
#include <ui/Region.h>
@@ -455,6 +456,10 @@
void doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
// Statistics gathering.
+ static constexpr std::chrono::duration TOUCH_STATS_REPORT_PERIOD = 5min;
+ LatencyStatistics mTouchStatistics{TOUCH_STATS_REPORT_PERIOD};
+
+ void reportTouchEventForStatistics(const MotionEntry& entry);
void updateDispatchStatistics(nsecs_t currentTime, const EventEntry* entry,
int32_t injectionResult, nsecs_t timeSpentWaitingForApplication);
void traceInboundQueueLengthLocked() REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/InputState.h b/services/inputflinger/dispatcher/InputState.h
index bccef0f..47e9b36 100644
--- a/services/inputflinger/dispatcher/InputState.h
+++ b/services/inputflinger/dispatcher/InputState.h
@@ -24,9 +24,6 @@
namespace android::inputdispatcher {
-// Sequence number for synthesized or injected events.
-constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;
-
/* Tracks dispatched key and motion event state so that cancellation events can be
* synthesized when events are dropped. */
class InputState {
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index fcb94fd..1407ef7 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -3,6 +3,7 @@
defaults: ["surfaceflinger_defaults"],
cflags: [
"-DLOG_TAG=\"CompositionEngine\"",
+ "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
],
shared_libs: [
"android.frameworks.vr.composer@2.0",
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
index a8e05cb..9898e35 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
@@ -46,8 +46,8 @@
virtual ~CompositionEngine();
// Create a composition Display
- virtual std::shared_ptr<Display> createDisplay(DisplayCreationArgs&&) = 0;
- virtual std::shared_ptr<Layer> createLayer(LayerCreationArgs&&) = 0;
+ virtual std::shared_ptr<Display> createDisplay(const DisplayCreationArgs&) = 0;
+ virtual std::shared_ptr<Layer> createLayer(const LayerCreationArgs&) = 0;
virtual HWComposer& getHwComposer() const = 0;
virtual void setHwComposer(std::unique_ptr<HWComposer>) = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
index dbcd3bd..9193dc0 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
@@ -47,10 +47,10 @@
virtual void disconnect() = 0;
// Creates a render color mode for the display
- virtual void createDisplayColorProfile(DisplayColorProfileCreationArgs&&) = 0;
+ virtual void createDisplayColorProfile(const DisplayColorProfileCreationArgs&) = 0;
// Creates a render surface for the display
- virtual void createRenderSurface(RenderSurfaceCreationArgs&&) = 0;
+ virtual void createRenderSurface(const RenderSurfaceCreationArgs&) = 0;
protected:
~Display() = default;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 0778936..ced4227 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
@@ -30,9 +30,6 @@
* A parameter object for creating Display instances
*/
struct DisplayCreationArgs {
- // True if this display is secure
- bool isSecure = false;
-
// True if this display is a virtual display
bool isVirtual = false;
@@ -54,17 +51,13 @@
*
* Prefer:
*
- * DisplayCreationArgsBuilder().setIsSecure(false).setIsVirtual(false)
+ * DisplayCreationArgsBuilder().setIsVirtual(false)
* .setDisplayId(displayId).build();
*/
class DisplayCreationArgsBuilder {
public:
DisplayCreationArgs build() { return std::move(mArgs); }
- DisplayCreationArgsBuilder& setIsSecure(bool isSecure) {
- mArgs.isSecure = isSecure;
- return *this;
- }
DisplayCreationArgsBuilder& setIsVirtual(bool isVirtual) {
mArgs.isVirtual = isVirtual;
return *this;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index d374baa..3830b07 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -162,12 +162,6 @@
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::shared_ptr<Layer>,
- sp<LayerFE>) = 0;
-
// Sets the new ordered set of output layers for this output
virtual void setOutputLayersOrderedByZ(OutputLayers&&) = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
index 6859846..5ce2fdc 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
@@ -78,7 +78,7 @@
// Queues the drawn buffer for consumption by HWC. readyFence is the fence
// which will fire when the buffer is ready for consumption.
- virtual void queueBuffer(base::unique_fd&& readyFence) = 0;
+ virtual void queueBuffer(base::unique_fd readyFence) = 0;
// Called after the HWC calls are made to present the display
virtual void onPresentDisplayCompleted() = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
index 6340b14..76798f1 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
@@ -26,9 +26,9 @@
~CompositionEngine() override;
std::shared_ptr<compositionengine::Display> createDisplay(
- compositionengine::DisplayCreationArgs&&) override;
+ const compositionengine::DisplayCreationArgs&) override;
std::shared_ptr<compositionengine::Layer> createLayer(
- compositionengine::LayerCreationArgs&&) override;
+ const compositionengine::LayerCreationArgs&) override;
HWComposer& getHwComposer() const override;
void setHwComposer(std::unique_ptr<HWComposer>) override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index b5d8325..45a604f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -17,6 +17,7 @@
#pragma once
#include <compositionengine/Display.h>
+#include <compositionengine/DisplayCreationArgs.h>
#include <compositionengine/impl/Output.h>
#include <memory>
@@ -29,36 +30,37 @@
class CompositionEngine;
-struct DisplayCreationArgs;
-
namespace impl {
-class Display : public compositionengine::impl::Output, public compositionengine::Display {
+// The implementation class contains the common implementation, but does not
+// actually contain the final display state.
+class Display : public compositionengine::impl::Output, public virtual compositionengine::Display {
public:
- Display(const CompositionEngine&, compositionengine::DisplayCreationArgs&&);
+ explicit Display(const compositionengine::DisplayCreationArgs&);
virtual ~Display();
// 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;
+ const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&) const override;
using compositionengine::impl::Output::setReleasedLayers;
- void setReleasedLayers(const compositionengine::CompositionRefreshArgs&) override;
- void setColorTransform(const compositionengine::CompositionRefreshArgs&) override;
+ void setReleasedLayers(const CompositionRefreshArgs&) override;
+ void setColorTransform(const CompositionRefreshArgs&) override;
void setColorProfile(const ColorProfile&) override;
void chooseCompositionStrategy() override;
bool getSkipColorTransform() const override;
compositionengine::Output::FrameFences presentAndGetFrameFences() override;
void setExpensiveRenderingExpected(bool) override;
- void finishFrame(const compositionengine::CompositionRefreshArgs&) override;
+ void finishFrame(const CompositionRefreshArgs&) override;
// compositionengine::Display overrides
const std::optional<DisplayId>& getId() const override;
bool isSecure() const override;
bool isVirtual() const override;
void disconnect() override;
- void createDisplayColorProfile(compositionengine::DisplayColorProfileCreationArgs&&) override;
- void createRenderSurface(compositionengine::RenderSurfaceCreationArgs&&) override;
+ void createDisplayColorProfile(
+ const compositionengine::DisplayColorProfileCreationArgs&) override;
+ void createRenderSurface(const compositionengine::RenderSurfaceCreationArgs&) override;
// Internal helpers used by chooseCompositionStrategy()
using ChangedTypes = android::HWComposer::DeviceRequestedChanges::ChangedTypes;
@@ -76,8 +78,18 @@
Hwc2::PowerAdvisor* const mPowerAdvisor{nullptr};
};
+// This template factory function standardizes the implementation details of the
+// final class using the types actually required by the implementation. This is
+// not possible to do in the base class as those types may not even be visible
+// to the base code.
+template <typename BaseDisplay, typename CompositionEngine, typename DisplayCreationArgs>
+std::shared_ptr<BaseDisplay> createDisplayTemplated(const CompositionEngine& compositionEngine,
+ const DisplayCreationArgs& args) {
+ return createOutputTemplated<BaseDisplay>(compositionEngine, args);
+}
+
std::shared_ptr<Display> createDisplay(const compositionengine::CompositionEngine&,
- compositionengine::DisplayCreationArgs&&);
+ const compositionengine::DisplayCreationArgs&);
} // namespace impl
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DisplayColorProfile.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DisplayColorProfile.h
index e84a36e..9bc0e68 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DisplayColorProfile.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DisplayColorProfile.h
@@ -33,7 +33,7 @@
class DisplayColorProfile : public compositionengine::DisplayColorProfile {
public:
- DisplayColorProfile(DisplayColorProfileCreationArgs&&);
+ DisplayColorProfile(const DisplayColorProfileCreationArgs&);
~DisplayColorProfile() override;
bool isValid() const override;
@@ -91,7 +91,7 @@
};
std::unique_ptr<compositionengine::DisplayColorProfile> createDisplayColorProfile(
- DisplayColorProfileCreationArgs&&);
+ const DisplayColorProfileCreationArgs&);
} // namespace impl
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h
index d441c9c..46489fb 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h
@@ -19,43 +19,66 @@
#include <memory>
#include <compositionengine/Layer.h>
-#include <compositionengine/LayerFECompositionState.h>
-#include <utils/RefBase.h>
+#include <compositionengine/LayerCreationArgs.h>
#include <utils/StrongPointer.h>
namespace android::compositionengine {
-class CompositionEngine;
-class LayerFE;
-
struct LayerCreationArgs;
namespace impl {
-class Display;
-
-class Layer : public compositionengine::Layer {
+// The implementation class contains the common implementation, but does not
+// actually contain the final layer state.
+class Layer : public virtual compositionengine::Layer {
public:
- Layer(const CompositionEngine&, compositionengine::LayerCreationArgs&&);
~Layer() override;
- sp<LayerFE> getLayerFE() const override;
+ // compositionengine::Layer overrides
+ void dump(std::string&) const override;
- const LayerFECompositionState& getFEState() const override;
- LayerFECompositionState& editFEState() override;
-
- void dump(std::string& result) const override;
-
-private:
- const compositionengine::CompositionEngine& mCompositionEngine;
- const wp<LayerFE> mLayerFE;
-
- // State obtained from calls to LayerFE::getCompositionState
- LayerFECompositionState mFrontEndState;
+protected:
+ // Implemented by the final implementation for the final state it uses.
+ virtual void dumpFEState(std::string&) const = 0;
};
-std::shared_ptr<compositionengine::Layer> createLayer(const compositionengine::CompositionEngine&,
- compositionengine::LayerCreationArgs&&);
+// This template factory function standardizes the implementation details of the
+// final class using the types actually required by the implementation. This is
+// not possible to do in the base class as those types may not even be visible
+// to the base code.
+template <typename BaseLayer, typename LayerCreationArgs>
+std::shared_ptr<BaseLayer> createLayerTemplated(const LayerCreationArgs& args) {
+ class Layer final : public BaseLayer {
+ public:
+// Clang incorrectly complains that these are unused.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-local-typedef"
+ using LayerFE = std::remove_pointer_t<decltype(
+ std::declval<decltype(std::declval<LayerCreationArgs>().layerFE)>().unsafe_get())>;
+ using LayerFECompositionState = std::remove_const_t<
+ std::remove_reference_t<decltype(std::declval<BaseLayer>().getFEState())>>;
+#pragma clang diagnostic pop
+
+ explicit Layer(const LayerCreationArgs& args) : mLayerFE(args.layerFE) {}
+ ~Layer() override = default;
+
+ private:
+ // compositionengine::Layer overrides
+ sp<compositionengine::LayerFE> getLayerFE() const override { return mLayerFE.promote(); }
+ const LayerFECompositionState& getFEState() const override { return mFrontEndState; }
+ LayerFECompositionState& editFEState() override { return mFrontEndState; }
+
+ // compositionengine::impl::Layer overrides
+ void dumpFEState(std::string& out) const override { mFrontEndState.dump(out); }
+
+ const wp<LayerFE> mLayerFE;
+ LayerFECompositionState mFrontEndState;
+ };
+
+ return std::make_shared<Layer>(args);
+}
+
+std::shared_ptr<Layer> createLayer(const LayerCreationArgs&);
} // namespace impl
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index fa6cd27..2766572 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -16,28 +16,24 @@
#pragma once
+#include <compositionengine/CompositionEngine.h>
+#include <compositionengine/Output.h>
+#include <compositionengine/impl/OutputCompositionState.h>
+
#include <memory>
#include <utility>
#include <vector>
-#include <compositionengine/Output.h>
-#include <compositionengine/impl/OutputCompositionState.h>
+namespace android::compositionengine::impl {
-namespace android::compositionengine {
-
-class CompositionEngine;
-class Layer;
-class OutputLayer;
-
-namespace impl {
-
+// The implementation class contains the common implementation, but does not
+// actually contain the final output state.
class Output : public virtual compositionengine::Output {
public:
- Output(const CompositionEngine&);
~Output() override;
+ // compositionengine::Output overrides
bool isValid() const override;
-
void setCompositionEnabled(bool) override;
void setProjection(const ui::Transform&, int32_t orientation, const Rect& frame,
const Rect& viewport, const Rect& scissor, bool needsFiltering) override;
@@ -58,9 +54,6 @@
compositionengine::RenderSurface* getRenderSurface() const override;
void setRenderSurface(std::unique_ptr<compositionengine::RenderSurface>) override;
- const OutputCompositionState& getState() const override;
- OutputCompositionState& editState() override;
-
Region getDirtyRegion(bool repaintEverything) const override;
bool belongsInOutput(std::optional<uint32_t>, bool) const override;
bool belongsInOutput(const compositionengine::Layer*) const override;
@@ -69,19 +62,17 @@
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::shared_ptr<compositionengine::Layer>, sp<LayerFE>) override;
void setOutputLayersOrderedByZ(OutputLayers&&) override;
const OutputLayers& getOutputLayersOrderedByZ() const override;
void setReleasedLayers(ReleasedLayers&&) override;
ReleasedLayers takeReleasedLayers() override;
- void prepare(const compositionengine::CompositionRefreshArgs&, LayerFESet&) override;
- void present(const compositionengine::CompositionRefreshArgs&) override;
+ void prepare(const CompositionRefreshArgs&, LayerFESet&) override;
+ void present(const CompositionRefreshArgs&) override;
- void rebuildLayerStacks(const compositionengine::CompositionRefreshArgs&, LayerFESet&) override;
- void collectVisibleLayers(const compositionengine::CompositionRefreshArgs&,
+ void rebuildLayerStacks(const CompositionRefreshArgs&, LayerFESet&) override;
+ void collectVisibleLayers(const CompositionRefreshArgs&,
compositionengine::Output::CoverageState&) override;
std::unique_ptr<compositionengine::OutputLayer> getOutputLayerIfVisible(
std::shared_ptr<compositionengine::Layer>,
@@ -93,8 +84,8 @@
void updateColorProfile(const compositionengine::CompositionRefreshArgs&) override;
void beginFrame() override;
void prepareFrame() override;
- void devOptRepaintFlash(const compositionengine::CompositionRefreshArgs&) override;
- void finishFrame(const compositionengine::CompositionRefreshArgs&) override;
+ void devOptRepaintFlash(const CompositionRefreshArgs&) override;
+ void finishFrame(const CompositionRefreshArgs&) override;
std::optional<base::unique_fd> composeSurfaces(const Region&) override;
void postFramebuffer() override;
@@ -104,7 +95,7 @@
void setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface>);
protected:
- const CompositionEngine& getCompositionEngine() const;
+ virtual const CompositionEngine& getCompositionEngine() const = 0;
std::unique_ptr<compositionengine::OutputLayer> takeOutputLayerForLayer(
compositionengine::Layer*);
void chooseCompositionStrategy() override;
@@ -117,18 +108,17 @@
void setExpensiveRenderingExpected(bool enabled) override;
void dumpBase(std::string&) const;
+ // Implemented by the final implementation for the final state it uses.
+ virtual void dumpState(std::string&) const = 0;
+
private:
void dirtyEntireOutput();
ui::Dataspace getBestDataspace(ui::Dataspace*, bool*) const;
compositionengine::Output::ColorProfile pickColorProfile(
const compositionengine::CompositionRefreshArgs&) const;
- const CompositionEngine& mCompositionEngine;
-
std::string mName;
- OutputCompositionState mState;
-
std::unique_ptr<compositionengine::DisplayColorProfile> mDisplayColorProfile;
std::unique_ptr<compositionengine::RenderSurface> mRenderSurface;
@@ -136,5 +126,46 @@
ReleasedLayers mReleasedLayers;
};
-} // namespace impl
-} // namespace android::compositionengine
+// This template factory function standardizes the implementation details of the
+// final class using the types actually required by the implementation. This is
+// not possible to do in the base class as those types may not even be visible
+// to the base code.
+template <typename BaseOutput, typename CompositionEngine, typename... Args>
+std::shared_ptr<BaseOutput> createOutputTemplated(const CompositionEngine& compositionEngine,
+ Args... args) {
+ class Output final : public BaseOutput {
+ public:
+// Clang incorrectly complains that these are unused.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-local-typedef"
+
+ using OutputCompositionState = std::remove_const_t<
+ std::remove_reference_t<decltype(std::declval<BaseOutput>().getState())>>;
+
+#pragma clang diagnostic pop
+
+ explicit Output(const CompositionEngine& compositionEngine, Args... args)
+ : BaseOutput(std::forward<Args>(args)...), mCompositionEngine(compositionEngine) {}
+ ~Output() override = default;
+
+ private:
+ // compositionengine::Output overrides
+ const OutputCompositionState& getState() const override { return mState; }
+ OutputCompositionState& editState() override { return mState; }
+
+ // compositionengine::impl::Output overrides
+ const CompositionEngine& getCompositionEngine() const override {
+ return mCompositionEngine;
+ };
+ void dumpState(std::string& out) const override { mState.dump(out); }
+
+ const CompositionEngine& mCompositionEngine;
+ OutputCompositionState mState;
+ };
+
+ return std::make_shared<Output>(compositionEngine, std::forward<Args>(args)...);
+}
+
+std::shared_ptr<Output> createOutput(const compositionengine::CompositionEngine&);
+
+} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
index 1199fea..34dbfb7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
@@ -20,7 +20,6 @@
#include <string>
#include <compositionengine/OutputLayer.h>
-#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <ui/FloatRect.h>
#include <ui/Rect.h>
@@ -32,21 +31,14 @@
namespace impl {
-class OutputLayer : public compositionengine::OutputLayer {
+// The implementation class contains the common implementation, but does not
+// actually contain the final layer state.
+class OutputLayer : public virtual compositionengine::OutputLayer {
public:
- OutputLayer(const compositionengine::Output&, const std::shared_ptr<compositionengine::Layer>&,
- const sp<compositionengine::LayerFE>&);
~OutputLayer() override;
void setHwcLayer(std::shared_ptr<HWC2::Layer>) override;
- const compositionengine::Output& getOutput() const override;
- compositionengine::Layer& getLayer() const override;
- compositionengine::LayerFE& getLayerFE() const override;
-
- const OutputLayerCompositionState& getState() const override;
- OutputLayerCompositionState& editState() override;
-
void updateCompositionState(bool) override;
void writeStateToHWC(bool) override;
void writeCursorPositionToHWC() const override;
@@ -59,12 +51,16 @@
void applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest request) override;
bool needsFiltering() const override;
- void dump(std::string& result) const override;
+ void dump(std::string&) const override;
virtual FloatRect calculateOutputSourceCrop() const;
virtual Rect calculateOutputDisplayFrame() const;
virtual uint32_t calculateOutputRelativeBufferTransform() const;
+protected:
+ // Implemented by the final implementation for the final state it uses.
+ virtual void dumpState(std::string&) const = 0;
+
private:
Rect calculateInitialCrop() const;
void writeOutputDependentGeometryStateToHWC(HWC2::Layer*, Hwc2::IComposerClient::Composition);
@@ -77,17 +73,60 @@
void writeCompositionTypeToHWC(HWC2::Layer*, Hwc2::IComposerClient::Composition);
void detectDisallowedCompositionTypeChange(Hwc2::IComposerClient::Composition from,
Hwc2::IComposerClient::Composition to) const;
-
- const compositionengine::Output& mOutput;
- std::shared_ptr<compositionengine::Layer> mLayer;
- sp<compositionengine::LayerFE> mLayerFE;
-
- OutputLayerCompositionState mState;
};
-std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
- const compositionengine::Output&, const std::shared_ptr<compositionengine::Layer>&,
- const sp<compositionengine::LayerFE>&);
+// This template factory function standardizes the implementation details of the
+// final class using the types actually required by the implementation. This is
+// not possible to do in the base class as those types may not even be visible
+// to the base code.
+template <typename BaseOutputLayer>
+std::unique_ptr<BaseOutputLayer> createOutputLayerTemplated(const Output& output,
+ std::shared_ptr<Layer> layer,
+ sp<LayerFE> layerFE) {
+ class OutputLayer final : public BaseOutputLayer {
+ public:
+// Clang incorrectly complains that these are unused.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-local-typedef"
+
+ using OutputLayerCompositionState = std::remove_const_t<
+ std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getState())>>;
+ using Output = std::remove_const_t<
+ std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getOutput())>>;
+ using Layer = std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getLayer())>;
+ using LayerFE =
+ std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getLayerFE())>;
+
+#pragma clang diagnostic pop
+
+ OutputLayer(const Output& output, const std::shared_ptr<Layer>& layer,
+ const sp<LayerFE>& layerFE)
+ : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
+ ~OutputLayer() override = default;
+
+ private:
+ // compositionengine::OutputLayer overrides
+ const Output& getOutput() const override { return mOutput; }
+ Layer& getLayer() const override { return *mLayer; }
+ LayerFE& getLayerFE() const override { return *mLayerFE; }
+ const OutputLayerCompositionState& getState() const override { return mState; }
+ OutputLayerCompositionState& editState() override { return mState; }
+
+ // compositionengine::impl::OutputLayer overrides
+ void dumpState(std::string& out) const override { mState.dump(out); }
+
+ const Output& mOutput;
+ const std::shared_ptr<Layer> mLayer;
+ const sp<LayerFE> mLayerFE;
+ OutputLayerCompositionState mState;
+ };
+
+ return std::make_unique<OutputLayer>(output, layer, layerFE);
+}
+
+std::unique_ptr<OutputLayer> createOutputLayer(const compositionengine::Output&,
+ const std::shared_ptr<compositionengine::Layer>&,
+ const sp<LayerFE>&);
} // namespace impl
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
index 0a04462..692d78d 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
@@ -39,7 +39,7 @@
class RenderSurface : public compositionengine::RenderSurface {
public:
RenderSurface(const CompositionEngine&, compositionengine::Display&,
- compositionengine::RenderSurfaceCreationArgs&&);
+ const compositionengine::RenderSurfaceCreationArgs&);
~RenderSurface() override;
bool isValid() const override;
@@ -54,7 +54,7 @@
status_t beginFrame(bool mustRecompose) override;
void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) override;
sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) override;
- void queueBuffer(base::unique_fd&& readyFence) override;
+ void queueBuffer(base::unique_fd readyFence) override;
void onPresentDisplayCompleted() override;
void flip() override;
@@ -84,7 +84,7 @@
std::unique_ptr<compositionengine::RenderSurface> createRenderSurface(
const compositionengine::CompositionEngine&, compositionengine::Display&,
- compositionengine::RenderSurfaceCreationArgs&&);
+ const compositionengine::RenderSurfaceCreationArgs&);
} // namespace impl
} // namespace compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
index e3254ac..af7efdd 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
@@ -32,8 +32,8 @@
CompositionEngine();
~CompositionEngine() override;
- MOCK_METHOD1(createDisplay, std::shared_ptr<Display>(DisplayCreationArgs&&));
- MOCK_METHOD1(createLayer, std::shared_ptr<Layer>(LayerCreationArgs&&));
+ MOCK_METHOD1(createDisplay, std::shared_ptr<Display>(const DisplayCreationArgs&));
+ MOCK_METHOD1(createLayer, std::shared_ptr<Layer>(const LayerCreationArgs&));
MOCK_CONST_METHOD0(getHwComposer, HWComposer&());
MOCK_METHOD1(setHwComposer, void(std::unique_ptr<HWComposer>));
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
index d763aa6..57f33ae 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
@@ -38,8 +38,8 @@
MOCK_METHOD0(disconnect, void());
- MOCK_METHOD1(createDisplayColorProfile, void(DisplayColorProfileCreationArgs&&));
- MOCK_METHOD1(createRenderSurface, void(RenderSurfaceCreationArgs&&));
+ MOCK_METHOD1(createDisplayColorProfile, void(const DisplayColorProfileCreationArgs&));
+ MOCK_METHOD1(createRenderSurface, void(const RenderSurfaceCreationArgs&));
};
} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
index ba6746a..ed4d492 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
@@ -39,7 +39,7 @@
MOCK_METHOD1(beginFrame, status_t(bool mustRecompose));
MOCK_METHOD2(prepareFrame, void(bool, bool));
MOCK_METHOD1(dequeueBuffer, sp<GraphicBuffer>(base::unique_fd*));
- MOCK_METHOD1(queueBuffer, void(base::unique_fd&&));
+ MOCK_METHOD1(queueBuffer, void(base::unique_fd));
MOCK_METHOD0(onPresentDisplayCompleted, void());
MOCK_METHOD0(flip, void());
MOCK_CONST_METHOD1(dump, void(std::string& result));
diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
index 8391458..abf73ad 100644
--- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -39,12 +39,13 @@
CompositionEngine::~CompositionEngine() = default;
std::shared_ptr<compositionengine::Display> CompositionEngine::createDisplay(
- DisplayCreationArgs&& args) {
- return compositionengine::impl::createDisplay(*this, std::move(args));
+ const DisplayCreationArgs& args) {
+ return compositionengine::impl::createDisplay(*this, args);
}
-std::shared_ptr<compositionengine::Layer> CompositionEngine::createLayer(LayerCreationArgs&& args) {
- return compositionengine::impl::createLayer(*this, std::move(args));
+std::shared_ptr<compositionengine::Layer> CompositionEngine::createLayer(
+ const LayerCreationArgs& args) {
+ return compositionengine::impl::createLayer(args);
}
HWComposer& CompositionEngine::getHwComposer() const {
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index fe8fa21..87df858 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -34,17 +34,12 @@
std::shared_ptr<Display> createDisplay(
const compositionengine::CompositionEngine& compositionEngine,
- compositionengine::DisplayCreationArgs&& args) {
- return std::make_shared<Display>(compositionEngine, std::move(args));
+ const compositionengine::DisplayCreationArgs& args) {
+ return createDisplayTemplated<Display>(compositionEngine, args);
}
-Display::Display(const CompositionEngine& compositionEngine, DisplayCreationArgs&& args)
- : compositionengine::impl::Output(compositionEngine),
- mIsVirtual(args.isVirtual),
- mId(args.displayId),
- mPowerAdvisor(args.powerAdvisor) {
- editState().isSecure = args.isSecure;
-}
+Display::Display(const DisplayCreationArgs& args)
+ : mIsVirtual(args.isVirtual), mId(args.displayId), mPowerAdvisor(args.powerAdvisor) {}
Display::~Display() = default;
@@ -125,13 +120,13 @@
Output::dumpBase(out);
}
-void Display::createDisplayColorProfile(DisplayColorProfileCreationArgs&& args) {
- setDisplayColorProfile(compositionengine::impl::createDisplayColorProfile(std::move(args)));
+void Display::createDisplayColorProfile(const DisplayColorProfileCreationArgs& args) {
+ setDisplayColorProfile(compositionengine::impl::createDisplayColorProfile(args));
}
-void Display::createRenderSurface(RenderSurfaceCreationArgs&& args) {
- setRenderSurface(compositionengine::impl::createRenderSurface(getCompositionEngine(), *this,
- std::move(args)));
+void Display::createRenderSurface(const RenderSurfaceCreationArgs& args) {
+ setRenderSurface(
+ compositionengine::impl::createRenderSurface(getCompositionEngine(), *this, args));
}
std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
diff --git a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
index 5ef9097..a7c4512 100644
--- a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
@@ -184,11 +184,11 @@
} // anonymous namespace
std::unique_ptr<compositionengine::DisplayColorProfile> createDisplayColorProfile(
- DisplayColorProfileCreationArgs&& args) {
- return std::make_unique<DisplayColorProfile>(std::move(args));
+ const DisplayColorProfileCreationArgs& args) {
+ return std::make_unique<DisplayColorProfile>(args);
}
-DisplayColorProfile::DisplayColorProfile(DisplayColorProfileCreationArgs&& args)
+DisplayColorProfile::DisplayColorProfile(const DisplayColorProfileCreationArgs& args)
: mHasWideColorGamut(args.hasWideColorGamut),
mSupportedPerFrameMetadata(args.supportedPerFrameMetadata) {
populateColorModes(args.hwcColorModes);
diff --git a/services/surfaceflinger/CompositionEngine/src/Layer.cpp b/services/surfaceflinger/CompositionEngine/src/Layer.cpp
index 8a1cbe4..ecacaee 100644
--- a/services/surfaceflinger/CompositionEngine/src/Layer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Layer.cpp
@@ -15,9 +15,8 @@
*/
#include <android-base/stringprintf.h>
-#include <compositionengine/CompositionEngine.h>
-#include <compositionengine/LayerCreationArgs.h>
#include <compositionengine/LayerFE.h>
+#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/impl/Layer.h>
namespace android::compositionengine {
@@ -26,38 +25,18 @@
namespace impl {
-std::shared_ptr<compositionengine::Layer> createLayer(
- const compositionengine::CompositionEngine& compositionEngine,
- compositionengine::LayerCreationArgs&& args) {
- return std::make_shared<Layer>(compositionEngine, std::move(args));
-}
-
-Layer::Layer(const CompositionEngine& compositionEngine, LayerCreationArgs&& args)
- : mCompositionEngine(compositionEngine), mLayerFE(args.layerFE) {
- static_cast<void>(mCompositionEngine); // Temporary use to prevent an unused warning
+std::shared_ptr<Layer> createLayer(const LayerCreationArgs& args) {
+ return compositionengine::impl::createLayerTemplated<Layer>(args);
}
Layer::~Layer() = default;
-sp<LayerFE> Layer::getLayerFE() const {
- return mLayerFE.promote();
-}
-
-const compositionengine::LayerFECompositionState& Layer::getFEState() const {
- return mFrontEndState;
-}
-
-compositionengine::LayerFECompositionState& Layer::editFEState() {
- return mFrontEndState;
-}
-
void Layer::dump(std::string& out) const {
auto layerFE = getLayerFE();
android::base::StringAppendF(&out, "* compositionengine::Layer %p (%s)\n", this,
layerFE ? layerFE->getDebugName() : "<unknown>");
-
out.append(" frontend:\n");
- mFrontEndState.dump(out);
+ dumpFEState(out);
}
} // namespace impl
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 02ebc1f..c511306 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -25,7 +25,9 @@
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/RenderSurface.h>
#include <compositionengine/impl/Output.h>
+#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <renderengine/DisplaySettings.h>
#include <renderengine/RenderEngine.h>
#include <ui/DebugUtils.h>
@@ -61,15 +63,13 @@
} // namespace
-Output::Output(const CompositionEngine& compositionEngine)
- : mCompositionEngine(compositionEngine) {}
+std::shared_ptr<Output> createOutput(
+ const compositionengine::CompositionEngine& compositionEngine) {
+ return createOutputTemplated<Output>(compositionEngine);
+}
Output::~Output() = default;
-const CompositionEngine& Output::getCompositionEngine() const {
- return mCompositionEngine;
-}
-
bool Output::isValid() const {
return mDisplayColorProfile && mDisplayColorProfile->isValid() && mRenderSurface &&
mRenderSurface->isValid();
@@ -84,22 +84,24 @@
}
void Output::setCompositionEnabled(bool enabled) {
- if (mState.isEnabled == enabled) {
+ auto& outputState = editState();
+ if (outputState.isEnabled == enabled) {
return;
}
- mState.isEnabled = enabled;
+ outputState.isEnabled = enabled;
dirtyEntireOutput();
}
void Output::setProjection(const ui::Transform& transform, int32_t orientation, const Rect& frame,
const Rect& viewport, const Rect& scissor, bool needsFiltering) {
- mState.transform = transform;
- mState.orientation = orientation;
- mState.scissor = scissor;
- mState.frame = frame;
- mState.viewport = viewport;
- mState.needsFiltering = needsFiltering;
+ auto& outputState = editState();
+ outputState.transform = transform;
+ outputState.orientation = orientation;
+ outputState.scissor = scissor;
+ outputState.frame = frame;
+ outputState.viewport = viewport;
+ outputState.needsFiltering = needsFiltering;
dirtyEntireOutput();
}
@@ -107,44 +109,48 @@
// TODO(b/121291683): Rename setSize() once more is moved.
void Output::setBounds(const ui::Size& size) {
mRenderSurface->setDisplaySize(size);
- // TODO(b/121291683): Rename mState.size once more is moved.
- mState.bounds = Rect(mRenderSurface->getSize());
+ // TODO(b/121291683): Rename outputState.size once more is moved.
+ editState().bounds = Rect(mRenderSurface->getSize());
dirtyEntireOutput();
}
void Output::setLayerStackFilter(uint32_t layerStackId, bool isInternal) {
- mState.layerStackId = layerStackId;
- mState.layerStackInternal = isInternal;
+ auto& outputState = editState();
+ outputState.layerStackId = layerStackId;
+ outputState.layerStackInternal = isInternal;
dirtyEntireOutput();
}
void Output::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
- if (!args.colorTransformMatrix || mState.colorTransformMatrix == *args.colorTransformMatrix) {
+ auto& colorTransformMatrix = editState().colorTransformMatrix;
+ if (!args.colorTransformMatrix || colorTransformMatrix == args.colorTransformMatrix) {
return;
}
- mState.colorTransformMatrix = *args.colorTransformMatrix;
+ colorTransformMatrix = *args.colorTransformMatrix;
dirtyEntireOutput();
}
void Output::setColorProfile(const ColorProfile& colorProfile) {
- const ui::Dataspace targetDataspace =
+ ui::Dataspace targetDataspace =
getDisplayColorProfile()->getTargetDataspace(colorProfile.mode, colorProfile.dataspace,
colorProfile.colorSpaceAgnosticDataspace);
- if (mState.colorMode == colorProfile.mode && mState.dataspace == colorProfile.dataspace &&
- mState.renderIntent == colorProfile.renderIntent &&
- mState.targetDataspace == targetDataspace) {
+ auto& outputState = editState();
+ if (outputState.colorMode == colorProfile.mode &&
+ outputState.dataspace == colorProfile.dataspace &&
+ outputState.renderIntent == colorProfile.renderIntent &&
+ outputState.targetDataspace == targetDataspace) {
return;
}
- mState.colorMode = colorProfile.mode;
- mState.dataspace = colorProfile.dataspace;
- mState.renderIntent = colorProfile.renderIntent;
- mState.targetDataspace = targetDataspace;
+ outputState.colorMode = colorProfile.mode;
+ outputState.dataspace = colorProfile.dataspace;
+ outputState.renderIntent = colorProfile.renderIntent;
+ outputState.targetDataspace = targetDataspace;
mRenderSurface->setBufferDataspace(colorProfile.dataspace);
@@ -166,7 +172,7 @@
}
void Output::dumpBase(std::string& out) const {
- mState.dump(out);
+ dumpState(out);
if (mDisplayColorProfile) {
mDisplayColorProfile->dump(out);
@@ -212,7 +218,7 @@
void Output::setRenderSurface(std::unique_ptr<compositionengine::RenderSurface> surface) {
mRenderSurface = std::move(surface);
- mState.bounds = Rect(mRenderSurface->getSize());
+ editState().bounds = Rect(mRenderSurface->getSize());
dirtyEntireOutput();
}
@@ -221,18 +227,11 @@
mRenderSurface = std::move(surface);
}
-const OutputCompositionState& Output::getState() const {
- return mState;
-}
-
-OutputCompositionState& Output::editState() {
- return mState;
-}
-
Region Output::getDirtyRegion(bool repaintEverything) const {
- Region dirty(mState.viewport);
+ const auto& outputState = getState();
+ Region dirty(outputState.viewport);
if (!repaintEverything) {
- dirty.andSelf(mState.dirtyRegion);
+ dirty.andSelf(outputState.dirtyRegion);
}
return dirty;
}
@@ -240,8 +239,9 @@
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 && (*layerStackId == mState.layerStackId) &&
- (!internalOnly || mState.layerStackInternal);
+ const auto& outputState = getState();
+ return layerStackId && (*layerStackId == outputState.layerStackId) &&
+ (!internalOnly || outputState.layerStackInternal);
}
bool Output::belongsInOutput(const compositionengine::Layer* layer) const {
@@ -274,15 +274,6 @@
return nullptr;
}
-std::unique_ptr<compositionengine::OutputLayer> Output::getOrCreateOutputLayer(
- std::shared_ptr<compositionengine::Layer> layer, sp<compositionengine::LayerFE> layerFE) {
- auto result = takeOutputLayerForLayer(layer.get());
- if (!result) {
- result = createOutputLayer(layer, layerFE);
- }
- return result;
-}
-
std::unique_ptr<compositionengine::OutputLayer> Output::createOutputLayer(
const std::shared_ptr<compositionengine::Layer>& layer,
const sp<compositionengine::LayerFE>& layerFE) const {
@@ -332,8 +323,10 @@
ATRACE_CALL();
ALOGV(__FUNCTION__);
+ auto& outputState = editState();
+
// Do nothing if this output is not enabled or there is no need to perform this update
- if (!mState.isEnabled || CC_LIKELY(!refreshArgs.updatingOutputGeometryThisFrame)) {
+ if (!outputState.isEnabled || CC_LIKELY(!refreshArgs.updatingOutputGeometryThisFrame)) {
return;
}
@@ -342,12 +335,12 @@
collectVisibleLayers(refreshArgs, coverage);
// Compute the resulting coverage for this output, and store it for later
- const ui::Transform& tr = mState.transform;
- Region undefinedRegion{mState.bounds};
+ const ui::Transform& tr = outputState.transform;
+ Region undefinedRegion{outputState.bounds};
undefinedRegion.subtractSelf(tr.transform(coverage.aboveOpaqueLayers));
- mState.undefinedRegion = undefinedRegion;
- mState.dirtyRegion.orSelf(coverage.dirtyRegion);
+ outputState.undefinedRegion = undefinedRegion;
+ outputState.dirtyRegion.orSelf(coverage.dirtyRegion);
}
void Output::collectVisibleLayers(const compositionengine::CompositionRefreshArgs& refreshArgs,
@@ -543,8 +536,9 @@
// Peform the final check to see if this layer is visible on this output
// TODO(b/121291683): Why does this not use visibleRegion? (see outputSpaceVisibleRegion below)
- Region drawRegion(mState.transform.transform(visibleNonTransparentRegion));
- drawRegion.andSelf(mState.bounds);
+ const auto& outputState = getState();
+ Region drawRegion(outputState.transform.transform(visibleNonTransparentRegion));
+ drawRegion.andSelf(outputState.bounds);
if (drawRegion.isEmpty()) {
return nullptr;
}
@@ -560,8 +554,8 @@
outputLayerState.visibleRegion = visibleRegion;
outputLayerState.visibleNonTransparentRegion = visibleNonTransparentRegion;
outputLayerState.coveredRegion = coveredRegion;
- outputLayerState.outputSpaceVisibleRegion =
- mState.transform.transform(outputLayerState.visibleRegion.intersect(mState.viewport));
+ outputLayerState.outputSpaceVisibleRegion = outputState.transform.transform(
+ outputLayerState.visibleRegion.intersect(outputState.viewport));
return result;
}
@@ -706,9 +700,10 @@
}
void Output::beginFrame() {
+ auto& outputState = editState();
const bool dirty = !getDirtyRegion(false).isEmpty();
const bool empty = mOutputLayersOrderedByZ.empty();
- const bool wasEmpty = !mState.lastCompositionHadVisibleLayers;
+ const bool wasEmpty = !outputState.lastCompositionHadVisibleLayers;
// If nothing has changed (!dirty), don't recompose.
// If something changed, but we don't currently have any visible layers,
@@ -729,7 +724,7 @@
mRenderSurface->beginFrame(mustRecompose);
if (mustRecompose) {
- mState.lastCompositionHadVisibleLayers = !empty;
+ outputState.lastCompositionHadVisibleLayers = !empty;
}
}
@@ -737,13 +732,15 @@
ATRACE_CALL();
ALOGV(__FUNCTION__);
- if (!mState.isEnabled) {
+ const auto& outputState = getState();
+ if (!outputState.isEnabled) {
return;
}
chooseCompositionStrategy();
- mRenderSurface->prepareFrame(mState.usesClientComposition, mState.usesDeviceComposition);
+ mRenderSurface->prepareFrame(outputState.usesClientComposition,
+ outputState.usesDeviceComposition);
}
void Output::devOptRepaintFlash(const compositionengine::CompositionRefreshArgs& refreshArgs) {
@@ -751,7 +748,7 @@
return;
}
- if (mState.isEnabled) {
+ if (getState().isEnabled) {
// transform the dirty region into this screen's coordinate space
const Region dirtyRegion = getDirtyRegion(refreshArgs.repaintEverything);
if (!dirtyRegion.isEmpty()) {
@@ -774,7 +771,7 @@
ATRACE_CALL();
ALOGV(__FUNCTION__);
- if (!mState.isEnabled) {
+ if (!getState().isEnabled) {
return;
}
@@ -793,32 +790,33 @@
ATRACE_CALL();
ALOGV(__FUNCTION__);
+ const auto& outputState = getState();
const TracedOrdinal<bool> hasClientComposition = {"hasClientComposition",
- mState.usesClientComposition};
+ outputState.usesClientComposition};
base::unique_fd readyFence;
-
if (!hasClientComposition) {
return readyFence;
}
ALOGV("hasClientComposition");
- auto& renderEngine = mCompositionEngine.getRenderEngine();
+ auto& renderEngine = getCompositionEngine().getRenderEngine();
const bool supportsProtectedContent = renderEngine.supportsProtectedContent();
renderengine::DisplaySettings clientCompositionDisplay;
- clientCompositionDisplay.physicalDisplay = mState.scissor;
- clientCompositionDisplay.clip = mState.scissor;
- clientCompositionDisplay.globalTransform = mState.transform.asMatrix4();
- clientCompositionDisplay.orientation = mState.orientation;
- clientCompositionDisplay.outputDataspace =
- mDisplayColorProfile->hasWideColorGamut() ? mState.dataspace : ui::Dataspace::UNKNOWN;
+ clientCompositionDisplay.physicalDisplay = outputState.scissor;
+ clientCompositionDisplay.clip = outputState.scissor;
+ clientCompositionDisplay.globalTransform = outputState.transform.asMatrix4();
+ clientCompositionDisplay.orientation = outputState.orientation;
+ clientCompositionDisplay.outputDataspace = mDisplayColorProfile->hasWideColorGamut()
+ ? outputState.dataspace
+ : ui::Dataspace::UNKNOWN;
clientCompositionDisplay.maxLuminance =
mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
// Compute the global color transform matrix.
- if (!mState.usesDeviceComposition && !getSkipColorTransform()) {
- clientCompositionDisplay.colorTransform = mState.colorTransformMatrix;
+ if (!outputState.usesDeviceComposition && !getSkipColorTransform()) {
+ clientCompositionDisplay.colorTransform = outputState.colorTransformMatrix;
}
// Note: Updated by generateClientCompositionRequests
@@ -833,7 +831,7 @@
// If we the display is secure, protected content support is enabled, and at
// least one layer has protected content, we need to use a secure back
// buffer.
- if (mState.isSecure && supportsProtectedContent) {
+ if (outputState.isSecure && supportsProtectedContent) {
bool needsProtected =
std::any_of(mOutputLayersOrderedByZ.begin(), mOutputLayersOrderedByZ.end(),
[](auto& layer) {
@@ -883,7 +881,8 @@
std::vector<renderengine::LayerSettings> clientCompositionLayers;
ALOGV("Rendering client layers");
- const Region viewportRegion(mState.viewport);
+ const auto& outputState = getState();
+ const Region viewportRegion(outputState.viewport);
const bool useIdentityTransform = false;
bool firstLayer = true;
// Used when a layer clears part of the buffer.
@@ -918,8 +917,8 @@
compositionengine::LayerFE::ClientCompositionTargetSettings targetSettings{
clip,
useIdentityTransform,
- layer->needsFiltering() || mState.needsFiltering,
- mState.isSecure,
+ layer->needsFiltering() || outputState.needsFiltering,
+ outputState.isSecure,
supportsProtectedContent,
clientComposition ? clearRegion : dummyRegion,
};
@@ -972,14 +971,15 @@
return;
}
- mState.dirtyRegion.clear();
+ auto& outputState = editState();
+ outputState.dirtyRegion.clear();
mRenderSurface->flip();
auto frame = presentAndGetFrameFences();
mRenderSurface->onPresentDisplayCompleted();
- for (auto& layer : getOutputLayersOrderedByZ()) {
+ for (auto& layer : mOutputLayersOrderedByZ) {
// The layer buffer from the previous frame (if any) is released
// by HWC only when the release fence from this frame (if any) is
// signaled. Always get the release fence from HWC first.
@@ -997,7 +997,7 @@
// client target acquire fence when it is available, even though
// this is suboptimal.
// TODO(b/121291683): Track previous frame client target acquire fence.
- if (mState.usesClientComposition) {
+ if (outputState.usesClientComposition) {
releaseFence =
Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence);
}
@@ -1006,7 +1006,7 @@
}
// We've got a list of layers needing fences, that are disjoint with
- // getOutputLayersOrderedByZ. The best we can do is to
+ // mOutputLayersOrderedByZ. The best we can do is to
// supply them with the present fence.
for (auto& weakLayer : mReleasedLayers) {
if (auto layer = weakLayer.promote(); layer != nullptr) {
@@ -1019,13 +1019,15 @@
}
void Output::dirtyEntireOutput() {
- mState.dirtyRegion.set(mState.bounds);
+ auto& outputState = editState();
+ outputState.dirtyRegion.set(outputState.bounds);
}
void Output::chooseCompositionStrategy() {
// The base output implementation can only do client composition
- mState.usesClientComposition = true;
- mState.usesDeviceComposition = false;
+ auto& outputState = editState();
+ outputState.usesClientComposition = true;
+ outputState.usesDeviceComposition = false;
}
bool Output::getSkipColorTransform() const {
@@ -1034,7 +1036,7 @@
compositionengine::Output::FrameFences Output::presentAndGetFrameFences() {
compositionengine::Output::FrameFences result;
- if (mState.usesClientComposition) {
+ if (getState().usesClientComposition) {
result.clientTargetAcquireFence = mRenderSurface->getClientTargetAcquireFence();
}
return result;
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 43ab87a..0124e5b 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -44,49 +44,26 @@
} // namespace
-std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
+std::unique_ptr<OutputLayer> createOutputLayer(
const compositionengine::Output& output,
const std::shared_ptr<compositionengine::Layer>& layer,
const sp<compositionengine::LayerFE>& layerFE) {
- return std::make_unique<OutputLayer>(output, layer, layerFE);
+ return createOutputLayerTemplated<OutputLayer>(output, layer, 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::setHwcLayer(std::shared_ptr<HWC2::Layer> hwcLayer) {
+ auto& state = editState();
if (hwcLayer) {
- mState.hwc.emplace(hwcLayer);
+ state.hwc.emplace(std::move(hwcLayer));
} else {
- mState.hwc.reset();
+ state.hwc.reset();
}
}
-const compositionengine::Output& OutputLayer::getOutput() const {
- return mOutput;
-}
-
-compositionengine::Layer& OutputLayer::getLayer() const {
- return *mLayer;
-}
-
-compositionengine::LayerFE& OutputLayer::getLayerFE() const {
- return *mLayerFE;
-}
-
-const OutputLayerCompositionState& OutputLayer::getState() const {
- return mState;
-}
-
-OutputLayerCompositionState& OutputLayer::editState() {
- return mState;
-}
-
Rect OutputLayer::calculateInitialCrop() const {
- const auto& layerState = mLayer->getFEState();
+ const auto& layerState = getLayer().getFEState();
// apply the projection's clipping to the window crop in
// layerstack space, and convert-back to layer space.
@@ -96,7 +73,7 @@
FloatRect activeCropFloat =
reduce(layerState.geomLayerBounds, layerState.transparentRegionHint);
- const Rect& viewport = mOutput.getState().viewport;
+ const Rect& viewport = getOutput().getState().viewport;
const ui::Transform& layerTransform = layerState.geomLayerTransform;
const ui::Transform& inverseLayerTransform = layerState.geomInverseLayerTransform;
// Transform to screen space.
@@ -119,8 +96,8 @@
}
FloatRect OutputLayer::calculateOutputSourceCrop() const {
- const auto& layerState = mLayer->getFEState();
- const auto& outputState = mOutput.getState();
+ const auto& layerState = getLayer().getFEState();
+ const auto& outputState = getOutput().getState();
if (!layerState.geomUsesSourceCrop) {
return {};
@@ -196,8 +173,8 @@
}
Rect OutputLayer::calculateOutputDisplayFrame() const {
- const auto& layerState = mLayer->getFEState();
- const auto& outputState = mOutput.getState();
+ const auto& layerState = getLayer().getFEState();
+ const auto& outputState = getOutput().getState();
// apply the layer's transform, followed by the display's global transform
// here we're guaranteed that the layer's transform preserves rects
@@ -243,8 +220,8 @@
}
uint32_t OutputLayer::calculateOutputRelativeBufferTransform() const {
- const auto& layerState = mLayer->getFEState();
- const auto& outputState = mOutput.getState();
+ const auto& layerState = getLayer().getFEState();
+ const auto& outputState = getOutput().getState();
/*
* Transformations are applied in this order:
@@ -283,9 +260,10 @@
} // namespace impl
void OutputLayer::updateCompositionState(bool includeGeometry) {
- const auto& layerFEState = mLayer->getFEState();
- const auto& outputState = mOutput.getState();
- const auto& profile = *mOutput.getDisplayColorProfile();
+ const auto& layerFEState = getLayer().getFEState();
+ const auto& outputState = getOutput().getState();
+ const auto& profile = *getOutput().getDisplayColorProfile();
+ auto& state = editState();
if (includeGeometry) {
// Clear the forceClientComposition flag before it is set for any
@@ -293,48 +271,49 @@
// updating the geometry state, we only clear it when updating the
// geometry since those conditions for forcing client composition won't
// go away otherwise.
- mState.forceClientComposition = false;
+ state.forceClientComposition = false;
- mState.displayFrame = calculateOutputDisplayFrame();
- mState.sourceCrop = calculateOutputSourceCrop();
- mState.bufferTransform =
+ state.displayFrame = calculateOutputDisplayFrame();
+ state.sourceCrop = calculateOutputSourceCrop();
+ state.bufferTransform =
static_cast<Hwc2::Transform>(calculateOutputRelativeBufferTransform());
if ((layerFEState.isSecure && !outputState.isSecure) ||
- (mState.bufferTransform & ui::Transform::ROT_INVALID)) {
- mState.forceClientComposition = true;
+ (state.bufferTransform & ui::Transform::ROT_INVALID)) {
+ state.forceClientComposition = true;
}
}
// Determine the output dependent dataspace for this layer. If it is
// colorspace agnostic, it just uses the dataspace chosen for the output to
// avoid the need for color conversion.
- mState.dataspace = layerFEState.isColorspaceAgnostic &&
+ state.dataspace = layerFEState.isColorspaceAgnostic &&
outputState.targetDataspace != ui::Dataspace::UNKNOWN
? outputState.targetDataspace
: layerFEState.dataspace;
// These are evaluated every frame as they can potentially change at any
// time.
- if (layerFEState.forceClientComposition || !profile.isDataspaceSupported(mState.dataspace)) {
- mState.forceClientComposition = true;
+ if (layerFEState.forceClientComposition || !profile.isDataspaceSupported(state.dataspace)) {
+ state.forceClientComposition = true;
}
}
void OutputLayer::writeStateToHWC(bool includeGeometry) {
+ const auto& state = getState();
// Skip doing this if there is no HWC interface
- if (!mState.hwc) {
+ if (!state.hwc) {
return;
}
- auto& hwcLayer = (*mState.hwc).hwcLayer;
+ auto& hwcLayer = (*state.hwc).hwcLayer;
if (!hwcLayer) {
ALOGE("[%s] failed to write composition state to HWC -- no hwcLayer for output %s",
- mLayerFE->getDebugName(), mOutput.getName().c_str());
+ getLayerFE().getDebugName(), getOutput().getName().c_str());
return;
}
- const auto& outputIndependentState = mLayer->getFEState();
+ const auto& outputIndependentState = getLayer().getFEState();
auto requestedCompositionType = outputIndependentState.compositionType;
if (includeGeometry) {
@@ -355,7 +334,7 @@
if (auto error = hwcLayer->setDisplayFrame(outputDependentState.displayFrame);
error != HWC2::Error::None) {
ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)",
- mLayerFE->getDebugName(), outputDependentState.displayFrame.left,
+ getLayerFE().getDebugName(), outputDependentState.displayFrame.left,
outputDependentState.displayFrame.top, outputDependentState.displayFrame.right,
outputDependentState.displayFrame.bottom, to_string(error).c_str(),
static_cast<int32_t>(error));
@@ -365,15 +344,15 @@
error != HWC2::Error::None) {
ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
"%s (%d)",
- mLayerFE->getDebugName(), outputDependentState.sourceCrop.left,
+ getLayerFE().getDebugName(), outputDependentState.sourceCrop.left,
outputDependentState.sourceCrop.top, outputDependentState.sourceCrop.right,
outputDependentState.sourceCrop.bottom, to_string(error).c_str(),
static_cast<int32_t>(error));
}
if (auto error = hwcLayer->setZOrder(outputDependentState.z); error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set Z %u: %s (%d)", mLayerFE->getDebugName(), outputDependentState.z,
- to_string(error).c_str(), static_cast<int32_t>(error));
+ ALOGE("[%s] Failed to set Z %u: %s (%d)", getLayerFE().getDebugName(),
+ outputDependentState.z, to_string(error).c_str(), static_cast<int32_t>(error));
}
// Solid-color layers should always use an identity transform.
@@ -383,7 +362,7 @@
: static_cast<Hwc2::Transform>(0);
if (auto error = hwcLayer->setTransform(static_cast<HWC2::Transform>(bufferTransform));
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set transform %s: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set transform %s: %s (%d)", getLayerFE().getDebugName(),
toString(outputDependentState.bufferTransform).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
@@ -394,21 +373,21 @@
if (auto error = hwcLayer->setBlendMode(
static_cast<HWC2::BlendMode>(outputIndependentState.blendMode));
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set blend mode %s: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set blend mode %s: %s (%d)", getLayerFE().getDebugName(),
toString(outputIndependentState.blendMode).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
if (auto error = hwcLayer->setPlaneAlpha(outputIndependentState.alpha);
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set plane alpha %.3f: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set plane alpha %.3f: %s (%d)", getLayerFE().getDebugName(),
outputIndependentState.alpha, to_string(error).c_str(), static_cast<int32_t>(error));
}
if (auto error = hwcLayer->setInfo(outputIndependentState.type, outputIndependentState.appId);
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set info %s (%d)", mLayerFE->getDebugName(), to_string(error).c_str(),
- static_cast<int32_t>(error));
+ ALOGE("[%s] Failed to set info %s (%d)", getLayerFE().getDebugName(),
+ to_string(error).c_str(), static_cast<int32_t>(error));
}
}
@@ -419,14 +398,14 @@
// state and should not change every frame.
if (auto error = hwcLayer->setVisibleRegion(outputDependentState.outputSpaceVisibleRegion);
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set visible region: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set visible region: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
outputDependentState.outputSpaceVisibleRegion.dump(LOG_TAG);
}
if (auto error = hwcLayer->setDataspace(outputDependentState.dataspace);
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set dataspace %d: %s (%d)", getLayerFE().getDebugName(),
outputDependentState.dataspace, to_string(error).c_str(),
static_cast<int32_t>(error));
}
@@ -441,13 +420,13 @@
editState().forceClientComposition = true;
break;
default:
- ALOGE("[%s] Failed to set color transform: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set color transform: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
if (auto error = hwcLayer->setSurfaceDamage(outputIndependentState.surfaceDamage);
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set surface damage: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set surface damage: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
outputIndependentState.surfaceDamage.dump(LOG_TAG);
}
@@ -479,7 +458,7 @@
255};
if (auto error = hwcLayer->setColor(color); error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set color: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set color: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
}
@@ -488,7 +467,7 @@
const LayerFECompositionState& outputIndependentState) {
if (auto error = hwcLayer->setSidebandStream(outputIndependentState.sidebandStream->handle());
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", getLayerFE().getDebugName(),
outputIndependentState.sidebandStream->handle(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
@@ -497,11 +476,11 @@
void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,
const LayerFECompositionState& outputIndependentState) {
auto supportedPerFrameMetadata =
- mOutput.getDisplayColorProfile()->getSupportedPerFrameMetadata();
+ getOutput().getDisplayColorProfile()->getSupportedPerFrameMetadata();
if (auto error = hwcLayer->setPerFrameMetadata(supportedPerFrameMetadata,
outputIndependentState.hdrMetadata);
error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
- ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
@@ -515,7 +494,7 @@
if (auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, outputIndependentState.acquireFence);
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set buffer %p: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set buffer %p: %s (%d)", getLayerFE().getDebugName(),
outputIndependentState.buffer->handle, to_string(error).c_str(),
static_cast<int32_t>(error));
}
@@ -537,7 +516,7 @@
if (auto error = hwcLayer->setCompositionType(
static_cast<HWC2::Composition>(requestedCompositionType));
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set composition type %s: %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Failed to set composition type %s: %s (%d)", getLayerFE().getDebugName(),
toString(requestedCompositionType).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
@@ -551,8 +530,8 @@
return;
}
- const auto& layerFEState = mLayer->getFEState();
- const auto& outputState = mOutput.getState();
+ const auto& layerFEState = getLayer().getFEState();
+ const auto& outputState = getOutput().getState();
Rect frame = layerFEState.cursorFrame;
frame.intersect(outputState.viewport, &frame);
@@ -560,23 +539,26 @@
if (auto error = hwcLayer->setCursorPosition(position.left, position.top);
error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set cursor position to (%d, %d): %s (%d)", mLayerFE->getDebugName(),
- position.left, position.top, to_string(error).c_str(), static_cast<int32_t>(error));
+ ALOGE("[%s] Failed to set cursor position to (%d, %d): %s (%d)",
+ getLayerFE().getDebugName(), position.left, position.top, to_string(error).c_str(),
+ static_cast<int32_t>(error));
}
}
HWC2::Layer* OutputLayer::getHwcLayer() const {
- return mState.hwc ? mState.hwc->hwcLayer.get() : nullptr;
+ const auto& state = getState();
+ return state.hwc ? state.hwc->hwcLayer.get() : nullptr;
}
bool OutputLayer::requiresClientComposition() const {
- return !mState.hwc ||
- mState.hwc->hwcCompositionType == Hwc2::IComposerClient::Composition::CLIENT;
+ const auto& state = getState();
+ return !state.hwc ||
+ state.hwc->hwcCompositionType == Hwc2::IComposerClient::Composition::CLIENT;
}
bool OutputLayer::isHardwareCursor() const {
- return mState.hwc &&
- mState.hwc->hwcCompositionType == Hwc2::IComposerClient::Composition::CURSOR;
+ const auto& state = getState();
+ return state.hwc && state.hwc->hwcCompositionType == Hwc2::IComposerClient::Composition::CURSOR;
}
void OutputLayer::detectDisallowedCompositionTypeChange(
@@ -602,15 +584,16 @@
if (!result) {
ALOGE("[%s] Invalid device requested composition type change: %s (%d) --> %s (%d)",
- mLayerFE->getDebugName(), toString(from).c_str(), static_cast<int>(from),
+ getLayerFE().getDebugName(), toString(from).c_str(), static_cast<int>(from),
toString(to).c_str(), static_cast<int>(to));
}
}
void OutputLayer::applyDeviceCompositionTypeChange(
Hwc2::IComposerClient::Composition compositionType) {
- LOG_FATAL_IF(!mState.hwc);
- auto& hwcState = *mState.hwc;
+ auto& state = editState();
+ LOG_FATAL_IF(!state.hwc);
+ auto& hwcState = *state.hwc;
detectDisallowedCompositionTypeChange(hwcState.hwcCompositionType, compositionType);
@@ -618,25 +601,28 @@
}
void OutputLayer::prepareForDeviceLayerRequests() {
- mState.clearClientTarget = false;
+ auto& state = editState();
+ state.clearClientTarget = false;
}
void OutputLayer::applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest request) {
+ auto& state = editState();
switch (request) {
case Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET:
- mState.clearClientTarget = true;
+ state.clearClientTarget = true;
break;
default:
- ALOGE("[%s] Unknown device layer request %s (%d)", mLayerFE->getDebugName(),
+ ALOGE("[%s] Unknown device layer request %s (%d)", getLayerFE().getDebugName(),
toString(request).c_str(), static_cast<int>(request));
break;
}
}
bool OutputLayer::needsFiltering() const {
- const auto& displayFrame = mState.displayFrame;
- const auto& sourceCrop = mState.sourceCrop;
+ const auto& state = getState();
+ const auto& displayFrame = state.displayFrame;
+ const auto& sourceCrop = state.sourceCrop;
return sourceCrop.getHeight() != displayFrame.getHeight() ||
sourceCrop.getWidth() != displayFrame.getWidth();
}
@@ -644,9 +630,9 @@
void OutputLayer::dump(std::string& out) const {
using android::base::StringAppendF;
- StringAppendF(&out, " - Output Layer %p (Composition layer %p) (%s)\n", this, mLayer.get(),
- mLayerFE->getDebugName());
- mState.dump(out);
+ StringAppendF(&out, " - Output Layer %p (Composition layer %p) (%s)\n", this, &getLayer(),
+ getLayerFE().getDebugName());
+ dumpState(out);
}
} // namespace impl
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index 1ce6b4c..5ed21fc 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -43,12 +43,13 @@
std::unique_ptr<compositionengine::RenderSurface> createRenderSurface(
const compositionengine::CompositionEngine& compositionEngine,
- compositionengine::Display& display, compositionengine::RenderSurfaceCreationArgs&& args) {
- return std::make_unique<RenderSurface>(compositionEngine, display, std::move(args));
+ compositionengine::Display& display,
+ const compositionengine::RenderSurfaceCreationArgs& args) {
+ return std::make_unique<RenderSurface>(compositionEngine, display, args);
}
RenderSurface::RenderSurface(const CompositionEngine& compositionEngine, Display& display,
- RenderSurfaceCreationArgs&& args)
+ const RenderSurfaceCreationArgs& args)
: mCompositionEngine(compositionEngine),
mDisplay(display),
mNativeWindow(args.nativeWindow),
@@ -156,7 +157,7 @@
return mGraphicBuffer;
}
-void RenderSurface::queueBuffer(base::unique_fd&& readyFence) {
+void RenderSurface::queueBuffer(base::unique_fd readyFence) {
auto& state = mDisplay.getState();
if (state.usesClientComposition || state.flipClientTarget) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 74b3ada..8401f08 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -58,7 +58,7 @@
layers.emplace_back(mLayer1);
layers.emplace_back(mLayer2);
layers.emplace_back(mLayer3);
- mDisplay.setOutputLayersOrderedByZ(std::move(layers));
+ mDisplay->setOutputLayersOrderedByZ(std::move(layers));
}
StrictMock<android::mock::HWComposer> mHwComposer;
@@ -71,11 +71,12 @@
mock::OutputLayer* mLayer1 = new StrictMock<mock::OutputLayer>();
mock::OutputLayer* mLayer2 = new StrictMock<mock::OutputLayer>();
mock::OutputLayer* mLayer3 = new StrictMock<mock::OutputLayer>();
- impl::Display mDisplay{mCompositionEngine,
- DisplayCreationArgsBuilder()
- .setDisplayId(DEFAULT_DISPLAY_ID)
- .setPowerAdvisor(&mPowerAdvisor)
- .build()};
+ std::shared_ptr<impl::Display> mDisplay =
+ impl::createDisplay(mCompositionEngine,
+ DisplayCreationArgsBuilder()
+ .setDisplayId(DEFAULT_DISPLAY_ID)
+ .setPowerAdvisor(&mPowerAdvisor)
+ .build());
};
/*
@@ -95,12 +96,10 @@
{
constexpr DisplayId display2 = DisplayId{546u};
- auto display = impl::createDisplay(mCompositionEngine,
- DisplayCreationArgsBuilder()
- .setIsSecure(true)
- .setDisplayId(display2)
- .build());
- EXPECT_TRUE(display->isSecure());
+ auto display =
+ impl::createDisplay(mCompositionEngine,
+ DisplayCreationArgsBuilder().setDisplayId(display2).build());
+ EXPECT_FALSE(display->isSecure());
EXPECT_FALSE(display->isVirtual());
EXPECT_EQ(display2, display->getId());
}
@@ -126,13 +125,13 @@
// The first call to disconnect will disconnect the display with the HWC and
// set mHwcId to -1.
EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(1);
- mDisplay.disconnect();
- EXPECT_FALSE(mDisplay.getId());
+ mDisplay->disconnect();
+ EXPECT_FALSE(mDisplay->getId());
// Subsequent calls will do nothing,
EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(0);
- mDisplay.disconnect();
- EXPECT_FALSE(mDisplay.getId());
+ mDisplay->disconnect();
+ EXPECT_FALSE(mDisplay->getId());
}
/*
@@ -143,7 +142,7 @@
// No change does nothing
CompositionRefreshArgs refreshArgs;
refreshArgs.colorTransformMatrix = std::nullopt;
- mDisplay.setColorTransform(refreshArgs);
+ mDisplay->setColorTransform(refreshArgs);
// Identity matrix sets an identity state value
const mat4 kIdentity;
@@ -151,7 +150,7 @@
EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kIdentity)).Times(1);
refreshArgs.colorTransformMatrix = kIdentity;
- mDisplay.setColorTransform(refreshArgs);
+ mDisplay->setColorTransform(refreshArgs);
// Non-identity matrix sets a non-identity state value
const mat4 kNonIdentity = mat4() * 2;
@@ -159,7 +158,7 @@
EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kNonIdentity)).Times(1);
refreshArgs.colorTransformMatrix = kNonIdentity;
- mDisplay.setColorTransform(refreshArgs);
+ mDisplay->setColorTransform(refreshArgs);
}
/*
@@ -170,27 +169,27 @@
using ColorProfile = Output::ColorProfile;
mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
- mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
+ mDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
mock::DisplayColorProfile* colorProfile = new StrictMock<mock::DisplayColorProfile>();
- mDisplay.setDisplayColorProfileForTest(std::unique_ptr<DisplayColorProfile>(colorProfile));
+ mDisplay->setDisplayColorProfileForTest(std::unique_ptr<DisplayColorProfile>(colorProfile));
EXPECT_CALL(*colorProfile, getTargetDataspace(_, _, _))
.WillRepeatedly(Return(ui::Dataspace::UNKNOWN));
// These values are expected to be the initial state.
- ASSERT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
- ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
- ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
- ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
+ ASSERT_EQ(ui::ColorMode::NATIVE, mDisplay->getState().colorMode);
+ ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay->getState().dataspace);
+ ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay->getState().renderIntent);
+ ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay->getState().targetDataspace);
- // If the set values are unchanged, nothing happens
- mDisplay.setColorProfile(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
- ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN});
+ // Otherwise if the values are unchanged, nothing happens
+ mDisplay->setColorProfile(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
+ ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN});
- EXPECT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
- EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
- EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
- EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
+ EXPECT_EQ(ui::ColorMode::NATIVE, mDisplay->getState().colorMode);
+ EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay->getState().dataspace);
+ EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay->getState().renderIntent);
+ EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay->getState().targetDataspace);
// Otherwise if the values are different, updates happen
EXPECT_CALL(*renderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
@@ -199,24 +198,24 @@
ui::RenderIntent::TONE_MAP_COLORIMETRIC))
.Times(1);
- mDisplay.setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
- ui::RenderIntent::TONE_MAP_COLORIMETRIC,
- ui::Dataspace::UNKNOWN});
+ mDisplay->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
+ ui::RenderIntent::TONE_MAP_COLORIMETRIC,
+ ui::Dataspace::UNKNOWN});
- EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mDisplay.getState().colorMode);
- EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mDisplay.getState().dataspace);
- EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mDisplay.getState().renderIntent);
- EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
+ EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mDisplay->getState().colorMode);
+ EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mDisplay->getState().dataspace);
+ EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mDisplay->getState().renderIntent);
+ EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay->getState().targetDataspace);
}
TEST_F(DisplayTest, setColorModeDoesNothingForVirtualDisplay) {
using ColorProfile = Output::ColorProfile;
- impl::Display virtualDisplay{mCompositionEngine,
- DisplayCreationArgs{false, true, DEFAULT_DISPLAY_ID}};
+ std::shared_ptr<impl::Display> virtualDisplay{
+ impl::createDisplay(mCompositionEngine, DisplayCreationArgs{true, DEFAULT_DISPLAY_ID})};
mock::DisplayColorProfile* colorProfile = new StrictMock<mock::DisplayColorProfile>();
- virtualDisplay.setDisplayColorProfileForTest(
+ virtualDisplay->setDisplayColorProfileForTest(
std::unique_ptr<DisplayColorProfile>(colorProfile));
EXPECT_CALL(*colorProfile,
@@ -224,14 +223,14 @@
ui::Dataspace::UNKNOWN))
.WillOnce(Return(ui::Dataspace::UNKNOWN));
- virtualDisplay.setColorProfile(
+ virtualDisplay->setColorProfile(
ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
ui::RenderIntent::TONE_MAP_COLORIMETRIC, ui::Dataspace::UNKNOWN});
- EXPECT_EQ(ui::ColorMode::NATIVE, virtualDisplay.getState().colorMode);
- EXPECT_EQ(ui::Dataspace::UNKNOWN, virtualDisplay.getState().dataspace);
- EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, virtualDisplay.getState().renderIntent);
- EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
+ EXPECT_EQ(ui::ColorMode::NATIVE, virtualDisplay->getState().colorMode);
+ EXPECT_EQ(ui::Dataspace::UNKNOWN, virtualDisplay->getState().dataspace);
+ EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, virtualDisplay->getState().renderIntent);
+ EXPECT_EQ(ui::Dataspace::UNKNOWN, virtualDisplay->getState().targetDataspace);
}
/*
@@ -239,11 +238,11 @@
*/
TEST_F(DisplayTest, createDisplayColorProfileSetsDisplayColorProfile) {
- EXPECT_TRUE(mDisplay.getDisplayColorProfile() == nullptr);
- mDisplay.createDisplayColorProfile(
+ EXPECT_TRUE(mDisplay->getDisplayColorProfile() == nullptr);
+ mDisplay->createDisplayColorProfile(
DisplayColorProfileCreationArgs{false, HdrCapabilities(), 0,
DisplayColorProfileCreationArgs::HwcColorModes()});
- EXPECT_TRUE(mDisplay.getDisplayColorProfile() != nullptr);
+ EXPECT_TRUE(mDisplay->getDisplayColorProfile() != nullptr);
}
/*
@@ -252,9 +251,9 @@
TEST_F(DisplayTest, createRenderSurfaceSetsRenderSurface) {
EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL)).WillRepeatedly(Return(NO_ERROR));
- EXPECT_TRUE(mDisplay.getRenderSurface() == nullptr);
- mDisplay.createRenderSurface(RenderSurfaceCreationArgs{640, 480, mNativeWindow, nullptr});
- EXPECT_TRUE(mDisplay.getRenderSurface() != nullptr);
+ EXPECT_TRUE(mDisplay->getRenderSurface() == nullptr);
+ mDisplay->createRenderSurface(RenderSurfaceCreationArgs{640, 480, mNativeWindow, nullptr});
+ EXPECT_TRUE(mDisplay->getRenderSurface() != nullptr);
}
/*
@@ -268,7 +267,7 @@
EXPECT_CALL(mHwComposer, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
- auto outputLayer = mDisplay.createOutputLayer(layer, layerFE);
+ auto outputLayer = mDisplay->createOutputLayer(layer, layerFE);
EXPECT_EQ(&hwcLayer, outputLayer->getHwcLayer());
@@ -308,13 +307,13 @@
{
Output::ReleasedLayers releasedLayers;
releasedLayers.emplace_back(layerXLayerFE);
- mDisplay.setReleasedLayers(std::move(releasedLayers));
+ mDisplay->setReleasedLayers(std::move(releasedLayers));
}
CompositionRefreshArgs refreshArgs;
- mDisplay.setReleasedLayers(refreshArgs);
+ mDisplay->setReleasedLayers(refreshArgs);
- const auto& releasedLayers = mDisplay.getReleasedLayersForTest();
+ const auto& releasedLayers = mDisplay->getReleasedLayersForTest();
ASSERT_EQ(1, releasedLayers.size());
}
@@ -341,9 +340,9 @@
refreshArgs.layersWithQueuedFrames.push_back(&layerXLayer);
refreshArgs.layersWithQueuedFrames.push_back(nullptr);
- mDisplay.setReleasedLayers(refreshArgs);
+ mDisplay->setReleasedLayers(refreshArgs);
- const auto& releasedLayers = mDisplay.getReleasedLayersForTest();
+ const auto& releasedLayers = mDisplay->getReleasedLayersForTest();
ASSERT_EQ(2, releasedLayers.size());
ASSERT_EQ(layer1LayerFE.get(), releasedLayers[0].promote().get());
ASSERT_EQ(layer2LayerFE.get(), releasedLayers[1].promote().get());
@@ -356,8 +355,8 @@
struct DisplayChooseCompositionStrategyTest : public testing::Test {
struct DisplayPartialMock : public impl::Display {
DisplayPartialMock(const compositionengine::CompositionEngine& compositionEngine,
- compositionengine::DisplayCreationArgs&& args)
- : impl::Display(compositionEngine, std::move(args)) {}
+ const compositionengine::DisplayCreationArgs& args)
+ : impl::Display(args), mCompositionEngine(compositionEngine) {}
// Sets up the helper functions called by chooseCompositionStrategy to
// use a mock implementations.
@@ -366,6 +365,21 @@
MOCK_METHOD1(applyChangedTypesToLayers, void(const impl::Display::ChangedTypes&));
MOCK_METHOD1(applyDisplayRequests, void(const impl::Display::DisplayRequests&));
MOCK_METHOD1(applyLayerRequestsToLayers, void(const impl::Display::LayerRequests&));
+
+ // compositionengine::Output overrides
+ const OutputCompositionState& getState() const override { return mState; }
+ OutputCompositionState& editState() override { return mState; }
+
+ // compositionengine::impl::Output overrides
+ const CompositionEngine& getCompositionEngine() const override {
+ return mCompositionEngine;
+ };
+
+ // These need implementations though are not expected to be called.
+ MOCK_CONST_METHOD1(dumpState, void(std::string&));
+
+ const compositionengine::CompositionEngine& mCompositionEngine;
+ impl::OutputCompositionState mState;
};
DisplayChooseCompositionStrategyTest() {
@@ -380,12 +394,13 @@
};
TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfNotAHwcDisplay) {
- impl::Display nonHwcDisplay{mCompositionEngine, DisplayCreationArgsBuilder().build()};
- EXPECT_FALSE(nonHwcDisplay.getId());
+ std::shared_ptr<impl::Display> nonHwcDisplay{
+ impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
+ EXPECT_FALSE(nonHwcDisplay->getId());
- nonHwcDisplay.chooseCompositionStrategy();
+ nonHwcDisplay->chooseCompositionStrategy();
- auto& state = nonHwcDisplay.getState();
+ auto& state = nonHwcDisplay->getState();
EXPECT_TRUE(state.usesClientComposition);
EXPECT_FALSE(state.usesDeviceComposition);
}
@@ -466,7 +481,7 @@
hasDisplayCapability(std::make_optional(DEFAULT_DISPLAY_ID),
HWC2::DisplayCapability::SkipClientColorTransform))
.WillOnce(Return(true));
- EXPECT_TRUE(mDisplay.getSkipColorTransform());
+ EXPECT_TRUE(mDisplay->getSkipColorTransform());
}
/*
@@ -478,14 +493,14 @@
EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(false));
- EXPECT_FALSE(mDisplay.anyLayersRequireClientComposition());
+ EXPECT_FALSE(mDisplay->anyLayersRequireClientComposition());
}
TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsTrue) {
EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
- EXPECT_TRUE(mDisplay.anyLayersRequireClientComposition());
+ EXPECT_TRUE(mDisplay->anyLayersRequireClientComposition());
}
/*
@@ -497,14 +512,14 @@
EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(true));
- EXPECT_TRUE(mDisplay.allLayersRequireClientComposition());
+ EXPECT_TRUE(mDisplay->allLayersRequireClientComposition());
}
TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsFalse) {
EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
- EXPECT_FALSE(mDisplay.allLayersRequireClientComposition());
+ EXPECT_FALSE(mDisplay->allLayersRequireClientComposition());
}
/*
@@ -512,7 +527,7 @@
*/
TEST_F(DisplayTest, applyChangedTypesToLayersTakesEarlyOutIfNoChangedLayers) {
- mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes());
+ mDisplay->applyChangedTypesToLayers(impl::Display::ChangedTypes());
}
TEST_F(DisplayTest, applyChangedTypesToLayersAppliesChanges) {
@@ -523,7 +538,7 @@
applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::DEVICE))
.Times(1);
- mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes{
+ mDisplay->applyChangedTypesToLayers(impl::Display::ChangedTypes{
{&mHWC2Layer1, HWC2::Composition::Client},
{&mHWC2Layer2, HWC2::Composition::Device},
{&mHWC2LayerUnknown, HWC2::Composition::SolidColor},
@@ -535,30 +550,30 @@
*/
TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesNoRequests) {
- mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(0));
+ mDisplay->applyDisplayRequests(static_cast<HWC2::DisplayRequest>(0));
- auto& state = mDisplay.getState();
+ auto& state = mDisplay->getState();
EXPECT_FALSE(state.flipClientTarget);
}
TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesFlipClientTarget) {
- mDisplay.applyDisplayRequests(HWC2::DisplayRequest::FlipClientTarget);
+ mDisplay->applyDisplayRequests(HWC2::DisplayRequest::FlipClientTarget);
- auto& state = mDisplay.getState();
+ auto& state = mDisplay->getState();
EXPECT_TRUE(state.flipClientTarget);
}
TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesWriteClientTargetToOutput) {
- mDisplay.applyDisplayRequests(HWC2::DisplayRequest::WriteClientTargetToOutput);
+ mDisplay->applyDisplayRequests(HWC2::DisplayRequest::WriteClientTargetToOutput);
- auto& state = mDisplay.getState();
+ auto& state = mDisplay->getState();
EXPECT_FALSE(state.flipClientTarget);
}
TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesAllRequestFlagsSet) {
- mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(~0));
+ mDisplay->applyDisplayRequests(static_cast<HWC2::DisplayRequest>(~0));
- auto& state = mDisplay.getState();
+ auto& state = mDisplay->getState();
EXPECT_TRUE(state.flipClientTarget);
}
@@ -571,7 +586,7 @@
EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
- mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests());
+ mDisplay->applyLayerRequestsToLayers(impl::Display::LayerRequests());
}
TEST_F(DisplayTest, applyLayerRequestsToLayers2) {
@@ -583,7 +598,7 @@
applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET))
.Times(1);
- mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests{
+ mDisplay->applyLayerRequestsToLayers(impl::Display::LayerRequests{
{&mHWC2Layer1, HWC2::LayerRequest::ClearClientTarget},
{&mHWC2LayerUnknown, HWC2::LayerRequest::ClearClientTarget},
});
@@ -617,7 +632,7 @@
.WillOnce(Return(layer2Fence));
EXPECT_CALL(mHwComposer, clearReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
- auto result = mDisplay.presentAndGetFrameFences();
+ auto result = mDisplay->presentAndGetFrameFences();
EXPECT_EQ(presentFence, result.presentFence);
@@ -634,10 +649,10 @@
TEST_F(DisplayTest, setExpensiveRenderingExpectedForwardsToPowerAdvisor) {
EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, true)).Times(1);
- mDisplay.setExpensiveRenderingExpected(true);
+ mDisplay->setExpensiveRenderingExpected(true);
EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, false)).Times(1);
- mDisplay.setExpensiveRenderingExpected(false);
+ mDisplay->setExpensiveRenderingExpected(false);
}
/*
@@ -646,20 +661,20 @@
TEST_F(DisplayTest, finishFrameDoesNotSkipCompositionIfNotDirtyOnHwcDisplay) {
mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
- mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
+ mDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
// We expect no calls to queueBuffer if composition was skipped.
EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
- mDisplay.editState().isEnabled = true;
- mDisplay.editState().usesClientComposition = false;
- mDisplay.editState().viewport = Rect(0, 0, 1, 1);
- mDisplay.editState().dirtyRegion = Region::INVALID_REGION;
+ mDisplay->editState().isEnabled = true;
+ mDisplay->editState().usesClientComposition = false;
+ mDisplay->editState().viewport = Rect(0, 0, 1, 1);
+ mDisplay->editState().dirtyRegion = Region::INVALID_REGION;
CompositionRefreshArgs refreshArgs;
refreshArgs.repaintEverything = false;
- mDisplay.finishFrame(refreshArgs);
+ mDisplay->finishFrame(refreshArgs);
}
TEST_F(DisplayTest, finishFrameSkipsCompositionIfNotDirty) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/LayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/LayerTest.cpp
index 26115a3..787f973 100644
--- a/services/surfaceflinger/CompositionEngine/tests/LayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/LayerTest.cpp
@@ -17,6 +17,7 @@
#include <gtest/gtest.h>
#include <compositionengine/LayerCreationArgs.h>
+#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/impl/Layer.h>
#include <compositionengine/mock/CompositionEngine.h>
#include <compositionengine/mock/LayerFE.h>
@@ -26,13 +27,28 @@
using testing::StrictMock;
-class LayerTest : public testing::Test {
-public:
+struct LayerTest : public testing::Test {
+ struct Layer final : public impl::Layer {
+ explicit Layer(const LayerCreationArgs& args) : mLayerFE(args.layerFE) {}
+ ~Layer() override = default;
+
+ // compositionengine::Layer overrides
+ sp<LayerFE> getLayerFE() const { return mLayerFE.promote(); }
+ const LayerFECompositionState& getFEState() const override { return mFrontEndState; }
+ LayerFECompositionState& editFEState() override { return mFrontEndState; }
+
+ // compositionengine::impl::Layer overrides
+ void dumpFEState(std::string& out) const override { mFrontEndState.dump(out); }
+
+ const wp<LayerFE> mLayerFE;
+ LayerFECompositionState mFrontEndState;
+ };
+
~LayerTest() override = default;
StrictMock<mock::CompositionEngine> mCompositionEngine;
sp<LayerFE> mLayerFE = new StrictMock<mock::LayerFE>();
- impl::Layer mLayer{mCompositionEngine, LayerCreationArgs{mLayerFE}};
+ Layer mLayer{LayerCreationArgs{mLayerFE}};
};
/* ------------------------------------------------------------------------
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index a1c156a..0347f75 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -15,6 +15,7 @@
*/
#include <compositionengine/impl/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <compositionengine/mock/CompositionEngine.h>
#include <compositionengine/mock/DisplayColorProfile.h>
#include <compositionengine/mock/Layer.h>
@@ -55,6 +56,29 @@
}
struct OutputLayerTest : public testing::Test {
+ struct OutputLayer final : public impl::OutputLayer {
+ OutputLayer(const compositionengine::Output& output,
+ std::shared_ptr<compositionengine::Layer> layer,
+ sp<compositionengine::LayerFE> layerFE)
+ : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
+ ~OutputLayer() override = default;
+
+ // compositionengine::OutputLayer overrides
+ const compositionengine::Output& getOutput() const override { return mOutput; }
+ compositionengine::Layer& getLayer() const override { return *mLayer; }
+ compositionengine::LayerFE& getLayerFE() const override { return *mLayerFE; }
+ const impl::OutputLayerCompositionState& getState() const override { return mState; }
+ impl::OutputLayerCompositionState& editState() override { return mState; }
+
+ // compositionengine::impl::OutputLayer overrides
+ void dumpState(std::string& out) const override { mState.dump(out); }
+
+ const compositionengine::Output& mOutput;
+ std::shared_ptr<compositionengine::Layer> mLayer;
+ sp<compositionengine::LayerFE> mLayerFE;
+ impl::OutputLayerCompositionState mState;
+ };
+
OutputLayerTest() {
EXPECT_CALL(*mLayerFE, getDebugName()).WillRepeatedly(Return("Test LayerFE"));
EXPECT_CALL(mOutput, getName()).WillRepeatedly(ReturnRef(kOutputName));
@@ -68,7 +92,7 @@
new StrictMock<compositionengine::mock::Layer>()};
sp<compositionengine::mock::LayerFE> mLayerFE{
new StrictMock<compositionengine::mock::LayerFE>()};
- impl::OutputLayer mOutputLayer{mOutput, mLayer, mLayerFE};
+ OutputLayer mOutputLayer{mOutput, mLayer, mLayerFE};
LayerFECompositionState mLayerFEState;
impl::OutputCompositionState mOutputState;
@@ -413,11 +437,26 @@
OutputLayerPartialMockForUpdateCompositionState(const compositionengine::Output& output,
std::shared_ptr<compositionengine::Layer> layer,
sp<compositionengine::LayerFE> layerFE)
- : impl::OutputLayer(output, layer, layerFE) {}
+ : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
// Mock everything called by updateCompositionState to simplify testing it.
MOCK_CONST_METHOD0(calculateOutputSourceCrop, FloatRect());
MOCK_CONST_METHOD0(calculateOutputDisplayFrame, Rect());
MOCK_CONST_METHOD0(calculateOutputRelativeBufferTransform, uint32_t());
+
+ // compositionengine::OutputLayer overrides
+ const compositionengine::Output& getOutput() const override { return mOutput; }
+ compositionengine::Layer& getLayer() const override { return *mLayer; }
+ compositionengine::LayerFE& getLayerFE() const override { return *mLayerFE; }
+ const impl::OutputLayerCompositionState& getState() const override { return mState; }
+ impl::OutputLayerCompositionState& editState() override { return mState; }
+
+ // These need implementations though are not expected to be called.
+ MOCK_CONST_METHOD1(dumpState, void(std::string&));
+
+ const compositionengine::Output& mOutput;
+ std::shared_ptr<compositionengine::Layer> mLayer;
+ sp<compositionengine::LayerFE> mLayerFE;
+ impl::OutputLayerCompositionState mState;
};
struct OutputLayerUpdateCompositionStateTest : public OutputLayerTest {
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 70c343b..635d77b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -51,11 +51,11 @@
struct OutputTest : public testing::Test {
OutputTest() {
- mOutput.setDisplayColorProfileForTest(
+ mOutput->setDisplayColorProfileForTest(
std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
- mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
+ mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
- mOutput.editState().bounds = kDefaultDisplaySize;
+ mOutput->editState().bounds = kDefaultDisplaySize;
}
static const Rect kDefaultDisplaySize;
@@ -63,7 +63,7 @@
StrictMock<mock::CompositionEngine> mCompositionEngine;
mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
- impl::Output mOutput{mCompositionEngine};
+ std::shared_ptr<impl::Output> mOutput = impl::createOutput(mCompositionEngine);
};
const Rect OutputTest::kDefaultDisplaySize{100, 200};
@@ -77,14 +77,14 @@
EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
- EXPECT_TRUE(mOutput.isValid());
+ EXPECT_TRUE(mOutput->isValid());
// If we take away the required components, it is no longer valid.
- mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
+ mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
- EXPECT_FALSE(mOutput.isValid());
+ EXPECT_FALSE(mOutput->isValid());
}
/*
@@ -92,30 +92,30 @@
*/
TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
- mOutput.editState().isEnabled = true;
+ mOutput->editState().isEnabled = true;
- mOutput.setCompositionEnabled(true);
+ mOutput->setCompositionEnabled(true);
- EXPECT_TRUE(mOutput.getState().isEnabled);
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
+ EXPECT_TRUE(mOutput->getState().isEnabled);
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
}
TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
- mOutput.editState().isEnabled = false;
+ mOutput->editState().isEnabled = false;
- mOutput.setCompositionEnabled(true);
+ mOutput->setCompositionEnabled(true);
- EXPECT_TRUE(mOutput.getState().isEnabled);
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
+ EXPECT_TRUE(mOutput->getState().isEnabled);
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
}
TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
- mOutput.editState().isEnabled = true;
+ mOutput->editState().isEnabled = true;
- mOutput.setCompositionEnabled(false);
+ mOutput->setCompositionEnabled(false);
- EXPECT_FALSE(mOutput.getState().isEnabled);
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
+ EXPECT_FALSE(mOutput->getState().isEnabled);
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
}
/*
@@ -130,14 +130,14 @@
const Rect scissor{9, 10, 11, 12};
const bool needsFiltering = true;
- mOutput.setProjection(transform, orientation, frame, viewport, scissor, needsFiltering);
+ mOutput->setProjection(transform, orientation, frame, viewport, scissor, needsFiltering);
- EXPECT_THAT(mOutput.getState().transform, TransformEq(transform));
- EXPECT_EQ(orientation, mOutput.getState().orientation);
- EXPECT_EQ(frame, mOutput.getState().frame);
- EXPECT_EQ(viewport, mOutput.getState().viewport);
- EXPECT_EQ(scissor, mOutput.getState().scissor);
- EXPECT_EQ(needsFiltering, mOutput.getState().needsFiltering);
+ EXPECT_THAT(mOutput->getState().transform, TransformEq(transform));
+ EXPECT_EQ(orientation, mOutput->getState().orientation);
+ EXPECT_EQ(frame, mOutput->getState().frame);
+ EXPECT_EQ(viewport, mOutput->getState().viewport);
+ EXPECT_EQ(scissor, mOutput->getState().scissor);
+ EXPECT_EQ(needsFiltering, mOutput->getState().needsFiltering);
}
/*
@@ -150,11 +150,11 @@
EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
- mOutput.setBounds(displaySize);
+ mOutput->setBounds(displaySize);
- EXPECT_EQ(Rect(displaySize), mOutput.getState().bounds);
+ EXPECT_EQ(Rect(displaySize), mOutput->getState().bounds);
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
}
/*
@@ -163,12 +163,12 @@
TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
const uint32_t layerStack = 123u;
- mOutput.setLayerStackFilter(layerStack, true);
+ mOutput->setLayerStackFilter(layerStack, true);
- EXPECT_TRUE(mOutput.getState().layerStackInternal);
- EXPECT_EQ(layerStack, mOutput.getState().layerStackId);
+ EXPECT_TRUE(mOutput->getState().layerStackInternal);
+ EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
}
/*
@@ -176,84 +176,84 @@
*/
TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
- mOutput.editState().colorTransformMatrix = kIdentity;
+ mOutput->editState().colorTransformMatrix = kIdentity;
// If no colorTransformMatrix is set the update should be skipped.
CompositionRefreshArgs refreshArgs;
refreshArgs.colorTransformMatrix = std::nullopt;
- mOutput.setColorTransform(refreshArgs);
+ mOutput->setColorTransform(refreshArgs);
// The internal state should be unchanged
- EXPECT_EQ(kIdentity, mOutput.getState().colorTransformMatrix);
+ EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
// No dirty region should be set
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
}
TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
- mOutput.editState().colorTransformMatrix = kIdentity;
+ mOutput->editState().colorTransformMatrix = kIdentity;
// Attempting to set the same colorTransformMatrix that is already set should
// also skip the update.
CompositionRefreshArgs refreshArgs;
refreshArgs.colorTransformMatrix = kIdentity;
- mOutput.setColorTransform(refreshArgs);
+ mOutput->setColorTransform(refreshArgs);
// The internal state should be unchanged
- EXPECT_EQ(kIdentity, mOutput.getState().colorTransformMatrix);
+ EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
// No dirty region should be set
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
}
TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
- mOutput.editState().colorTransformMatrix = kNonIdentityHalf;
+ mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
// Setting a different colorTransformMatrix should perform the update.
CompositionRefreshArgs refreshArgs;
refreshArgs.colorTransformMatrix = kIdentity;
- mOutput.setColorTransform(refreshArgs);
+ mOutput->setColorTransform(refreshArgs);
// The internal state should have been updated
- EXPECT_EQ(kIdentity, mOutput.getState().colorTransformMatrix);
+ EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
// The dirtyRegion should be set to the full display size
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
}
TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
- mOutput.editState().colorTransformMatrix = kIdentity;
+ mOutput->editState().colorTransformMatrix = kIdentity;
// Setting a different colorTransformMatrix should perform the update.
CompositionRefreshArgs refreshArgs;
refreshArgs.colorTransformMatrix = kNonIdentityHalf;
- mOutput.setColorTransform(refreshArgs);
+ mOutput->setColorTransform(refreshArgs);
// The internal state should have been updated
- EXPECT_EQ(kNonIdentityHalf, mOutput.getState().colorTransformMatrix);
+ EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
// The dirtyRegion should be set to the full display size
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
}
TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
- mOutput.editState().colorTransformMatrix = kNonIdentityHalf;
+ mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
// Setting a different colorTransformMatrix should perform the update.
CompositionRefreshArgs refreshArgs;
refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
- mOutput.setColorTransform(refreshArgs);
+ mOutput->setColorTransform(refreshArgs);
// The internal state should have been updated
- EXPECT_EQ(kNonIdentityQuarter, mOutput.getState().colorTransformMatrix);
+ EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
// The dirtyRegion should be set to the full display size
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
}
/*
@@ -269,16 +269,16 @@
.WillOnce(Return(ui::Dataspace::UNKNOWN));
EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
- mOutput.setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
- ui::RenderIntent::TONE_MAP_COLORIMETRIC,
- ui::Dataspace::UNKNOWN});
+ mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
+ ui::RenderIntent::TONE_MAP_COLORIMETRIC,
+ ui::Dataspace::UNKNOWN});
- EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput.getState().colorMode);
- EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput.getState().dataspace);
- EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput.getState().renderIntent);
- EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput.getState().targetDataspace);
+ EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
+ EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
+ EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
+ EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
}
TEST_F(OutputTest, setColorModeDoesNothingIfNoChange) {
@@ -289,16 +289,16 @@
ui::Dataspace::UNKNOWN))
.WillOnce(Return(ui::Dataspace::UNKNOWN));
- mOutput.editState().colorMode = ui::ColorMode::DISPLAY_P3;
- mOutput.editState().dataspace = ui::Dataspace::DISPLAY_P3;
- mOutput.editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
- mOutput.editState().targetDataspace = ui::Dataspace::UNKNOWN;
+ mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
+ mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
+ mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
+ mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
- mOutput.setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
- ui::RenderIntent::TONE_MAP_COLORIMETRIC,
- ui::Dataspace::UNKNOWN});
+ mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
+ ui::RenderIntent::TONE_MAP_COLORIMETRIC,
+ ui::Dataspace::UNKNOWN});
- EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
+ EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
}
/*
@@ -311,9 +311,9 @@
mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
- mOutput.setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
+ mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
- EXPECT_EQ(Rect(newDisplaySize), mOutput.getState().bounds);
+ EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().bounds);
}
/*
@@ -322,11 +322,11 @@
TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
const Rect viewport{100, 200};
- mOutput.editState().viewport = viewport;
- mOutput.editState().dirtyRegion.set(50, 300);
+ mOutput->editState().viewport = viewport;
+ mOutput->editState().dirtyRegion.set(50, 300);
{
- Region result = mOutput.getDirtyRegion(true);
+ Region result = mOutput->getDirtyRegion(true);
EXPECT_THAT(result, RegionEq(Region(viewport)));
}
@@ -334,11 +334,11 @@
TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
const Rect viewport{100, 200};
- mOutput.editState().viewport = viewport;
- mOutput.editState().dirtyRegion.set(50, 300);
+ mOutput->editState().viewport = viewport;
+ mOutput->editState().dirtyRegion.set(50, 300);
{
- Region result = mOutput.getDirtyRegion(false);
+ Region result = mOutput->getDirtyRegion(false);
// The dirtyRegion should be clipped to the display bounds.
EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
@@ -354,26 +354,26 @@
const uint32_t layerStack2 = 456u;
// If the output accepts layerStack1 and internal-only layers....
- mOutput.setLayerStackFilter(layerStack1, true);
+ 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));
+ 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));
- EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, true));
- EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, false));
+ EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
+ EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
+ EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
+ EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
// If the output accepts layerStack21 but not internal-only layers...
- mOutput.setLayerStackFilter(layerStack1, false);
+ mOutput->setLayerStackFilter(layerStack1, false);
// Only non-internal layers with layerStack1 belong to it.
- EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, false));
- EXPECT_FALSE(mOutput.belongsInOutput(layerStack1, true));
- EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, true));
- EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, false));
+ EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
+ EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
+ EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
+ EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
}
TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
@@ -386,59 +386,59 @@
const uint32_t layerStack2 = 456u;
// If the output accepts layerStack1 and internal-only layers....
- mOutput.setLayerStackFilter(layerStack1, true);
+ mOutput->setLayerStackFilter(layerStack1, true);
// A null layer pointer does not belong to the output
- EXPECT_FALSE(mOutput.belongsInOutput(nullptr));
+ EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
// A layer with no layerStack does not belong to it, internal-only or not.
layerFEState.layerStackId = std::nullopt;
layerFEState.internalOnly = false;
- EXPECT_FALSE(mOutput.belongsInOutput(&layer));
+ EXPECT_FALSE(mOutput->belongsInOutput(&layer));
layerFEState.layerStackId = std::nullopt;
layerFEState.internalOnly = true;
- EXPECT_FALSE(mOutput.belongsInOutput(&layer));
+ EXPECT_FALSE(mOutput->belongsInOutput(&layer));
// Any layer with layerStack1 belongs to it, internal-only or not.
layerFEState.layerStackId = layerStack1;
layerFEState.internalOnly = false;
- EXPECT_TRUE(mOutput.belongsInOutput(&layer));
+ EXPECT_TRUE(mOutput->belongsInOutput(&layer));
layerFEState.layerStackId = layerStack1;
layerFEState.internalOnly = true;
- EXPECT_TRUE(mOutput.belongsInOutput(&layer));
+ EXPECT_TRUE(mOutput->belongsInOutput(&layer));
layerFEState.layerStackId = layerStack2;
layerFEState.internalOnly = true;
- EXPECT_FALSE(mOutput.belongsInOutput(&layer));
+ EXPECT_FALSE(mOutput->belongsInOutput(&layer));
layerFEState.layerStackId = layerStack2;
layerFEState.internalOnly = false;
- EXPECT_FALSE(mOutput.belongsInOutput(&layer));
+ EXPECT_FALSE(mOutput->belongsInOutput(&layer));
// If the output accepts layerStack1 but not internal-only layers...
- mOutput.setLayerStackFilter(layerStack1, false);
+ mOutput->setLayerStackFilter(layerStack1, false);
// A null layer pointer does not belong to the output
- EXPECT_FALSE(mOutput.belongsInOutput(nullptr));
+ EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
// Only non-internal layers with layerStack1 belong to it.
layerFEState.layerStackId = layerStack1;
layerFEState.internalOnly = false;
- EXPECT_TRUE(mOutput.belongsInOutput(&layer));
+ EXPECT_TRUE(mOutput->belongsInOutput(&layer));
layerFEState.layerStackId = layerStack1;
layerFEState.internalOnly = true;
- EXPECT_FALSE(mOutput.belongsInOutput(&layer));
+ EXPECT_FALSE(mOutput->belongsInOutput(&layer));
layerFEState.layerStackId = layerStack2;
layerFEState.internalOnly = true;
- EXPECT_FALSE(mOutput.belongsInOutput(&layer));
+ EXPECT_FALSE(mOutput->belongsInOutput(&layer));
layerFEState.layerStackId = layerStack2;
layerFEState.internalOnly = false;
- EXPECT_FALSE(mOutput.belongsInOutput(&layer));
+ EXPECT_FALSE(mOutput->belongsInOutput(&layer));
}
/*
@@ -453,71 +453,24 @@
outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer1));
outputLayers.emplace_back(nullptr);
outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer2));
- mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
+ mOutput->setOutputLayersOrderedByZ(std::move(outputLayers));
StrictMock<mock::Layer> layer;
StrictMock<mock::Layer> otherLayer;
// If the input layer matches the first OutputLayer, it will be returned.
EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(layer));
- EXPECT_EQ(outputLayer1, mOutput.getOutputLayerForLayer(&layer));
+ EXPECT_EQ(outputLayer1, mOutput->getOutputLayerForLayer(&layer));
// If the input layer matches the second OutputLayer, it will be returned.
EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(layer));
- EXPECT_EQ(outputLayer2, mOutput.getOutputLayerForLayer(&layer));
+ EXPECT_EQ(outputLayer2, mOutput->getOutputLayerForLayer(&layer));
// If the input layer does not match an output layer, null will be returned.
EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(otherLayer));
- EXPECT_EQ(nullptr, mOutput.getOutputLayerForLayer(&layer));
-}
-
-/*
- * Output::getOrCreateOutputLayer()
- */
-
-TEST_F(OutputTest, getOrCreateOutputLayerWorks) {
- mock::OutputLayer* existingOutputLayer = new StrictMock<mock::OutputLayer>();
-
- Output::OutputLayers outputLayers;
- outputLayers.emplace_back(nullptr);
- outputLayers.emplace_back(std::unique_ptr<OutputLayer>(existingOutputLayer));
- mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
-
- std::shared_ptr<mock::Layer> layer{new StrictMock<mock::Layer>()};
- sp<LayerFE> layerFE{new StrictMock<mock::LayerFE>()};
-
- StrictMock<mock::Layer> otherLayer;
-
- {
- // 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(layer, layerFE);
- EXPECT_NE(existingOutputLayer, result.get());
- EXPECT_TRUE(result.get() != nullptr);
- EXPECT_EQ(layer.get(), &result->getLayer());
- EXPECT_EQ(layerFE.get(), &result->getLayerFE());
-
- // The entries in the ordered array should be unchanged.
- auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
- EXPECT_EQ(nullptr, outputLayers[0].get());
- EXPECT_EQ(existingOutputLayer, outputLayers[1].get());
- }
-
- {
- // 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(layer, layerFE);
- EXPECT_EQ(existingOutputLayer, result.get());
-
- // The corresponding entry in the ordered array should be cleared.
- auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
- EXPECT_EQ(nullptr, outputLayers[0].get());
- EXPECT_EQ(nullptr, outputLayers[1].get());
- }
+ EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(&layer));
}
/*
@@ -526,12 +479,19 @@
struct OutputPrepareFrameTest : public testing::Test {
struct OutputPartialMock : public impl::Output {
- OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
- : impl::Output(compositionEngine) {}
-
// Sets up the helper functions called by prepareFrame to use a mock
// implementations.
MOCK_METHOD0(chooseCompositionStrategy, void());
+
+ // compositionengine::Output overrides
+ const OutputCompositionState& getState() const override { return mState; }
+ OutputCompositionState& editState() override { return mState; }
+
+ // These need implementations though are not expected to be called.
+ MOCK_CONST_METHOD1(dumpState, void(std::string&));
+ MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
+
+ impl::OutputCompositionState mState;
};
OutputPrepareFrameTest() {
@@ -543,7 +503,7 @@
StrictMock<mock::CompositionEngine> mCompositionEngine;
mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
- StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
+ StrictMock<OutputPartialMock> mOutput;
};
TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
@@ -566,16 +526,16 @@
// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
// base chooseCompositionStrategy() is invoked.
TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
- mOutput.editState().isEnabled = true;
- mOutput.editState().usesClientComposition = false;
- mOutput.editState().usesDeviceComposition = true;
+ mOutput->editState().isEnabled = true;
+ mOutput->editState().usesClientComposition = false;
+ mOutput->editState().usesDeviceComposition = true;
EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
- mOutput.prepareFrame();
+ mOutput->prepareFrame();
- EXPECT_TRUE(mOutput.getState().usesClientComposition);
- EXPECT_FALSE(mOutput.getState().usesDeviceComposition);
+ EXPECT_TRUE(mOutput->getState().usesClientComposition);
+ EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
}
/*
@@ -592,9 +552,6 @@
static const mat4 kDefaultColorTransformMat;
struct OutputPartialMock : public impl::Output {
- OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
- : impl::Output(compositionEngine) {}
-
// Sets up the helper functions called by composeSurfaces to use a mock
// implementations.
MOCK_CONST_METHOD0(getSkipColorTransform, bool());
@@ -603,6 +560,16 @@
MOCK_METHOD2(appendRegionFlashRequests,
void(const Region&, std::vector<renderengine::LayerSettings>&));
MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
+
+ // compositionengine::Output overrides
+ const OutputCompositionState& getState() const override { return mState; }
+ OutputCompositionState& editState() override { return mState; }
+
+ // These need implementations though are not expected to be called.
+ MOCK_CONST_METHOD1(dumpState, void(std::string&));
+ MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
+
+ impl::OutputCompositionState mState;
};
OutputComposeSurfacesTest() {
@@ -627,6 +594,7 @@
mOutput.editState().usesClientComposition = true;
mOutput.editState().usesDeviceComposition = false;
+ EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
}
@@ -636,7 +604,7 @@
mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
mock::OutputLayer* mOutputLayer1 = new StrictMock<mock::OutputLayer>();
mock::OutputLayer* mOutputLayer2 = new StrictMock<mock::OutputLayer>();
- StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
+ StrictMock<OutputPartialMock> mOutput;
sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
};
@@ -691,14 +659,22 @@
struct GenerateClientCompositionRequestsTest : public testing::Test {
struct OutputPartialMock : public impl::Output {
- OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
- : impl::Output(compositionEngine) {}
+ // compositionengine::Output overrides
std::vector<renderengine::LayerSettings> generateClientCompositionRequests(
bool supportsProtectedContent, Region& clearRegion) override {
return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
clearRegion);
}
+
+ const OutputCompositionState& getState() const override { return mState; }
+ OutputCompositionState& editState() override { return mState; }
+
+ // These need implementations though are not expected to be called.
+ MOCK_CONST_METHOD1(dumpState, void(std::string&));
+ MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
+
+ impl::OutputCompositionState mState;
};
GenerateClientCompositionRequestsTest() {
@@ -707,10 +683,9 @@
mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
}
- StrictMock<mock::CompositionEngine> mCompositionEngine;
mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
- StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
+ StrictMock<OutputPartialMock> mOutput;
};
// TODO(b/121291683): Add more unit test coverage for generateClientCompositionRequests
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 2ada86b..89123df 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -59,12 +59,13 @@
mSequenceId(args.sequenceId),
mDisplayInstallOrientation(args.displayInstallOrientation),
mCompositionDisplay{mFlinger->getCompositionEngine().createDisplay(
- compositionengine::DisplayCreationArgs{args.isSecure, args.isVirtual,
- args.displayId, args.powerAdvisor})},
+ compositionengine::DisplayCreationArgs{args.isVirtual, args.displayId,
+ args.powerAdvisor})},
mIsVirtual(args.isVirtual),
mOrientation(),
mActiveConfig(0),
mIsPrimary(args.isPrimary) {
+ mCompositionDisplay->editState().isSecure = args.isSecure;
mCompositionDisplay->createRenderSurface(
compositionengine::RenderSurfaceCreationArgs{ANativeWindow_getWidth(
args.nativeWindow.get()),
@@ -254,13 +255,17 @@
scissor = displayBounds;
}
+ uint32_t transformOrientation;
+
if (isPrimary()) {
sPrimaryDisplayOrientation = displayStateOrientationToTransformOrientation(orientation);
+ transformOrientation = displayStateOrientationToTransformOrientation(
+ (orientation + mDisplayInstallOrientation) % (DisplayState::eOrientation270 + 1));
+ } else {
+ transformOrientation = displayStateOrientationToTransformOrientation(orientation);
}
- getCompositionDisplay()->setProjection(globalTransform,
- displayStateOrientationToTransformOrientation(
- orientation),
+ getCompositionDisplay()->setProjection(globalTransform, transformOrientation,
frame, viewport, scissor, needsFiltering);
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 52a09b3..079bc66 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -899,6 +899,7 @@
}
setZOrderRelativeOf(nullptr);
}
+ mCurrentState.isRelativeOf = false;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -942,6 +943,7 @@
mCurrentState.sequence++;
mCurrentState.modified = true;
mCurrentState.z = relativeZ;
+ mCurrentState.isRelativeOf = true;
auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
if (oldZOrderRelativeOf != nullptr) {
@@ -1540,7 +1542,7 @@
bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) const {
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const State& state = useDrawing ? mDrawingState : mCurrentState;
- return state.zOrderRelativeOf != nullptr;
+ return state.isRelativeOf;
}
__attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::makeTraversalList(
@@ -1565,8 +1567,7 @@
}
for (const sp<Layer>& child : children) {
- const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
- if (childState.zOrderRelativeOf != nullptr) {
+ if (child->usingRelativeZ(stateSet)) {
continue;
}
traverse.add(child);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 96970ac..610df25 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -172,6 +172,7 @@
// If non-null, a Surface this Surface's Z-order is interpreted relative to.
wp<Layer> zOrderRelativeOf;
+ bool isRelativeOf{false};
// A list of surfaces whose Z-order is interpreted relative to ours.
SortedVector<wp<Layer>> zOrderRelatives;
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
index 8494524..8271fd9 100644
--- a/services/surfaceflinger/LayerVector.cpp
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -64,7 +64,7 @@
const auto& layer = (*this)[i];
auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
: layer->getDrawingState();
- if (state.zOrderRelativeOf != nullptr) {
+ if (state.isRelativeOf) {
continue;
}
layer->traverseInZOrder(stateSet, visitor);
@@ -76,7 +76,7 @@
const auto& layer = (*this)[i];
auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
: layer->getDrawingState();
- if (state.zOrderRelativeOf != nullptr) {
+ if (state.isRelativeOf) {
continue;
}
layer->traverseInReverseZOrder(stateSet, visitor);