Merge "Make batterystats logging readable" into pi-dev am: 36a2324a92
am: 8828fd1266
Change-Id: Ic81d28df2e6c6ec32b6ada4710f23287a13e0314
diff --git a/docs/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png b/docs/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png
index a02fd89..f739fa2 100644
--- a/docs/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png
+++ b/docs/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png
Binary files differ
diff --git a/docs/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png b/docs/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png
index c309ac5..4b45e3a 100644
--- a/docs/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png
+++ b/docs/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png
Binary files differ
diff --git a/docs/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png b/docs/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png
index 414fad4..748d1a2 100644
--- a/docs/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png
+++ b/docs/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png
Binary files differ
diff --git a/docs/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png b/docs/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png
index c147a87..6e436ba 100644
--- a/docs/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png
+++ b/docs/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png
Binary files differ
diff --git a/docs/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png b/docs/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png
index 4ce2125..9776874 100644
--- a/docs/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png
+++ b/docs/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png
Binary files differ
diff --git a/include/input/Input.h b/include/input/Input.h
index cfcafab..15c86eb 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -339,7 +339,7 @@
static const char* getLabel(int32_t keyCode);
static int32_t getKeyCodeFromLabel(const char* label);
-
+
void initialize(
int32_t deviceId,
int32_t source,
@@ -373,6 +373,10 @@
virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
+ inline int32_t getDisplayId() const { return mDisplayId; }
+
+ inline void setDisplayId(int32_t displayId) { mDisplayId = displayId; }
+
inline int32_t getAction() const { return mAction; }
inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; }
@@ -556,6 +560,7 @@
void initialize(
int32_t deviceId,
int32_t source,
+ int32_t displayId,
int32_t action,
int32_t actionButton,
int32_t flags,
@@ -609,6 +614,7 @@
static int32_t getAxisFromLabel(const char* label);
protected:
+ int32_t mDisplayId;
int32_t mAction;
int32_t mActionButton;
int32_t mFlags;
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 1ea2c2c..ee52661 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -64,7 +64,6 @@
nsecs_t eventTime __attribute__((aligned(8)));
int32_t deviceId;
int32_t source;
- int32_t displayId;
int32_t action;
int32_t flags;
int32_t keyCode;
@@ -305,7 +304,7 @@
* Other errors probably indicate that the channel is broken.
*/
status_t consume(InputEventFactoryInterface* factory, bool consumeBatches,
- nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent, int32_t* displayId);
+ nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
/* Sends a finished signal to the publisher to inform it that the message
* with the specified sequence number has finished being process and whether
@@ -460,10 +459,9 @@
Vector<SeqChain> mSeqChains;
status_t consumeBatch(InputEventFactoryInterface* factory,
- nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent, int32_t* displayId);
+ nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
status_t consumeSamples(InputEventFactoryInterface* factory,
- Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent,
- int32_t* displayId);
+ Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent);
void updateTouchState(InputMessage& msg);
void resampleTouchState(nsecs_t frameTime, MotionEvent* event,
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index a624663..db27e11 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -215,6 +215,7 @@
void MotionEvent::initialize(
int32_t deviceId,
int32_t source,
+ int32_t displayId,
int32_t action,
int32_t actionButton,
int32_t flags,
@@ -231,6 +232,7 @@
const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords) {
InputEvent::initialize(deviceId, source);
+ mDisplayId = displayId;
mAction = action;
mActionButton = actionButton;
mFlags = flags;
@@ -251,6 +253,7 @@
void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
InputEvent::initialize(other->mDeviceId, other->mSource);
+ mDisplayId = other->mDisplayId;
mAction = other->mAction;
mActionButton = other->mActionButton;
mFlags = other->mFlags;
@@ -431,6 +434,7 @@
mDeviceId = parcel->readInt32();
mSource = parcel->readInt32();
+ mDisplayId = parcel->readInt32();
mAction = parcel->readInt32();
mActionButton = parcel->readInt32();
mFlags = parcel->readInt32();
@@ -480,6 +484,7 @@
parcel->writeInt32(mDeviceId);
parcel->writeInt32(mSource);
+ parcel->writeInt32(mDisplayId);
parcel->writeInt32(mAction);
parcel->writeInt32(mActionButton);
parcel->writeInt32(mFlags);
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index aa0bf17..f1c3fea 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -303,13 +303,15 @@
const PointerCoords* pointerCoords) {
#if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
+ "displayId=%" PRId32 ", "
"action=0x%x, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, "
"metaState=0x%x, buttonState=0x%x, xOffset=%f, yOffset=%f, "
"xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", "
"pointerCount=%" PRIu32,
mChannel->getName().c_str(), seq,
- deviceId, source, action, actionButton, flags, edgeFlags, metaState, buttonState,
- xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
+ deviceId, source, displayId, action, actionButton, flags, edgeFlags, metaState,
+ buttonState, xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime,
+ pointerCount);
#endif
if (!seq) {
@@ -398,8 +400,7 @@
}
status_t InputConsumer::consume(InputEventFactoryInterface* factory,
- bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent,
- int32_t* displayId) {
+ bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
#if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%" PRId64,
mChannel->getName().c_str(), consumeBatches ? "true" : "false", frameTime);
@@ -407,7 +408,6 @@
*outSeq = 0;
*outEvent = NULL;
- *displayId = -1; // Invalid display.
// Fetch the next input message.
// Loop until an event can be returned or no additional events are received.
@@ -422,7 +422,7 @@
if (result) {
// Consume the next batched event unless batches are being held for later.
if (consumeBatches || result != WOULD_BLOCK) {
- result = consumeBatch(factory, frameTime, outSeq, outEvent, displayId);
+ result = consumeBatch(factory, frameTime, outSeq, outEvent);
if (*outEvent) {
#if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
@@ -466,7 +466,7 @@
// the previous batch right now and defer the new message until later.
mMsgDeferred = true;
status_t result = consumeSamples(factory,
- batch, batch.samples.size(), outSeq, outEvent, displayId);
+ batch, batch.samples.size(), outSeq, outEvent);
mBatches.removeAt(batchIndex);
if (result) {
return result;
@@ -500,7 +500,7 @@
initializeMotionEvent(motionEvent, &mMsg);
*outSeq = mMsg.body.motion.seq;
*outEvent = motionEvent;
- *displayId = mMsg.body.motion.displayId;
+
#if DEBUG_TRANSPORT_ACTIONS
ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
mChannel->getName().c_str(), *outSeq);
@@ -518,14 +518,13 @@
}
status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
- nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent, int32_t* displayId) {
+ nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
status_t result;
for (size_t i = mBatches.size(); i > 0; ) {
i--;
Batch& batch = mBatches.editItemAt(i);
if (frameTime < 0) {
- result = consumeSamples(factory, batch, batch.samples.size(),
- outSeq, outEvent, displayId);
+ result = consumeSamples(factory, batch, batch.samples.size(), outSeq, outEvent);
mBatches.removeAt(i);
return result;
}
@@ -539,7 +538,7 @@
continue;
}
- result = consumeSamples(factory, batch, split + 1, outSeq, outEvent, displayId);
+ result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
const InputMessage* next;
if (batch.samples.isEmpty()) {
mBatches.removeAt(i);
@@ -557,7 +556,7 @@
}
status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
- Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent, int32_t* displayId) {
+ Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
MotionEvent* motionEvent = factory->createMotionEvent();
if (! motionEvent) return NO_MEMORY;
@@ -572,7 +571,6 @@
mSeqChains.push(seqChain);
addSample(motionEvent, &msg);
} else {
- *displayId = msg.body.motion.displayId;
initializeMotionEvent(motionEvent, &msg);
}
chain = msg.body.motion.seq;
@@ -950,6 +948,7 @@
event->initialize(
msg->body.motion.deviceId,
msg->body.motion.source,
+ msg->body.motion.displayId,
msg->body.motion.action,
msg->body.motion.actionButton,
msg->body.motion.flags,
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index c07a812..496158b 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -115,7 +115,7 @@
// Allow the default strategy to be overridden using a system property for debugging.
if (!strategy) {
- int length = property_get("debug.velocitytracker.strategy", value, NULL);
+ int length = property_get("persist.input.velocitytracker.strategy", value, NULL);
if (length > 0) {
strategy = value;
} else {
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index fd3b7c8..c4b8fe3 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -22,6 +22,9 @@
namespace android {
+// Default display id.
+static constexpr int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
+
class BaseTest : public testing::Test {
protected:
virtual void SetUp() { }
@@ -248,7 +251,7 @@
pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 26);
pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
- event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE, 0,
+ event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, AMOTION_EVENT_ACTION_MOVE, 0,
AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
@@ -301,6 +304,7 @@
ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
ASSERT_EQ(2, event->getDeviceId());
ASSERT_EQ(static_cast<int>(AINPUT_SOURCE_TOUCHSCREEN), event->getSource());
+ ASSERT_EQ(DISPLAY_ID, event->getDisplayId());
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
@@ -434,6 +438,11 @@
event.setSource(AINPUT_SOURCE_JOYSTICK);
ASSERT_EQ(static_cast<int>(AINPUT_SOURCE_JOYSTICK), event.getSource());
+ // Set displayId.
+ constexpr int32_t newDisplayId = 2;
+ event.setDisplayId(newDisplayId);
+ ASSERT_EQ(newDisplayId, event.getDisplayId());
+
// Set action.
event.setAction(AMOTION_EVENT_ACTION_CANCEL);
ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, event.getAction());
@@ -557,7 +566,7 @@
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
}
MotionEvent event;
- event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0, 0, 0,
+ event.initialize(0, 0, DISPLAY_ID, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords);
float originalRawX = 0 + 3;
float originalRawY = -RADIUS + 2;
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index c532241..6c4faed 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -89,9 +89,7 @@
uint32_t consumeSeq;
InputEvent* event;
- int32_t displayId;
- status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event,
- &displayId);
+ status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
ASSERT_EQ(OK, status)
<< "consumer consume should return OK";
@@ -131,23 +129,23 @@
void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() {
status_t status;
- const uint32_t seq = 15;
- const int32_t deviceId = 1;
- const int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
- int32_t displayId = 0;
- const int32_t action = AMOTION_EVENT_ACTION_MOVE;
- const int32_t actionButton = 0;
- const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
- const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
- const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
- const int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
- const float xOffset = -10;
- const float yOffset = -20;
- const float xPrecision = 0.25;
- const float yPrecision = 0.5;
- const nsecs_t downTime = 3;
- const size_t pointerCount = 3;
- const nsecs_t eventTime = 4;
+ constexpr uint32_t seq = 15;
+ constexpr int32_t deviceId = 1;
+ constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
+ constexpr int32_t displayId = 0;
+ constexpr int32_t action = AMOTION_EVENT_ACTION_MOVE;
+ constexpr int32_t actionButton = 0;
+ constexpr int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
+ constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
+ constexpr int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
+ constexpr int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
+ constexpr float xOffset = -10;
+ constexpr float yOffset = -20;
+ constexpr float xPrecision = 0.25;
+ constexpr float yPrecision = 0.5;
+ constexpr nsecs_t downTime = 3;
+ constexpr size_t pointerCount = 3;
+ constexpr nsecs_t eventTime = 4;
PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
for (size_t i = 0; i < pointerCount; i++) {
@@ -176,8 +174,7 @@
uint32_t consumeSeq;
InputEvent* event;
- status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event,
- &displayId);
+ status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
ASSERT_EQ(OK, status)
<< "consumer consume should return OK";
@@ -190,6 +187,7 @@
EXPECT_EQ(seq, consumeSeq);
EXPECT_EQ(deviceId, motionEvent->getDeviceId());
EXPECT_EQ(source, motionEvent->getSource());
+ EXPECT_EQ(displayId, motionEvent->getDisplayId());
EXPECT_EQ(action, motionEvent->getAction());
EXPECT_EQ(flags, motionEvent->getFlags());
EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp
index d19f3b8..77cce7a 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -38,14 +38,13 @@
CHECK_OFFSET(InputMessage::Body::Key, eventTime, 8);
CHECK_OFFSET(InputMessage::Body::Key, deviceId, 16);
CHECK_OFFSET(InputMessage::Body::Key, source, 20);
- CHECK_OFFSET(InputMessage::Body::Key, displayId, 24);
- CHECK_OFFSET(InputMessage::Body::Key, action, 28);
- CHECK_OFFSET(InputMessage::Body::Key, flags, 32);
- CHECK_OFFSET(InputMessage::Body::Key, keyCode, 36);
- CHECK_OFFSET(InputMessage::Body::Key, scanCode, 40);
- CHECK_OFFSET(InputMessage::Body::Key, metaState, 44);
- CHECK_OFFSET(InputMessage::Body::Key, repeatCount, 48);
- CHECK_OFFSET(InputMessage::Body::Key, downTime, 56);
+ CHECK_OFFSET(InputMessage::Body::Key, action, 24);
+ CHECK_OFFSET(InputMessage::Body::Key, flags, 28);
+ CHECK_OFFSET(InputMessage::Body::Key, keyCode, 32);
+ CHECK_OFFSET(InputMessage::Body::Key, scanCode, 36);
+ CHECK_OFFSET(InputMessage::Body::Key, metaState, 40);
+ CHECK_OFFSET(InputMessage::Body::Key, repeatCount, 44);
+ CHECK_OFFSET(InputMessage::Body::Key, downTime, 48);
CHECK_OFFSET(InputMessage::Body::Motion, seq, 0);
CHECK_OFFSET(InputMessage::Body::Motion, eventTime, 8);
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index 43b6012..5242a18 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -26,6 +26,8 @@
namespace android {
+constexpr int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT; // default display id
+
constexpr int32_t DEFAULT_POINTER_ID = 0; // pointer ID used for manually defined tests
// velocity must be in the range (1-tol)*EV <= velocity <= (1+tol)*EV
@@ -89,7 +91,7 @@
// First sample added separately with initialize
coords.setAxisValue(AMOTION_EVENT_AXIS_X, positions[0].x);
coords.setAxisValue(AMOTION_EVENT_AXIS_Y, positions[0].y);
- event->initialize(0, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE,
+ event->initialize(0, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, AMOTION_EVENT_ACTION_MOVE,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, positions[0].time, 1, properties, &coords);
for (size_t i = 1; i < numSamples; i++) {
diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp
index 1ae75fb..0144c25 100644
--- a/libs/vr/libdvr/tests/Android.bp
+++ b/libs/vr/libdvr/tests/Android.bp
@@ -12,28 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-shared_libraries = [
- "libbase",
- "libbinder",
- "libbufferhubqueue",
- "libcutils",
- "libgui",
- "liblog",
- "libhardware",
- "libui",
- "libutils",
- "libnativewindow",
- "libpdx_default_transport",
-]
-
-static_libraries = [
- "libdvr_static",
- "libchrome",
- "libdvrcommon",
- "libdisplay",
- "libbroadcastring",
-]
-
cc_test {
srcs: [
"dvr_display_manager-test.cpp",
@@ -41,8 +19,26 @@
],
header_libs: ["libdvr_headers"],
- static_libs: static_libraries,
- shared_libs: shared_libraries,
+ static_libs: [
+ "libdvr_static",
+ "libchrome",
+ "libdvrcommon",
+ "libdisplay",
+ "libbroadcastring",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "libbufferhubqueue",
+ "libcutils",
+ "libgui",
+ "liblog",
+ "libhardware",
+ "libui",
+ "libutils",
+ "libnativewindow",
+ "libpdx_default_transport",
+ ],
cflags: [
"-DLOG_TAG=\"dvr_api-test\"",
"-DTRACE=0",
@@ -52,3 +48,55 @@
],
name: "dvr_api-test",
}
+
+cc_test {
+ name: "dvr_buffer_queue-test",
+
+ // Includes the dvr_api.h header. Tests should only include "dvr_api.h",
+ // and shall only get access to |dvrGetApi|, as other symbols are hidden
+ // from the library.
+ include_dirs: ["frameworks/native/libs/vr/libdvr/include"],
+
+ srcs: ["dvr_buffer_queue-test.cpp"],
+
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+
+ cflags: [
+ "-DTRACE=0",
+ "-O2",
+ "-g",
+ ],
+
+ // DTS Should only link to NDK libraries.
+ sdk_version: "26",
+ stl: "c++_static",
+}
+
+cc_test {
+ name: "dvr_display-test",
+
+ include_dirs: [
+ "frameworks/native/libs/vr/libdvr/include",
+ "frameworks/native/libs/nativewindow/include",
+ ],
+
+ srcs: ["dvr_display-test.cpp"],
+
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+
+ cflags: [
+ "-DTRACE=0",
+ "-O2",
+ "-g",
+ ],
+
+ // DTS Should only link to NDK libraries.
+ sdk_version: "26",
+ stl: "c++_static",
+}
diff --git a/libs/vr/libdvr/tests/Android.mk b/libs/vr/libdvr/tests/Android.mk
deleted file mode 100644
index 0f3840d..0000000
--- a/libs/vr/libdvr/tests/Android.mk
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-# TODO(b/73133405): Currently, building cc_test against NDK using Android.bp
-# doesn't work well. Migrate to use Android.bp once b/73133405 gets fixed.
-
-include $(CLEAR_VARS)
-LOCAL_MODULE:= dvr_buffer_queue-test
-
-# Includes the dvr_api.h header. Tests should only include "dvr_api.h",
-# and shall only get access to |dvrGetApi|, as other symbols are hidden from the
-# library.
-LOCAL_C_INCLUDES := \
- frameworks/native/libs/vr/libdvr/include \
-
-LOCAL_SANITIZE := thread
-
-LOCAL_SRC_FILES := dvr_buffer_queue-test.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libandroid \
- liblog \
-
-LOCAL_CFLAGS := \
- -DTRACE=0 \
- -O2 \
- -g \
-
-# DTS Should only link to NDK libraries.
-LOCAL_SDK_VERSION := 26
-LOCAL_NDK_STL_VARIANT := c++_static
-
-include $(BUILD_NATIVE_TEST)
-
-
-include $(CLEAR_VARS)
-LOCAL_MODULE:= dvr_display-test
-
-LOCAL_C_INCLUDES := \
- frameworks/native/libs/vr/libdvr/include \
- frameworks/native/libs/nativewindow/include
-
-LOCAL_SANITIZE := thread
-
-LOCAL_SRC_FILES := dvr_display-test.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libandroid \
- liblog
-
-LOCAL_CFLAGS := \
- -DTRACE=0 \
- -O2 \
- -g
-
-# DTS Should only link to NDK libraries.
-LOCAL_SDK_VERSION := 26
-LOCAL_NDK_STL_VARIANT := c++_static
-
-include $(BUILD_NATIVE_TEST)
\ No newline at end of file
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index b022a20..36ea3ef 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -1042,38 +1042,6 @@
egl_tls_t::setContext(EGL_NO_CONTEXT);
}
} else {
-
- if (cur_c != NULL) {
- // Force return to current context for drivers that cannot handle errors
- EGLBoolean restore_result = EGL_FALSE;
- // get a reference to the old current objects
- ContextRef _c2(dp.get(), cur_c);
- SurfaceRef _d2(dp.get(), cur_c->draw);
- SurfaceRef _r2(dp.get(), cur_c->read);
-
- c = cur_c;
- impl_ctx = c->context;
- impl_draw = EGL_NO_SURFACE;
- if (cur_c->draw != EGL_NO_SURFACE) {
- d = get_surface(cur_c->draw);
- impl_draw = d->surface;
- }
- impl_read = EGL_NO_SURFACE;
- if (cur_c->read != EGL_NO_SURFACE) {
- r = get_surface(cur_c->read);
- impl_read = r->surface;
- }
- restore_result = dp->makeCurrent(c, cur_c,
- cur_c->draw, cur_c->read, cur_c->context,
- impl_draw, impl_read, impl_ctx);
- if (restore_result == EGL_TRUE) {
- _c2.acquire();
- _r2.acquire();
- _d2.acquire();
- } else {
- ALOGE("Could not restore original EGL context");
- }
- }
// this will ALOGE the error
egl_connection_t* const cnx = &gEGLImpl;
result = setError(cnx->egl.eglGetError(), (EGLBoolean)EGL_FALSE);
diff --git a/opengl/libs/tools/genfiles b/opengl/libs/tools/genfiles
deleted file mode 100755
index feef318..0000000
--- a/opengl/libs/tools/genfiles
+++ /dev/null
@@ -1,50 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2008 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Force a specific locale for sorting to avoid irrelevant differences
-# in the generated files that could hide real differences.
-export LC_ALL=POSIX
-
-./glapigen ../../include/GLES/gl.h > ../GLES_CM/gl_api.in
-./glapigen ../../include/GLES/glext.h > ../GLES_CM/glext_api.in
-./glapigen ../../include/GLES3/gl3.h > ../GLES2/gl2_api.in
-./glapigen ../../include/GLES2/gl2ext.h > ../GLES2/gl2ext_api.in
-
-./glentrygen ../../include/GLES/gl.h > /tmp/gl_entries.in
-./glentrygen ../../include/GLES/glext.h > /tmp/glext_entries.in
-./glentrygen ../../include/GLES3/gl3.h > /tmp/gl2_entries.in
-./glentrygen ../../include/GLES2/gl2ext.h > /tmp/gl2ext_entries.in
-
-# The awk command removes lines with the same function name as an earlier
-# line, even if the rest of the line differs. Although signatures of
-# functions with the same name should be the same, the different versions
-# have some irrelevant whitespace and parameter name differences.
-cat /tmp/gl_entries.in \
- /tmp/glext_entries.in \
- /tmp/gl2_entries.in \
- /tmp/gl2ext_entries.in \
- | sort -t, -k2 \
- | awk -F, '!_[$2]++' \
- > ../entries.in
-
-cat ../../include/GLES/gl.h \
- ../../include/GLES/glext.h \
- ../../include/GLES2/gl2ext.h \
- ../../include/GLES3/gl3.h \
- | ./glenumsgen \
- | sort \
- > ../enums.in
-
diff --git a/opengl/libs/tools/glapigen b/opengl/libs/tools/glapigen
deleted file mode 100755
index 4d8334f..0000000
--- a/opengl/libs/tools/glapigen
+++ /dev/null
@@ -1,76 +0,0 @@
-#! /usr/bin/perl
-#
-# Copyright (C) 2008 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-use strict;
-
-sub rtrim($)
-{
- my $string = shift;
- $string =~ s/\s+$//;
- return $string;
-}
-
-while (my $line = <>) {
- next if $line =~ /^\//;
- next if $line =~ /^#/;
- next if $line =~ /^\s*$/;
- if ($line !~ /^GL_API(CALL)?\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) {
- next;
- }
- my $type = rtrim($2);
- my $name = $3;
- my $args = $4;
-
- #printf("%s", $line);
-
- my $prefix = "";
- if ($name eq "glGetString") {
- $prefix = "__";
- }
-
- printf("%s API_ENTRY(%s%s)(%s)", $type, $prefix, $name, $args);
-
- printf(" {\n");
- if ($type eq "void") {
- printf(" CALL_GL_API(%s", $name);
- } else {
- printf(" CALL_GL_API_RETURN(%s", $name);
- }
- my @args = split ',', $args;
- my $len = scalar(@args);
- for (my $num = 0; $num < $len; $num++) {
- if ($args[$num] ne "void") {
- print ", ";
- #
- # extract the name from the parameter
- # type name
- # const type *name
- # type *name
- # type name[4]
- #
- if ($args[$num] =~ /(\S+\s)+\**\s*([\w]+)/) {
- printf("%s", $2);
- }
- }
- }
- printf(");\n");
- printf("}\n");
-}
-
-
-
-
-
diff --git a/opengl/libs/tools/glentrygen b/opengl/libs/tools/glentrygen
deleted file mode 100755
index 170f041..0000000
--- a/opengl/libs/tools/glentrygen
+++ /dev/null
@@ -1,38 +0,0 @@
-#! /usr/bin/perl
-#
-# Copyright (C) 2008 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-use strict;
-
-sub rtrim($)
-{
- my $string = shift;
- $string =~ s/\s+$//;
- return $string;
-}
-
-while (my $line = <>) {
- next if $line =~ /^\//;
- next if $line =~ /^#/;
- next if $line =~ /^\s*$/;
- if ($line !~ /^GL_API(CALL)?\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) {
- next;
- }
- my $type = rtrim($2);
- my $name = $3;
- my $args = $4;
-
- printf("GL_ENTRY(%s, %s, %s)\n", $type, $name, $args);
-}
diff --git a/opengl/libs/tools/glenumsgen b/opengl/libs/tools/glenumsgen
deleted file mode 100755
index 2ae5fbf..0000000
--- a/opengl/libs/tools/glenumsgen
+++ /dev/null
@@ -1,38 +0,0 @@
-#! /usr/bin/perl
-#
-# Copyright (C) 2010 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-use strict;
-
-my %enumHash = ();
-
-while (my $line = <STDIN>) {
- next if $line =~ /^\//;
- # Skip bitfield definitions.
- next if $line =~ /_BIT(\d+_|\s+)/;
- if ($line !~ /^#define\s+(\S+)\s+(0x\S+)/) {
- next;
- }
- my $enumName = $1;
- my $enumValue = $2;
- next if exists($enumHash { $enumValue });
- $enumHash { $enumValue } = $enumName;
- printf("GL_ENUM(%s,%s)\n", $enumValue, $enumName);
-}
-
-
-
-
-
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 9a449fa..5c078d3 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -924,12 +924,13 @@
void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, policyFlags=0x%x, "
+ ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
+ ", policyFlags=0x%x, "
"action=0x%x, actionButton=0x%x, flags=0x%x, "
"metaState=0x%x, buttonState=0x%x,"
"edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
prefix,
- entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
+ entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
entry->action, entry->actionButton, entry->flags,
entry->metaState, entry->buttonState,
entry->edgeFlags, entry->xPrecision, entry->yPrecision,
@@ -2384,6 +2385,7 @@
originalMotionEntry->eventTime,
originalMotionEntry->deviceId,
originalMotionEntry->source,
+ originalMotionEntry->displayId,
originalMotionEntry->policyFlags,
action,
originalMotionEntry->actionButton,
@@ -2394,7 +2396,6 @@
originalMotionEntry->xPrecision,
originalMotionEntry->yPrecision,
originalMotionEntry->downTime,
- originalMotionEntry->displayId,
splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
if (originalMotionEntry->injectionState) {
@@ -2526,10 +2527,11 @@
void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
- ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, policyFlags=0x%x, "
+ ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
+ ", policyFlags=0x%x, "
"action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x,"
"edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
- args->eventTime, args->deviceId, args->source, args->policyFlags,
+ args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
for (uint32_t i = 0; i < args->pointerCount; i++) {
@@ -2573,7 +2575,8 @@
mLock.unlock();
MotionEvent event;
- event.initialize(args->deviceId, args->source, args->action, args->actionButton,
+ event.initialize(args->deviceId, args->source, args->displayId,
+ args->action, args->actionButton,
args->flags, args->edgeFlags, args->metaState, args->buttonState,
0, 0, args->xPrecision, args->yPrecision,
args->downTime, args->eventTime,
@@ -2589,11 +2592,10 @@
// Just enqueue a new motion event.
MotionEntry* newEntry = new MotionEntry(args->eventTime,
- args->deviceId, args->source, policyFlags,
+ args->deviceId, args->source, args->displayId, policyFlags,
args->action, args->actionButton, args->flags,
args->metaState, args->buttonState,
args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
- args->displayId,
args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);
needWake = enqueueInboundEventLocked(newEntry);
@@ -2642,14 +2644,13 @@
}
}
-int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t displayId,
+int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
uint32_t policyFlags) {
#if DEBUG_INBOUND_EVENT_DETAILS
ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
- "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x, displayId=%d",
- event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags,
- displayId);
+ "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
+ event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
#endif
nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
@@ -2717,12 +2718,13 @@
const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
firstInjectedEntry = new MotionEntry(*sampleEventTimes,
- motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+ motionEvent->getDeviceId(), motionEvent->getSource(), motionEvent->getDisplayId(),
+ policyFlags,
action, actionButton, motionEvent->getFlags(),
motionEvent->getMetaState(), motionEvent->getButtonState(),
motionEvent->getEdgeFlags(),
motionEvent->getXPrecision(), motionEvent->getYPrecision(),
- motionEvent->getDownTime(), displayId,
+ motionEvent->getDownTime(),
uint32_t(pointerCount), pointerProperties, samplePointerCoords,
motionEvent->getXOffset(), motionEvent->getYOffset());
lastInjectedEntry = firstInjectedEntry;
@@ -2730,12 +2732,13 @@
sampleEventTimes += 1;
samplePointerCoords += pointerCount;
MotionEntry* nextInjectedEntry = new MotionEntry(*sampleEventTimes,
- motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+ motionEvent->getDeviceId(), motionEvent->getSource(),
+ motionEvent->getDisplayId(), policyFlags,
action, actionButton, motionEvent->getFlags(),
motionEvent->getMetaState(), motionEvent->getButtonState(),
motionEvent->getEdgeFlags(),
motionEvent->getXPrecision(), motionEvent->getYPrecision(),
- motionEvent->getDownTime(), displayId,
+ motionEvent->getDownTime(),
uint32_t(pointerCount), pointerProperties, samplePointerCoords,
motionEvent->getXOffset(), motionEvent->getYOffset());
lastInjectedEntry->next = nextInjectedEntry;
@@ -4026,18 +4029,19 @@
// --- InputDispatcher::MotionEntry ---
InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime, int32_t deviceId,
- uint32_t source, uint32_t policyFlags, int32_t action, int32_t actionButton,
+ uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
+ int32_t actionButton,
int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
float xPrecision, float yPrecision, nsecs_t downTime,
- int32_t displayId, uint32_t pointerCount,
+ uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xOffset, float yOffset) :
EventEntry(TYPE_MOTION, eventTime, policyFlags),
eventTime(eventTime),
- deviceId(deviceId), source(source), action(action), actionButton(actionButton),
- flags(flags), metaState(metaState), buttonState(buttonState),
+ deviceId(deviceId), source(source), displayId(displayId), action(action),
+ actionButton(actionButton), flags(flags), metaState(metaState), buttonState(buttonState),
edgeFlags(edgeFlags), xPrecision(xPrecision), yPrecision(yPrecision),
- downTime(downTime), displayId(displayId), pointerCount(pointerCount) {
+ downTime(downTime), pointerCount(pointerCount) {
for (uint32_t i = 0; i < pointerCount; i++) {
this->pointerProperties[i].copyFrom(pointerProperties[i]);
this->pointerCoords[i].copyFrom(pointerCoords[i]);
@@ -4051,11 +4055,12 @@
}
void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, action=%s, actionButton=0x%08x, "
- "flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, "
- "edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, displayId=%d, pointers=[",
- deviceId, source, motionActionToString(action).c_str(), actionButton, flags, metaState,
- buttonState, edgeFlags, xPrecision, yPrecision, displayId);
+ msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
+ ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, "
+ "edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, pointers=[",
+ deviceId, source, displayId, motionActionToString(action).c_str(), actionButton, flags,
+ metaState, buttonState, edgeFlags, xPrecision, yPrecision);
+
for (uint32_t i = 0; i < pointerCount; i++) {
if (i) {
msg += ", ";
@@ -4184,8 +4189,8 @@
}
#if DEBUG_OUTBOUND_EVENT_DETAILS
ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
- "actionMasked=%d",
- entry->deviceId, entry->source, actionMasked);
+ "displayId=%" PRId32 ", actionMasked=%d",
+ entry->deviceId, entry->source, entry->displayId, actionMasked);
#endif
return false;
}
@@ -4237,8 +4242,8 @@
}
#if DEBUG_OUTBOUND_EVENT_DETAILS
ALOGD("Dropping inconsistent motion pointer up/down or move event: "
- "deviceId=%d, source=%08x, actionMasked=%d",
- entry->deviceId, entry->source, actionMasked);
+ "deviceId=%d, source=%08x, displayId=%" PRId32 ", actionMasked=%d",
+ entry->deviceId, entry->source, entry->displayId, actionMasked);
#endif
return false;
}
@@ -4250,8 +4255,9 @@
return true;
}
#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x",
- entry->deviceId, entry->source);
+ ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x, "
+ "displayId=%" PRId32,
+ entry->deviceId, entry->source, entry->displayId);
#endif
return false;
}
@@ -4317,11 +4323,11 @@
MotionMemento& memento = mMotionMementos.editTop();
memento.deviceId = entry->deviceId;
memento.source = entry->source;
+ memento.displayId = entry->displayId;
memento.flags = flags;
memento.xPrecision = entry->xPrecision;
memento.yPrecision = entry->yPrecision;
memento.downTime = entry->downTime;
- memento.displayId = entry->displayId;
memento.setPointers(entry);
memento.hovering = hovering;
memento.policyFlags = entry->policyFlags;
@@ -4351,13 +4357,12 @@
const MotionMemento& memento = mMotionMementos.itemAt(i);
if (shouldCancelMotion(memento, options)) {
outEvents.push(new MotionEntry(currentTime,
- memento.deviceId, memento.source, memento.policyFlags,
+ memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
memento.hovering
? AMOTION_EVENT_ACTION_HOVER_EXIT
: AMOTION_EVENT_ACTION_CANCEL,
memento.flags, 0, 0, 0, 0,
memento.xPrecision, memento.yPrecision, memento.downTime,
- memento.displayId,
memento.pointerCount, memento.pointerProperties, memento.pointerCoords,
0, 0));
}
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 8da8450..5f76abe 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -299,7 +299,7 @@
*
* This method may be called on any thread (usually by the input manager).
*/
- virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId,
+ virtual int32_t injectInputEvent(const InputEvent* event,
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
uint32_t policyFlags) = 0;
@@ -383,7 +383,7 @@
virtual void notifySwitch(const NotifySwitchArgs* args);
virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
- virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId,
+ virtual int32_t injectInputEvent(const InputEvent* event,
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
uint32_t policyFlags);
@@ -508,6 +508,7 @@
nsecs_t eventTime;
int32_t deviceId;
uint32_t source;
+ int32_t displayId;
int32_t action;
int32_t actionButton;
int32_t flags;
@@ -517,17 +518,15 @@
float xPrecision;
float yPrecision;
nsecs_t downTime;
- int32_t displayId;
uint32_t pointerCount;
PointerProperties pointerProperties[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
MotionEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags,
+ int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags,
int32_t action, int32_t actionButton, int32_t flags,
int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- float xPrecision, float yPrecision, nsecs_t downTime,
- int32_t displayId, uint32_t pointerCount,
+ float xPrecision, float yPrecision, nsecs_t downTime, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xOffset, float yOffset);
virtual void appendDescription(std::string& msg) const;
@@ -765,11 +764,11 @@
struct MotionMemento {
int32_t deviceId;
uint32_t source;
+ int32_t displayId;
int32_t flags;
float xPrecision;
float yPrecision;
nsecs_t downTime;
- int32_t displayId;
uint32_t pointerCount;
PointerProperties pointerProperties[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index 520fea4..c36d7cf 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -67,16 +67,17 @@
// --- NotifyMotionArgs ---
NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags,
+ int32_t displayId, uint32_t policyFlags,
int32_t action, int32_t actionButton, int32_t flags, int32_t metaState,
- int32_t buttonState, int32_t edgeFlags, int32_t displayId, uint32_t deviceTimestamp,
+ int32_t buttonState, int32_t edgeFlags, uint32_t deviceTimestamp,
uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, nsecs_t downTime) :
- eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
+ eventTime(eventTime), deviceId(deviceId), source(source), displayId(displayId),
+ policyFlags(policyFlags),
action(action), actionButton(actionButton),
flags(flags), metaState(metaState), buttonState(buttonState),
- edgeFlags(edgeFlags), displayId(displayId), deviceTimestamp(deviceTimestamp),
+ edgeFlags(edgeFlags), deviceTimestamp(deviceTimestamp),
pointerCount(pointerCount),
xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
for (uint32_t i = 0; i < pointerCount; i++) {
@@ -87,10 +88,10 @@
NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
- policyFlags(other.policyFlags),
+ displayId(other.displayId), policyFlags(other.policyFlags),
action(other.action), actionButton(other.actionButton), flags(other.flags),
metaState(other.metaState), buttonState(other.buttonState),
- edgeFlags(other.edgeFlags), displayId(other.displayId),
+ edgeFlags(other.edgeFlags),
deviceTimestamp(other.deviceTimestamp), pointerCount(other.pointerCount),
xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
for (uint32_t i = 0; i < pointerCount; i++) {
diff --git a/services/inputflinger/InputListener.h b/services/inputflinger/InputListener.h
index 77afb34..d24be4c 100644
--- a/services/inputflinger/InputListener.h
+++ b/services/inputflinger/InputListener.h
@@ -82,6 +82,7 @@
nsecs_t eventTime;
int32_t deviceId;
uint32_t source;
+ int32_t displayId;
uint32_t policyFlags;
int32_t action;
int32_t actionButton;
@@ -89,7 +90,6 @@
int32_t metaState;
int32_t buttonState;
int32_t edgeFlags;
- int32_t displayId;
/**
* A timestamp in the input device's time base, not the platform's.
* The units are microseconds since the last reset.
@@ -106,10 +106,11 @@
inline NotifyMotionArgs() { }
- NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
+ NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
+ uint32_t policyFlags,
int32_t action, int32_t actionButton, int32_t flags,
int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, int32_t displayId, uint32_t deviceTimestamp, uint32_t pointerCount,
+ int32_t edgeFlags, uint32_t deviceTimestamp, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, nsecs_t downTime);
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index e0cd8a0..50229cb 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -2279,15 +2279,12 @@
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+ mOrientation = DISPLAY_ORIENTATION_0;
if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
DisplayViewport v;
if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, NULL, &v)) {
mOrientation = v.orientation;
- } else {
- mOrientation = DISPLAY_ORIENTATION_0;
}
- } else {
- mOrientation = DISPLAY_ORIENTATION_0;
}
}
}
@@ -2699,15 +2696,12 @@
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+ mOrientation = DISPLAY_ORIENTATION_0;
if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
DisplayViewport v;
if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, NULL, &v)) {
mOrientation = v.orientation;
- } else {
- mOrientation = DISPLAY_ORIENTATION_0;
}
- } else {
- mOrientation = DISPLAY_ORIENTATION_0;
}
bumpGeneration();
}
@@ -2894,19 +2888,19 @@
while (!released.isEmpty()) {
int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
buttonState &= ~actionButton;
- NotifyMotionArgs releaseArgs(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs releaseArgs(when, getDeviceId(), mSource, displayId, policyFlags,
AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&releaseArgs);
}
}
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, displayId, policyFlags,
motionEventAction, 0, 0, metaState, currentButtonState,
AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&args);
@@ -2915,10 +2909,10 @@
while (!pressed.isEmpty()) {
int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
buttonState |= actionButton;
- NotifyMotionArgs pressArgs(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs pressArgs(when, getDeviceId(), mSource, displayId, policyFlags,
AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&pressArgs);
}
@@ -2929,10 +2923,10 @@
// Send hover move after UP to tell the application that the mouse is hovering now.
if (motionEventAction == AMOTION_EVENT_ACTION_UP
&& (mSource == AINPUT_SOURCE_MOUSE)) {
- NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&hoverArgs);
}
@@ -2942,10 +2936,10 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, displayId, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, currentButtonState,
AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&scrollArgs);
}
@@ -3072,10 +3066,10 @@
int32_t metaState = mContext->getGlobalMetaState();
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_SCROLL, scroll * mScalingFactor);
- NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, displayId, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, 0,
AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
0, 0, 0);
getListener()->notifyMotion(&scrollArgs);
}
@@ -5413,10 +5407,10 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- mViewport.displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
0, 0, mPointerGesture.downTime);
getListener()->notifyMotion(&args);
}
@@ -6336,9 +6330,9 @@
mPointerSimple.down = false;
// Send up.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_UP, 0, 0, metaState, mLastRawState.buttonState, 0,
- mViewport.displayId, /* deviceTimestamp */ 0,
+ /* deviceTimestamp */ 0,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6349,9 +6343,9 @@
mPointerSimple.hovering = false;
// Send hover exit.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastRawState.buttonState, 0,
- mViewport.displayId, /* deviceTimestamp */ 0,
+ /* deviceTimestamp */ 0,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6364,9 +6358,9 @@
mPointerSimple.downTime = when;
// Send down.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_DOWN, 0, 0, metaState, mCurrentRawState.buttonState, 0,
- mViewport.displayId, /* deviceTimestamp */ 0,
+ /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6374,9 +6368,9 @@
}
// Send move.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, mCurrentRawState.buttonState, 0,
- mViewport.displayId, /* deviceTimestamp */ 0,
+ /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6388,10 +6382,10 @@
mPointerSimple.hovering = true;
// Send hover enter.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
- mViewport.displayId, /* deviceTimestamp */ 0,
+ /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6399,10 +6393,10 @@
}
// Send hover move.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
mCurrentRawState.buttonState, 0,
- mViewport.displayId, /* deviceTimestamp */ 0,
+ /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6421,9 +6415,9 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mSource, mViewport.displayId, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, mCurrentRawState.buttonState, 0,
- mViewport.displayId, /* deviceTimestamp */ 0,
+ /* deviceTimestamp */ 0,
1, &mPointerSimple.currentProperties, &pointerCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -6484,9 +6478,9 @@
}
}
- NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), source, mViewport.displayId, policyFlags,
action, actionButton, flags, metaState, buttonState, edgeFlags,
- mViewport.displayId, deviceTimestamp, pointerCount, pointerProperties, pointerCoords,
+ deviceTimestamp, pointerCount, pointerProperties, pointerCoords,
xPrecision, yPrecision, downTime);
getListener()->notifyMotion(&args);
}
@@ -7404,9 +7398,10 @@
// TODO: Use the input device configuration to control this behavior more finely.
uint32_t policyFlags = 0;
- NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, ADISPLAY_ID_NONE,
+ policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- ADISPLAY_ID_NONE, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
0, 0, 0);
getListener()->notifyMotion(&args);
}
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index aa6df24..9c72c77 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -28,7 +28,7 @@
static const int32_t DEVICE_ID = 1;
// An arbitrary display id.
-static const int32_t DISPLAY_ID = 0;
+static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
// An arbitrary injector pid / uid pair that has permission to inject events.
static const int32_t INJECTOR_PID = 999;
@@ -124,7 +124,7 @@
/*action*/ -1, 0,
AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject key events with undefined action.";
@@ -133,7 +133,7 @@
AKEY_EVENT_ACTION_MULTIPLE, 0,
AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject key events with ACTION_MULTIPLE.";
}
@@ -149,106 +149,106 @@
}
// Rejects undefined motion actions.
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
/*action*/ -1, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with undefined action.";
// Rejects pointer down with invalid index.
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer down index too large.";
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
AMOTION_EVENT_ACTION_POINTER_DOWN | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer down index too small.";
// Rejects pointer up with invalid index.
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer up index too large.";
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
AMOTION_EVENT_ACTION_POINTER_UP | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer up index too small.";
// Rejects motion events with invalid number of pointers.
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 0, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with 0 pointers.";
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with more than MAX_POINTERS pointers.";
// Rejects motion events with invalid pointer ids.
pointerProperties[0].id = -1;
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer ids less than 0.";
pointerProperties[0].id = MAX_POINTER_ID + 1;
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
// Rejects motion events with duplicate pointer ids.
pointerProperties[0].id = 1;
pointerProperties[1].id = 1;
- event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+ event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 2, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
- &event, DISPLAY_ID,
+ &event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with duplicate pointer ids.";
}
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 956844f..f4131d4 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -56,7 +56,7 @@
mService->cleanupConnection(this);
if (mEventCache != NULL) {
- delete mEventCache;
+ delete[] mEventCache;
}
mDestroyed = true;
}
@@ -224,7 +224,7 @@
wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
// filter out events not for this connection
- sensors_event_t* sanitizedBuffer = nullptr;
+ std::unique_ptr<sensors_event_t[]> sanitizedBuffer;
int count = 0;
Mutex::Autolock _l(mConnectionLock);
@@ -293,7 +293,8 @@
scratch = const_cast<sensors_event_t *>(buffer);
count = numEvents;
} else {
- scratch = sanitizedBuffer = new sensors_event_t[numEvents];
+ sanitizedBuffer.reset(new sensors_event_t[numEvents]);
+ scratch = sanitizedBuffer.get();
for (size_t i = 0; i < numEvents; i++) {
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
scratch[count++] = buffer[i++];
@@ -305,7 +306,6 @@
sendPendingFlushEventsLocked();
// Early return if there are no events for this connection.
if (count == 0) {
- delete sanitizedBuffer;
return status_t(NO_ERROR);
}
@@ -323,7 +323,6 @@
// the max cache size that is desired.
if (mCacheSize + count < computeMaxCacheSizeLocked()) {
reAllocateCacheLocked(scratch, count);
- delete sanitizedBuffer;
return status_t(NO_ERROR);
}
// Some events need to be dropped.
@@ -342,7 +341,6 @@
memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
numEventsDropped * sizeof(sensors_event_t));
}
- delete sanitizedBuffer;
return status_t(NO_ERROR);
}
@@ -384,7 +382,6 @@
// Add this file descriptor to the looper to get a callback when this fd is available for
// writing.
updateLooperRegistrationLocked(mService->getLooper());
- delete sanitizedBuffer;
return size;
}
@@ -394,7 +391,6 @@
}
#endif
- delete sanitizedBuffer;
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
@@ -415,7 +411,7 @@
ALOGD_IF(DEBUG_CONNECTIONS, "reAllocateCacheLocked maxCacheSize=%d %d", mMaxCacheSize,
new_cache_size);
- delete mEventCache;
+ delete[] mEventCache;
mEventCache = eventCache_new;
mCacheSize += count;
mMaxCacheSize = new_cache_size;
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 5b1e631..1f0562d 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -103,6 +103,7 @@
"FrameTracker.cpp",
"GpuService.cpp",
"Layer.cpp",
+ "LayerBE.cpp",
"LayerProtoHelper.cpp",
"LayerRejecter.cpp",
"LayerStats.cpp",
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 7fd9d01..250c2f1 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -98,15 +98,13 @@
}
bool BufferLayer::isProtected() const {
- const sp<GraphicBuffer>& buffer(getBE().compositionInfo.mBuffer);
- return (buffer != 0) &&
- (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+ const sp<GraphicBuffer>& buffer(mActiveBuffer);
+ return (buffer != 0) && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
}
bool BufferLayer::isVisible() const {
return !(isHiddenByPolicy()) && getAlpha() > 0.0f &&
- (getBE().compositionInfo.mBuffer != nullptr ||
- getBE().compositionInfo.hwc.sidebandStream != nullptr);
+ (mActiveBuffer != nullptr || getBE().compositionInfo.hwc.sidebandStream != nullptr);
}
bool BufferLayer::isFixedSize() const {
@@ -162,7 +160,7 @@
bool useIdentityTransform) const {
ATRACE_CALL();
- if (CC_UNLIKELY(getBE().compositionInfo.mBuffer == 0)) {
+ if (CC_UNLIKELY(mActiveBuffer == 0)) {
// the texture has not been created yet, this Layer has
// in fact never been drawn into. This happens frequently with
// SurfaceView because the WindowManager can't know when the client
@@ -240,8 +238,7 @@
}
// Set things up for texturing.
- mTexture.setDimensions(getBE().compositionInfo.mBuffer->getWidth(),
- getBE().compositionInfo.mBuffer->getHeight());
+ mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
mTexture.setFiltering(useFiltering);
mTexture.setMatrix(textureMatrix);
@@ -291,12 +288,10 @@
bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
if (mBufferLatched) {
Mutex::Autolock lock(mFrameEventHistoryMutex);
- mFrameEventHistory.addPreComposition(mCurrentFrameNumber,
- refreshStartTime);
+ mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime);
}
mRefreshPending = false;
- return mQueuedFrames > 0 || mSidebandStreamChanged ||
- mAutoRefresh;
+ return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
}
bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
const std::shared_ptr<FenceTime>& presentFence,
@@ -308,8 +303,8 @@
// Update mFrameEventHistory.
{
Mutex::Autolock lock(mFrameEventHistoryMutex);
- mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence,
- presentFence, compositorTiming);
+ mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence,
+ compositorTiming);
}
// Update mFrameTracker.
@@ -358,8 +353,7 @@
return;
}
- auto releaseFenceTime =
- std::make_shared<FenceTime>(mConsumer->getPrevFinalReleaseFence());
+ auto releaseFenceTime = std::make_shared<FenceTime>(mConsumer->getPrevFinalReleaseFence());
mReleaseTimeline.updateSignalTimes();
mReleaseTimeline.push(releaseFenceTime);
@@ -412,7 +406,7 @@
// Capture the old state of the layer for comparisons later
const State& s(getDrawingState());
const bool oldOpacity = isOpaque(s);
- sp<GraphicBuffer> oldBuffer = getBE().compositionInfo.mBuffer;
+ sp<GraphicBuffer> oldBuffer = mActiveBuffer;
if (!allTransactionsSignaled()) {
mFlinger->signalLayerUpdate();
@@ -425,12 +419,10 @@
// buffer mode.
bool queuedBuffer = false;
LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
- getProducerStickyTransform() != 0, mName.string(),
- mOverrideScalingMode, mFreezeGeometryUpdates);
- status_t updateResult =
- mConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync,
- &mAutoRefresh, &queuedBuffer,
- mLastFrameNumberReceived);
+ getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
+ mFreezeGeometryUpdates);
+ status_t updateResult = mConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, &mAutoRefresh,
+ &queuedBuffer, mLastFrameNumberReceived);
if (updateResult == BufferQueue::PRESENT_LATER) {
// Producer doesn't want buffer to be displayed yet. Signal a
// layer update so we check again at the next opportunity.
@@ -483,17 +475,16 @@
// Decrement the queued-frames count. Signal another event if we
// have more frames pending.
- if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) ||
- mAutoRefresh) {
+ if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) || mAutoRefresh) {
mFlinger->signalLayerUpdate();
}
// update the active buffer
- getBE().compositionInfo.mBuffer =
- mConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot);
- // replicated in LayerBE until FE/BE is ready to be synchronized
- mActiveBuffer = getBE().compositionInfo.mBuffer;
- if (getBE().compositionInfo.mBuffer == nullptr) {
+ mActiveBuffer = mConsumer->getCurrentBuffer(&mActiveBufferSlot);
+ getBE().compositionInfo.mBuffer = mActiveBuffer;
+ getBE().compositionInfo.mBufferSlot = mActiveBufferSlot;
+
+ if (mActiveBuffer == nullptr) {
// this can only happen if the very first buffer was rejected.
return outDirtyRegion;
}
@@ -540,8 +531,7 @@
Rect crop(mConsumer->getCurrentCrop());
const uint32_t transform(mConsumer->getCurrentTransform());
const uint32_t scalingMode(mConsumer->getCurrentScalingMode());
- if ((crop != mCurrentCrop) ||
- (transform != mCurrentTransform) ||
+ if ((crop != mCurrentCrop) || (transform != mCurrentTransform) ||
(scalingMode != mCurrentScalingMode)) {
mCurrentCrop = crop;
mCurrentTransform = transform;
@@ -550,15 +540,14 @@
}
if (oldBuffer != nullptr) {
- uint32_t bufWidth = getBE().compositionInfo.mBuffer->getWidth();
- uint32_t bufHeight = getBE().compositionInfo.mBuffer->getHeight();
- if (bufWidth != uint32_t(oldBuffer->width) ||
- bufHeight != uint32_t(oldBuffer->height)) {
+ uint32_t bufWidth = mActiveBuffer->getWidth();
+ uint32_t bufHeight = mActiveBuffer->getHeight();
+ if (bufWidth != uint32_t(oldBuffer->width) || bufHeight != uint32_t(oldBuffer->height)) {
recomputeVisibleRegions = true;
}
}
- mCurrentOpacity = getOpacityForFormat(getBE().compositionInfo.mBuffer->format);
+ mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
if (oldOpacity != isOpaque(s)) {
recomputeVisibleRegions = true;
}
@@ -606,14 +595,14 @@
auto hwcId = displayDevice->getHwcDisplayId();
auto& hwcInfo = getBE().mHwcLayers[hwcId];
auto& hwcLayer = hwcInfo.layer;
- auto error = hwcLayer->setVisibleRegion(visible);
+ auto error = (*hwcLayer)->setVisibleRegion(visible);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
visible.dump(LOG_TAG);
}
- error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
+ error = (*hwcLayer)->setSurfaceDamage(surfaceDamageRegion);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
@@ -624,7 +613,7 @@
if (getBE().compositionInfo.hwc.sidebandStream.get()) {
setCompositionType(hwcId, HWC2::Composition::Sideband);
ALOGV("[%s] Requesting Sideband composition", mName.string());
- error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
+ error = (*hwcLayer)->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
@@ -643,14 +632,14 @@
}
ALOGV("setPerFrameData: dataspace = %d", mDrawingState.dataSpace);
- error = hwcLayer->setDataspace(mDrawingState.dataSpace);
+ error = (*hwcLayer)->setDataspace(mDrawingState.dataSpace);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace,
to_string(error).c_str(), static_cast<int32_t>(error));
}
const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata();
- error = hwcLayer->setPerFrameMetadata(displayDevice->getSupportedPerFrameMetadata(), metadata);
+ error = (*hwcLayer)->setPerFrameMetadata(displayDevice->getSupportedPerFrameMetadata(), metadata);
if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
@@ -658,11 +647,11 @@
uint32_t hwcSlot = 0;
sp<GraphicBuffer> hwcBuffer;
- hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot,
- getBE().compositionInfo.mBuffer, &hwcSlot, &hwcBuffer);
+ getBE().mHwcLayers[hwcId].bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot,
+ &hwcBuffer);
auto acquireFence = mConsumer->getCurrentFence();
- error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
+ error = (*hwcLayer)->setBuffer(hwcSlot, hwcBuffer, acquireFence);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
@@ -673,7 +662,7 @@
bool BufferLayer::isOpaque(const Layer::State& s) const {
// if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
// layer's opaque flag.
- if ((getBE().compositionInfo.hwc.sidebandStream == nullptr) && (getBE().compositionInfo.mBuffer == nullptr)) {
+ if ((getBE().compositionInfo.hwc.sidebandStream == nullptr) && (mActiveBuffer == nullptr)) {
return false;
}
@@ -688,8 +677,7 @@
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer, true);
mProducer = new MonitoredProducer(producer, mFlinger, this);
- mConsumer = new BufferLayerConsumer(consumer,
- mFlinger->getRenderEngine(), mTextureName, this);
+ mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);
mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mConsumer->setContentsChangedListener(this);
mConsumer->setName(mName);
@@ -721,8 +709,7 @@
// Ensure that callbacks are handled in order
while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
- status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
- ms2ns(500));
+ status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
if (result != NO_ERROR) {
ALOGE("[%s] Timed out waiting on callback", mName.string());
}
@@ -745,8 +732,7 @@
// Ensure that callbacks are handled in order
while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
- status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
- ms2ns(500));
+ status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
if (result != NO_ERROR) {
ALOGE("[%s] Timed out waiting on callback", mName.string());
}
@@ -912,8 +898,7 @@
// able to be latched. To avoid this, grab this buffer anyway.
return true;
}
- return mQueueItems[0].mFenceTime->getSignalTime() !=
- Fence::SIGNAL_TIME_PENDING;
+ return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
}
uint32_t BufferLayer::getEffectiveScalingMode() const {
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index c87b669..09103a9 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -68,7 +68,7 @@
auto hwcId = displayDevice->getHwcDisplayId();
auto& hwcInfo = getBE().mHwcLayers[hwcId];
auto& hwcLayer = hwcInfo.layer;
- auto error = hwcLayer->setVisibleRegion(visible);
+ auto error = (*hwcLayer)->setVisibleRegion(visible);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
@@ -77,14 +77,14 @@
setCompositionType(hwcId, HWC2::Composition::SolidColor);
- error = hwcLayer->setDataspace(mDrawingState.dataSpace);
+ error = (*hwcLayer)->setDataspace(mDrawingState.dataSpace);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace,
to_string(error).c_str(), static_cast<int32_t>(error));
}
half4 color = getColor();
- error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
+ error = (*hwcLayer)->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
static_cast<uint8_t>(std::round(255.0f * color.g)),
static_cast<uint8_t>(std::round(255.0f * color.b)), 255});
if (error != HWC2::Error::None) {
@@ -93,7 +93,7 @@
}
// Clear out the transform, because it doesn't make sense absent a source buffer
- error = hwcLayer->setTransform(HWC2::Transform::None);
+ error = (*hwcLayer)->setTransform(HWC2::Transform::None);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(),
static_cast<int32_t>(error));
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 7c6302e..952a63f 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -149,8 +149,8 @@
return mDisplayHeight;
}
-void DisplayDevice::setDisplayName(const String8& displayName) {
- if (!displayName.isEmpty()) {
+void DisplayDevice::setDisplayName(const std::string& displayName) {
+ if (!displayName.empty()) {
// never override the name with an empty name
mDisplayName = displayName;
}
@@ -201,8 +201,7 @@
status_t result = mDisplaySurface->advanceFrame();
if (result != NO_ERROR) {
- ALOGE("[%s] failed pushing new frame to HWC: %d",
- mDisplayName.string(), result);
+ ALOGE("[%s] failed pushing new frame to HWC: %d", mDisplayName.c_str(), result);
}
}
@@ -452,7 +451,7 @@
}
mOrientation = orientation;
- if (mType == DisplayType::DISPLAY_PRIMARY) {
+ if (isPrimary()) {
uint32_t transform = 0;
switch (mOrientation) {
case DisplayState::eOrientationDefault:
@@ -481,7 +480,7 @@
void DisplayDevice::dump(String8& result) const {
const Transform& tr(mGlobalTransform);
ANativeWindow* const window = mNativeWindow.get();
- result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string());
+ result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.c_str());
result.appendFormat(" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p "
"(%d:%d:%d:%d), orient=%2d (type=%08x), "
"flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n",
@@ -508,18 +507,6 @@
result.append(surfaceDump);
}
-std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1);
-
-DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure)
- : type(type),
- layerStack(DisplayDevice::NO_LAYER_STACK),
- orientation(0),
- width(0),
- height(0),
- isSecure(isSecure)
-{
- viewport.makeInvalid();
- frame.makeInvalid();
-}
+std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
} // namespace android
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index df5d945..960fe8a 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -37,6 +37,7 @@
#include "RenderEngine/Surface.h"
#include <memory>
+#include <string>
struct ANativeWindow;
@@ -128,6 +129,7 @@
uint32_t getLayerStack() const { return mLayerStack; }
int32_t getDisplayType() const { return mType; }
bool isPrimary() const { return mType == DISPLAY_PRIMARY; }
+ bool isVirtual() const { return mType == DISPLAY_VIRTUAL; }
int32_t getHwcDisplayId() const { return mHwcDisplayId; }
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
@@ -152,8 +154,8 @@
}
inline Rect bounds() const { return getBounds(); }
- void setDisplayName(const String8& displayName);
- const String8& getDisplayName() const { return mDisplayName; }
+ void setDisplayName(const std::string& displayName);
+ const std::string& getDisplayName() const { return mDisplayName; }
bool makeCurrent() const;
void setViewportAndProjection() const;
@@ -208,7 +210,7 @@
int mDisplayWidth;
int mDisplayHeight;
mutable uint32_t mPageFlipCount;
- String8 mDisplayName;
+ std::string mDisplayName;
bool mIsSecure;
/*
@@ -266,15 +268,10 @@
};
struct DisplayDeviceState {
- DisplayDeviceState() = default;
- DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure);
-
bool isValid() const { return type >= 0; }
- bool isMainDisplay() const { return type == DisplayDevice::DISPLAY_PRIMARY; }
- bool isVirtualDisplay() const { return type >= DisplayDevice::DISPLAY_VIRTUAL; }
+ bool isVirtual() const { return type >= DisplayDevice::DISPLAY_VIRTUAL; }
- static std::atomic<int32_t> nextDisplayId;
- int32_t displayId = nextDisplayId++;
+ int32_t sequenceId = sNextSequenceId++;
DisplayDevice::DisplayType type = DisplayDevice::DISPLAY_ID_INVALID;
sp<IGraphicBufferProducer> surface;
uint32_t layerStack = DisplayDevice::NO_LAYER_STACK;
@@ -283,8 +280,11 @@
uint8_t orientation = 0;
uint32_t width = 0;
uint32_t height = 0;
- String8 displayName;
+ std::string displayName;
bool isSecure = false;
+
+private:
+ static std::atomic<int32_t> sNextSequenceId;
};
class DisplayRenderArea : public RenderArea {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
deleted file mode 100644
index fe7944f..0000000
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_SF_HWCOMPOSER_HWC1_H
-#define ANDROID_SF_HWCOMPOSER_HWC1_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <hardware/hwcomposer_defs.h>
-
-#include <system/graphics.h>
-
-#include <ui/Fence.h>
-
-#include <utils/BitSet.h>
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
-#include <utils/StrongPointer.h>
-#include <utils/Thread.h>
-#include <utils/Timers.h>
-#include <utils/Vector.h>
-
-extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
- const struct timespec *request,
- struct timespec *remain);
-
-struct hwc_composer_device_1;
-struct hwc_display_contents_1;
-struct hwc_layer_1;
-struct hwc_procs;
-struct framebuffer_device_t;
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-class Fence;
-class FloatRect;
-class GraphicBuffer;
-class NativeHandle;
-class Region;
-class String8;
-class SurfaceFlinger;
-
-class HWComposer
-{
-public:
- class EventHandler {
- friend class HWComposer;
- virtual void onVSyncReceived(
- HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
- virtual void onHotplugReceived(HWComposer* composer, int disp, bool connected) = 0;
- virtual void onInvalidateReceived(HWComposer* composer) = 0;
- protected:
- virtual ~EventHandler() {}
- };
-
- enum {
- NUM_BUILTIN_DISPLAYS = HWC_NUM_PHYSICAL_DISPLAY_TYPES,
- MAX_HWC_DISPLAYS = HWC_NUM_DISPLAY_TYPES,
- VIRTUAL_DISPLAY_ID_BASE = HWC_DISPLAY_VIRTUAL,
- };
-
- HWComposer(
- const sp<SurfaceFlinger>& flinger,
- EventHandler& handler);
-
- ~HWComposer();
-
- status_t initCheck() const;
-
- // Returns a display ID starting at VIRTUAL_DISPLAY_ID_BASE, this ID is to
- // be used with createWorkList (and all other methods requiring an ID
- // below).
- // IDs below NUM_BUILTIN_DISPLAYS are pre-defined and therefore are
- // always valid.
- // Returns -1 if an ID cannot be allocated
- int32_t allocateDisplayId();
-
- // Recycles the given virtual display ID and frees the associated worklist.
- // IDs below NUM_BUILTIN_DISPLAYS are not recycled.
- status_t freeDisplayId(int32_t id);
-
-
- // Asks the HAL what it can do
- status_t prepare();
-
- // commits the list
- status_t commit();
-
- // set power mode
- status_t setPowerMode(int disp, int mode);
-
- // set active config
- status_t setActiveConfig(int disp, int mode);
-
- // reset state when an external, non-virtual display is disconnected
- void disconnectDisplay(int disp);
-
- // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
- status_t createWorkList(int32_t id, size_t numLayers);
-
- bool supportsFramebufferTarget() const;
-
- // does this display have layers handled by HWC
- bool hasHwcComposition(int32_t id) const;
-
- // does this display have layers handled by GLES
- bool hasGlesComposition(int32_t id) const;
-
- // get the releaseFence file descriptor for a display's framebuffer layer.
- // the release fence is only valid after commit()
- sp<Fence> getAndResetReleaseFence(int32_t id);
-
- // needed forward declarations
- class LayerListIterator;
-
- // return the visual id to be used to find a suitable EGLConfig for
- // *ALL* displays.
- int getVisualID() const;
-
- // Forwarding to FB HAL for pre-HWC-1.1 code (see FramebufferSurface).
- int fbPost(int32_t id, const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf);
- int fbCompositionComplete();
- void fbDump(String8& result);
-
- // Set the output buffer and acquire fence for a virtual display.
- // Returns INVALID_OPERATION if id is not a virtual display.
- status_t setOutputBuffer(int32_t id, const sp<Fence>& acquireFence,
- const sp<GraphicBuffer>& buf);
-
- // Get the retire fence for the last committed frame. This fence will
- // signal when the h/w composer is completely finished with the frame.
- // For physical displays, it is no longer being displayed. For virtual
- // displays, writes to the output buffer are complete.
- sp<Fence> getLastRetireFence(int32_t id) const;
-
- status_t setCursorPositionAsync(int32_t id, const Rect &pos);
-
- /*
- * Interface to hardware composer's layers functionality.
- * This abstracts the HAL interface to layers which can evolve in
- * incompatible ways from one release to another.
- * The idea is that we could extend this interface as we add
- * features to h/w composer.
- */
- class HWCLayerInterface {
- protected:
- virtual ~HWCLayerInterface() { }
- public:
- virtual int32_t getCompositionType() const = 0;
- virtual uint32_t getHints() const = 0;
- virtual sp<Fence> getAndResetReleaseFence() = 0;
- virtual void setDefaultState() = 0;
- virtual void setSkip(bool skip) = 0;
- virtual void setIsCursorLayerHint(bool isCursor = true) = 0;
- virtual void setBlending(uint32_t blending) = 0;
- virtual void setTransform(uint32_t transform) = 0;
- virtual void setFrame(const Rect& frame) = 0;
- virtual void setCrop(const FloatRect& crop) = 0;
- virtual void setVisibleRegionScreen(const Region& reg) = 0;
- virtual void setSurfaceDamage(const Region& reg) = 0;
- virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0;
- virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
- virtual void setAcquireFenceFd(int fenceFd) = 0;
- virtual void setPlaneAlpha(uint8_t alpha) = 0;
- virtual void onDisplayed() = 0;
- };
-
- /*
- * Interface used to implement an iterator to a list
- * of HWCLayer.
- */
- class HWCLayer : public HWCLayerInterface {
- friend class LayerListIterator;
- // select the layer at the given index
- virtual status_t setLayer(size_t index) = 0;
- virtual HWCLayer* dup() = 0;
- static HWCLayer* copy(HWCLayer *rhs) {
- return rhs ? rhs->dup() : nullptr;
- }
- protected:
- virtual ~HWCLayer() { }
- };
-
- /*
- * Iterator through a HWCLayer list.
- * This behaves more or less like a forward iterator.
- */
- class LayerListIterator {
- friend class HWComposer;
- HWCLayer* const mLayerList;
- size_t mIndex;
-
- LayerListIterator() : mLayerList(nullptr), mIndex(0) { }
-
- LayerListIterator(HWCLayer* layer, size_t index)
- : mLayerList(layer), mIndex(index) { }
-
- // we don't allow assignment, because we don't need it for now
- LayerListIterator& operator = (const LayerListIterator& rhs);
-
- public:
- // copy operators
- LayerListIterator(const LayerListIterator& rhs)
- : mLayerList(HWCLayer::copy(rhs.mLayerList)), mIndex(rhs.mIndex) {
- }
-
- ~LayerListIterator() { delete mLayerList; }
-
- // pre-increment
- LayerListIterator& operator++() {
- mLayerList->setLayer(++mIndex);
- return *this;
- }
-
- // dereference
- HWCLayerInterface& operator * () { return *mLayerList; }
- HWCLayerInterface* operator -> () { return mLayerList; }
-
- // comparison
- bool operator == (const LayerListIterator& rhs) const {
- return mIndex == rhs.mIndex;
- }
- bool operator != (const LayerListIterator& rhs) const {
- return !operator==(rhs);
- }
- };
-
- // Returns an iterator to the beginning of the layer list
- LayerListIterator begin(int32_t id);
-
- // Returns an iterator to the end of the layer list
- LayerListIterator end(int32_t id);
-
-
- // Events handling ---------------------------------------------------------
-
- enum {
- EVENT_VSYNC = HWC_EVENT_VSYNC
- };
-
- void eventControl(int disp, int event, int enabled);
-
- struct DisplayConfig {
- uint32_t width;
- uint32_t height;
- float xdpi;
- float ydpi;
- nsecs_t refresh;
- android_color_mode_t colorMode;
- bool operator==(const DisplayConfig& rhs) const {
- return width == rhs.width &&
- height == rhs.height &&
- xdpi == rhs.xdpi &&
- ydpi == rhs.ydpi &&
- refresh == rhs.refresh &&
- colorMode == rhs.colorMode;
- }
- };
-
- // Query display parameters. Pass in a display index (e.g.
- // HWC_DISPLAY_PRIMARY).
- nsecs_t getRefreshTimestamp(int disp) const;
- sp<Fence> getDisplayFence(int disp) const;
- uint32_t getFormat(int disp) const;
- bool isConnected(int disp) const;
-
- // These return the values for the current config of a given display index.
- // To get the values for all configs, use getConfigs below.
- uint32_t getWidth(int disp) const;
- uint32_t getHeight(int disp) const;
- float getDpiX(int disp) const;
- float getDpiY(int disp) const;
- nsecs_t getRefreshPeriod(int disp) const;
- android_color_mode_t getColorMode(int disp) const;
-
- const Vector<DisplayConfig>& getConfigs(int disp) const;
- size_t getCurrentConfig(int disp) const;
-
- status_t setVirtualDisplayProperties(int32_t id, uint32_t w, uint32_t h,
- uint32_t format);
-
- // this class is only used to fake the VSync event on systems that don't
- // have it.
- class VSyncThread : public Thread {
- HWComposer& mHwc;
- mutable Mutex mLock;
- Condition mCondition;
- bool mEnabled;
- mutable nsecs_t mNextFakeVSync;
- nsecs_t mRefreshPeriod;
- virtual void onFirstRef();
- virtual bool threadLoop();
- public:
- VSyncThread(HWComposer& hwc);
- void setEnabled(bool enabled);
- };
-
- friend class VSyncThread;
-
- // for debugging ----------------------------------------------------------
- void dump(String8& out) const;
-
-private:
- void loadHwcModule();
- int loadFbHalModule();
-
- LayerListIterator getLayerIterator(int32_t id, size_t index);
-
- struct cb_context;
-
- static void hook_invalidate(const struct hwc_procs* procs);
- static void hook_vsync(const struct hwc_procs* procs, int disp,
- int64_t timestamp);
- static void hook_hotplug(const struct hwc_procs* procs, int disp,
- int connected);
-
- inline void invalidate();
- inline void vsync(int disp, int64_t timestamp);
- inline void hotplug(int disp, int connected);
-
- status_t queryDisplayProperties(int disp);
-
- status_t setFramebufferTarget(int32_t id,
- const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf);
-
- struct DisplayData {
- DisplayData();
- ~DisplayData();
- Vector<DisplayConfig> configs;
- size_t currentConfig;
- uint32_t format; // pixel format from FB hal, for pre-hwc-1.1
- bool connected;
- bool hasFbComp;
- bool hasOvComp;
- size_t capacity;
- hwc_display_contents_1* list;
- hwc_layer_1* framebufferTarget;
- buffer_handle_t fbTargetHandle;
- sp<Fence> lastRetireFence; // signals when the last set op retires
- sp<Fence> lastDisplayFence; // signals when the last set op takes
- // effect on screen
- buffer_handle_t outbufHandle;
- sp<Fence> outbufAcquireFence;
-
- // protected by mEventControlLock
- int32_t events;
-
- // We need to hold "copies" of these for memory management purposes. The
- // actual hwc_layer_1_t holds pointers to the memory within. Vector<>
- // internally doesn't copy the memory unless one of the copies is
- // modified.
- Vector<Region> visibleRegions;
- Vector<Region> surfaceDamageRegions;
- };
-
- sp<SurfaceFlinger> mFlinger;
- framebuffer_device_t* mFbDev;
- struct hwc_composer_device_1* mHwc;
- // invariant: mLists[0] != nullptr iff mHwc != nullptr
- // mLists[i>0] can be nullptr. that display is to be ignored
- struct hwc_display_contents_1* mLists[MAX_HWC_DISPLAYS];
- DisplayData mDisplayData[MAX_HWC_DISPLAYS];
- // protect mDisplayData from races between prepare and dump
- mutable Mutex mDisplayLock;
- size_t mNumDisplays;
-
- cb_context* mCBContext;
- EventHandler& mEventHandler;
- size_t mVSyncCounts[HWC_NUM_PHYSICAL_DISPLAY_TYPES];
- sp<VSyncThread> mVSyncThread;
- bool mDebugForceFakeVSync;
- BitSet32 mAllocatedDisplayIDs;
-
- // protected by mLock
- mutable Mutex mLock;
- mutable nsecs_t mLastHwVSync[HWC_NUM_PHYSICAL_DISPLAY_TYPES];
-
- // thread-safe
- mutable Mutex mEventControlLock;
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_SF_HWCOMPOSER_H
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 9a2817d..c111a27 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -32,11 +32,11 @@
// ---------------------------------------------------------------------------
#define VDS_LOGE(msg, ...) ALOGE("[%s] " msg, \
- mDisplayName.string(), ##__VA_ARGS__)
+ mDisplayName.c_str(), ##__VA_ARGS__)
#define VDS_LOGW_IF(cond, msg, ...) ALOGW_IF(cond, "[%s] " msg, \
- mDisplayName.string(), ##__VA_ARGS__)
+ mDisplayName.c_str(), ##__VA_ARGS__)
#define VDS_LOGV(msg, ...) ALOGV("[%s] " msg, \
- mDisplayName.string(), ##__VA_ARGS__)
+ mDisplayName.c_str(), ##__VA_ARGS__)
static const char* dbgCompositionTypeStr(DisplaySurface::CompositionType type) {
switch (type) {
@@ -52,7 +52,7 @@
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer,
- const String8& name)
+ const std::string& name)
: ConsumerBase(bqConsumer),
mHwc(hwc),
mDisplayId(dispId),
@@ -102,7 +102,7 @@
}
mOutputFormat = mDefaultOutputFormat;
- ConsumerBase::mName = String8::format("VDS: %s", mDisplayName.string());
+ ConsumerBase::mName = String8::format("VDS: %s", mDisplayName.c_str());
mConsumer->setConsumerName(ConsumerBase::mName);
mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight);
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 5c8acea..4bd4d0f 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
#define ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
+#include <string>
+
#include "DisplaySurface.h"
#include "HWComposerBufferCache.h"
@@ -77,7 +79,7 @@
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer,
- const String8& name);
+ const std::string& name);
//
// DisplaySurface interface
@@ -153,7 +155,7 @@
//
HWComposer& mHwc;
const int32_t mDisplayId;
- const String8 mDisplayName;
+ const std::string mDisplayName;
sp<IGraphicBufferProducer> mSource[2]; // indexed by SOURCE_*
uint32_t mDefaultOutputFormat;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index bbc974d..fc9f16b 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -63,11 +63,6 @@
namespace android {
-LayerBE::LayerBE()
- : mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) {
-}
-
-
int32_t Layer::sSequence = 1;
Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
@@ -98,7 +93,8 @@
mQueueItems(),
mLastFrameNumberReceived(0),
mAutoRefresh(false),
- mFreezeGeometryUpdates(false) {
+ mFreezeGeometryUpdates(false),
+ mBE{this, name.string()} {
mCurrentCrop.makeInvalid();
@@ -223,15 +219,14 @@
bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) {
LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.count(hwcId) != 0,
"Already have a layer for hwcId %d", hwcId);
- HWC2::Layer* layer = hwc->createLayer(hwcId);
+
+ std::shared_ptr<LayerContainer> layer(new LayerContainer(hwc, hwcId));
if (!layer) {
return false;
}
LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers[hwcId];
hwcInfo.hwc = hwc;
hwcInfo.layer = layer;
- layer->setLayerDestroyedListener(
- [this, hwcId](HWC2::Layer* /*layer*/) { getBE().mHwcLayers.erase(hwcId); });
return true;
}
@@ -242,11 +237,12 @@
auto& hwcInfo = getBE().mHwcLayers[hwcId];
LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer");
LOG_ALWAYS_FATAL_IF(hwcInfo.hwc == nullptr, "Missing HWComposer");
- hwcInfo.hwc->destroyLayer(hwcId, hwcInfo.layer);
- // The layer destroyed listener should have cleared the entry from
- // mHwcLayers. Verify that.
- LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.count(hwcId) != 0,
- "Stale layer entry in getBE().mHwcLayers");
+ hwcInfo.layer = nullptr;
+
+ if (getBE().mHwcLayers.count(hwcId) == 1) {
+ getBE().mHwcLayers.erase(hwcId);
+ }
+
return true;
}
@@ -505,7 +501,7 @@
blendMode =
mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
}
- auto error = hwcLayer->setBlendMode(blendMode);
+ auto error = (*hwcLayer)->setBlendMode(blendMode);
ALOGE_IF(error != HWC2::Error::None,
"[%s] Failed to set blend mode %s:"
" %s (%d)",
@@ -553,7 +549,7 @@
}
const Transform& tr(displayDevice->getTransform());
Rect transformedFrame = tr.transform(frame);
- error = hwcLayer->setDisplayFrame(transformedFrame);
+ error = (*hwcLayer)->setDisplayFrame(transformedFrame);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", mName.string(),
transformedFrame.left, transformedFrame.top, transformedFrame.right,
@@ -563,7 +559,7 @@
}
FloatRect sourceCrop = computeCrop(displayDevice);
- error = hwcLayer->setSourceCrop(sourceCrop);
+ error = (*hwcLayer)->setSourceCrop(sourceCrop);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
"%s (%d)",
@@ -574,13 +570,13 @@
}
float alpha = static_cast<float>(getAlpha());
- error = hwcLayer->setPlaneAlpha(alpha);
+ error = (*hwcLayer)->setPlaneAlpha(alpha);
ALOGE_IF(error != HWC2::Error::None,
"[%s] Failed to set plane alpha %.3f: "
"%s (%d)",
mName.string(), alpha, to_string(error).c_str(), static_cast<int32_t>(error));
- error = hwcLayer->setZOrder(z);
+ error = (*hwcLayer)->setZOrder(z);
ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z,
to_string(error).c_str(), static_cast<int32_t>(error));
@@ -595,7 +591,7 @@
}
}
- error = hwcLayer->setInfo(type, appId);
+ error = (*hwcLayer)->setInfo(type, appId);
ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(),
static_cast<int32_t>(error));
@@ -638,7 +634,7 @@
} else {
auto transform = static_cast<HWC2::Transform>(orientation);
hwcInfo.transform = transform;
- auto error = hwcLayer->setTransform(transform);
+ auto error = (*hwcLayer)->setTransform(transform);
ALOGE_IF(error != HWC2::Error::None,
"[%s] Failed to set transform %s: "
"%s (%d)",
@@ -691,7 +687,7 @@
auto& displayTransform(displayDevice->getTransform());
auto position = displayTransform.transform(frame);
- auto error = getBE().mHwcLayers[hwcId].layer->setCursorPosition(position.left,
+ auto error = (*getBE().mHwcLayers[hwcId].layer)->setCursorPosition(position.left,
position.top);
ALOGE_IF(error != HWC2::Error::None,
"[%s] Failed to set cursor position "
@@ -735,13 +731,13 @@
}
auto& hwcInfo = getBE().mHwcLayers[hwcId];
auto& hwcLayer = hwcInfo.layer;
- ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(), to_string(type).c_str(),
+ ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", (*hwcLayer)->getId(), to_string(type).c_str(),
static_cast<int>(callIntoHwc));
if (hwcInfo.compositionType != type) {
ALOGV(" actually setting");
hwcInfo.compositionType = type;
if (callIntoHwc) {
- auto error = hwcLayer->setCompositionType(type);
+ auto error = (*hwcLayer)->setCompositionType(type);
ALOGE_IF(error != HWC2::Error::None,
"[%s] Failed to set "
"composition type %s: %s (%d)",
@@ -1439,7 +1435,7 @@
info.mMatrix[1][0] = ds.active.transform[1][0];
info.mMatrix[1][1] = ds.active.transform[1][1];
{
- sp<const GraphicBuffer> buffer = getBE().compositionInfo.mBuffer;
+ sp<const GraphicBuffer> buffer = mActiveBuffer;
if (buffer != 0) {
info.mActiveBufferWidth = buffer->getWidth();
info.mActiveBufferHeight = buffer->getHeight();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index be3967b..d05a91b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -42,6 +42,7 @@
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
#include "Transform.h"
+#include "LayerBE.h"
#include <layerproto/LayerProtoHeader.h>
#include "DisplayHardware/HWComposer.h"
@@ -73,70 +74,6 @@
// ---------------------------------------------------------------------------
-struct CompositionInfo {
- HWC2::Composition compositionType;
- sp<GraphicBuffer> mBuffer = nullptr;
- int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
- struct {
- HWComposer* hwc;
- sp<Fence> fence;
- HWC2::BlendMode blendMode;
- Rect displayFrame;
- float alpha;
- FloatRect sourceCrop;
- HWC2::Transform transform;
- int z;
- int type;
- int appId;
- Region visibleRegion;
- Region surfaceDamage;
- sp<NativeHandle> sidebandStream;
- android_dataspace dataspace;
- hwc_color_t color;
- } hwc;
- struct {
- RE::RenderEngine* renderEngine;
- Mesh* mesh;
- } renderEngine;
-};
-
-class LayerBE {
-public:
- LayerBE();
-
- // The mesh used to draw the layer in GLES composition mode
- Mesh mMesh;
-
- // HWC items, accessed from the main thread
- struct HWCInfo {
- HWCInfo()
- : hwc(nullptr),
- layer(nullptr),
- forceClientComposition(false),
- compositionType(HWC2::Composition::Invalid),
- clearClientTarget(false),
- transform(HWC2::Transform::None) {}
-
- HWComposer* hwc;
- HWC2::Layer* layer;
- bool forceClientComposition;
- HWC2::Composition compositionType;
- bool clearClientTarget;
- Rect displayFrame;
- FloatRect sourceCrop;
- HWComposerBufferCache bufferCache;
- HWC2::Transform transform;
- };
-
- // A layer can be attached to multiple displays when operating in mirror mode
- // (a.k.a: when several displays are attached with equal layerStack). In this
- // case we need to keep track. In non-mirror mode, a layer will have only one
- // HWCInfo. This map key is a display layerStack.
- std::unordered_map<int32_t, HWCInfo> mHwcLayers;
-
- CompositionInfo compositionInfo;
-};
-
class Layer : public virtual RefBase {
static int32_t sSequence;
@@ -518,7 +455,15 @@
if (getBE().mHwcLayers.count(hwcId) == 0) {
return nullptr;
}
- return getBE().mHwcLayers[hwcId].layer;
+ return *(getBE().mHwcLayers[hwcId].layer.get());
+ }
+
+ bool setHwcLayer(int32_t hwcId) {
+ if (getBE().mHwcLayers.count(hwcId) == 0) {
+ return false;
+ }
+ getBE().compositionInfo.hwc.hwcLayer = getBE().mHwcLayers[hwcId].layer;
+ return true;
}
// -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp
new file mode 100644
index 0000000..5287fe1
--- /dev/null
+++ b/services/surfaceflinger/LayerBE.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "LayerBE"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include "Layer.h"
+
+namespace android {
+
+LayerBE::LayerBE(Layer* layer, std::string layerName)
+ : mLayer(layer),
+ mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) {
+ compositionInfo.layer = this;
+ compositionInfo.layerName = layerName;
+}
+
+void LayerBE::onLayerDisplayed(const sp<Fence>& releaseFence) {
+ mLayer->onLayerDisplayed(releaseFence);
+}
+
+void CompositionInfo::dumpHwc(const char* tag) const {
+ ALOGV("[%s]\thwcLayer=%p", tag, static_cast<HWC2::Layer*>(*hwc.hwcLayer));
+ ALOGV("[%s]\tfence=%p", tag, hwc.fence.get());
+ ALOGV("[%s]\ttransform=%d", tag, hwc.transform);
+ ALOGV("[%s]\tz=%d", tag, hwc.z);
+ ALOGV("[%s]\ttype=%d", tag, hwc.type);
+ ALOGV("[%s]\tappId=%d", tag, hwc.appId);
+ ALOGV("[%s]\tdisplayFrame=%4d %4d %4d %4d", tag, hwc.displayFrame.left, hwc.displayFrame.top, hwc.displayFrame.right, hwc.displayFrame.bottom);
+ ALOGV("[%s]\talpha=%.3f", tag, hwc.alpha);
+ ALOGV("[%s]\tsourceCrop=%6.1f %6.1f %6.1f %6.1f", tag, hwc.sourceCrop.left, hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom);
+
+ std::string label = tag;
+ label+=":visibleRegion";
+ hwc.visibleRegion.dump(label.c_str());
+ label = tag;
+ label+=":surfaceDamage";
+ hwc.surfaceDamage.dump(label.c_str());
+}
+
+void CompositionInfo::dumpRe(const char* tag) const {
+ ALOGV("[%s]\tblackoutLayer=%d", tag, re.blackoutLayer);
+ ALOGV("[%s]\tclearArea=%d", tag, re.clearArea);
+ ALOGV("[%s]\tpreMultipliedAlpha=%d", tag, re.preMultipliedAlpha);
+ ALOGV("[%s]\topaque=%d\n", tag, re.opaque);
+ ALOGV("[%s]\ttexture:name(%d), target(%d), size(%d/%d)", tag, re.texture.getTextureName(), re.texture.getTextureTarget(), (unsigned int)re.texture.getWidth(), (unsigned int)re.texture.getHeight());
+ ALOGV("[%s]\tuseIdentityTransform=%d\n", tag, re.useIdentityTransform);
+}
+
+void CompositionInfo::dump(const char* tag) const {
+ ALOGV("[%s] CompositionInfo", tag);
+ ALOGV("[%s]\tLayerName: %s", tag, layerName.c_str());
+ ALOGV("[%s]\tCompositionType: %d", tag, compositionType);
+ ALOGV("[%s]\tmBuffer = %p", tag, mBuffer.get());
+ ALOGV("[%s]\tmBufferSlot=%d", tag, mBufferSlot);
+ switch (compositionType) {
+ case HWC2::Composition::Device:
+ dumpHwc(tag);
+ break;
+ case HWC2::Composition::Client:
+ dumpRe(tag);
+ default:
+ break;
+ }
+}
+
+}; // namespace android
diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h
new file mode 100644
index 0000000..981f756
--- /dev/null
+++ b/services/surfaceflinger/LayerBE.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/Region.h>
+
+#include "SurfaceFlinger.h"
+
+#include "DisplayHardware/HWComposer.h"
+#include "DisplayHardware/HWComposerBufferCache.h"
+#include "RenderEngine/Mesh.h"
+#include "RenderEngine/Texture.h"
+
+namespace android {
+
+class LayerBE;
+
+class LayerContainer
+{
+ public:
+ LayerContainer(HWComposer* hwc, int32_t hwcId) : mHwc(hwc), mHwcId(hwcId) {
+ mLayer = hwc->createLayer(hwcId);
+ }
+
+ ~LayerContainer() {
+ mHwc->destroyLayer(mHwcId, mLayer);
+ }
+
+ HWC2::Layer* operator->() {
+ return mLayer;
+ }
+
+ operator HWC2::Layer*const () const {
+ return mLayer;
+ }
+
+ private:
+ HWComposer* mHwc;
+ int32_t mHwcId;
+ HWC2::Layer* mLayer;
+};
+
+struct CompositionInfo {
+ std::string layerName;
+ HWC2::Composition compositionType;
+ sp<GraphicBuffer> mBuffer = nullptr;
+ int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
+ LayerBE* layer = nullptr;
+ struct {
+ std::shared_ptr<LayerContainer> hwcLayer;
+ int32_t hwid = -1;
+ sp<Fence> fence;
+ HWC2::BlendMode blendMode = HWC2::BlendMode::Invalid;
+ Rect displayFrame;
+ float alpha;
+ FloatRect sourceCrop;
+ HWC2::Transform transform = HWC2::Transform::None;
+ int z;
+ int type;
+ int appId;
+ Region visibleRegion;
+ Region surfaceDamage;
+ sp<NativeHandle> sidebandStream;
+ android_dataspace dataspace;
+ hwc_color_t color;
+ } hwc;
+ struct {
+ Mesh* mesh;
+ bool blackoutLayer = false;
+ bool clearArea = false;
+ bool preMultipliedAlpha = false;
+ bool opaque = false;
+ half4 color;
+ Texture texture;
+ bool useIdentityTransform = false;
+ } re;
+
+ void dump(const char* tag) const;
+ void dumpHwc(const char* tag) const;
+ void dumpRe(const char* tag) const;
+};
+
+class LayerBE {
+public:
+ friend class Layer;
+ friend class BufferLayer;
+ friend class ColorLayer;
+ friend class SurfaceFlinger;
+
+ LayerBE(Layer* layer, std::string layerName);
+
+ void onLayerDisplayed(const sp<Fence>& releaseFence);
+ Mesh& getMesh() { return mMesh; }
+
+private:
+ Layer*const mLayer;
+ // The mesh used to draw the layer in GLES composition mode
+ Mesh mMesh;
+
+ // HWC items, accessed from the main thread
+ struct HWCInfo {
+ HWCInfo()
+ : hwc(nullptr),
+ layer(nullptr),
+ forceClientComposition(false),
+ compositionType(HWC2::Composition::Invalid),
+ clearClientTarget(false),
+ transform(HWC2::Transform::None) {}
+
+ HWComposer* hwc;
+ std::shared_ptr<LayerContainer> layer;
+ bool forceClientComposition;
+ HWC2::Composition compositionType;
+ bool clearClientTarget;
+ Rect displayFrame;
+ FloatRect sourceCrop;
+ HWComposerBufferCache bufferCache;
+ HWC2::Transform transform;
+ };
+
+
+ // A layer can be attached to multiple displays when operating in mirror mode
+ // (a.k.a: when several displays are attached with equal layerStack). In this
+ // case we need to keep track. In non-mirror mode, a layer will have only one
+ // HWCInfo. This map key is a display layerStack.
+ std::unordered_map<int32_t, HWCInfo> mHwcLayers;
+
+ CompositionInfo compositionInfo;
+};
+
+}; // namespace android
+
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e12d7ca..ab476f0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -408,8 +408,10 @@
sp<BBinder> token = new DisplayToken(this);
Mutex::Autolock _l(mStateLock);
- DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
+ DisplayDeviceState info;
+ info.type = DisplayDevice::DISPLAY_VIRTUAL;
info.displayName = displayName;
+ info.isSecure = secure;
mCurrentState.displays.add(token, info);
mInterceptor->saveDisplayCreation(info);
return token;
@@ -425,11 +427,11 @@
}
const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
- if (!info.isVirtualDisplay()) {
+ if (!info.isVirtual()) {
ALOGE("destroyDisplay called for non-virtual display");
return;
}
- mInterceptor->saveDisplayDeletion(info.displayId);
+ mInterceptor->saveDisplayDeletion(info.sequenceId);
mCurrentState.displays.removeItemsAt(idx);
setTransactionFlags(eDisplayTransactionNeeded);
}
@@ -923,7 +925,6 @@
void SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
this);
- int32_t type = hw->getDisplayType();
int currentMode = hw->getActiveConfig();
if (mode == currentMode) {
@@ -931,13 +932,13 @@
return;
}
- if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
+ if (hw->isVirtual()) {
ALOGW("Trying to set config for virtual display");
return;
}
hw->setActiveConfig(mode);
- getHwComposer().setActiveConfig(type, mode);
+ getHwComposer().setActiveConfig(hw->getDisplayType(), mode);
}
status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
@@ -961,7 +962,7 @@
if (hw == nullptr) {
ALOGE("Attempt to set active config = %d for null display %p",
mMode, mDisplay.get());
- } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
+ } else if (hw->isVirtual()) {
ALOGW("Attempt to set active config = %d for virtual display",
mMode);
} else {
@@ -1018,7 +1019,6 @@
void SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
ColorMode mode, Dataspace dataSpace) {
- int32_t type = hw->getDisplayType();
ColorMode currentMode = hw->getActiveColorMode();
Dataspace currentDataSpace = hw->getCompositionDataSpace();
RenderIntent currentRenderIntent = hw->getActiveRenderIntent();
@@ -1032,9 +1032,8 @@
// In Auto Color Mode, we want to strech to panel color space, right now
// only the built-in display supports it.
- if (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
- mBuiltinDisplaySupportsEnhance &&
- hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
+ if (mDisplayColorSetting == DisplayColorSetting::ENHANCED && mBuiltinDisplaySupportsEnhance &&
+ hw->isPrimary()) {
renderIntent = RenderIntent::ENHANCE;
}
@@ -1043,7 +1042,7 @@
return;
}
- if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
+ if (hw->isVirtual()) {
ALOGW("Trying to set config for virtual display");
return;
}
@@ -1051,7 +1050,7 @@
hw->setActiveColorMode(mode);
hw->setCompositionDataSpace(dataSpace);
hw->setActiveRenderIntent(renderIntent);
- getHwComposer().setActiveColorMode(type, mode, renderIntent);
+ getHwComposer().setActiveColorMode(hw->getDisplayType(), mode, renderIntent);
ALOGV("Set active color mode: %s (%d), active render intent: %s (%d), type=%d",
decodeColorMode(mode).c_str(), mode,
@@ -1083,7 +1082,7 @@
if (hw == nullptr) {
ALOGE("Attempt to set active color mode %s (%d) for null display %p",
decodeColorMode(mMode).c_str(), mMode, mDisplay.get());
- } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
+ } else if (hw->isVirtual()) {
ALOGW("Attempt to set active color mode %s %d for virtual display",
decodeColorMode(mMode).c_str(), mMode);
} else {
@@ -1976,7 +1975,7 @@
// emit any black frames until a layer is added to the layer stack.
bool mustRecompose = dirty && !(empty && wasEmpty);
- ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
+ ALOGV_IF(mDisplays[dpy]->isVirtual(),
"dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
mustRecompose ? "doing" : "skipping",
dirty ? "+" : "-",
@@ -2134,7 +2133,7 @@
displayDevice->getClientTargetAcquireFence());
}
- layer->onLayerDisplayed(releaseFence);
+ layer->getBE().onLayerDisplayed(releaseFence);
}
// We've got a list of layers needing fences, that are disjoint with
@@ -2143,7 +2142,7 @@
if (!displayDevice->getLayersNeedingFences().isEmpty()) {
sp<Fence> presentFence = getBE().mHwc->getPresentFence(hwcId);
for (auto& layer : displayDevice->getLayersNeedingFences()) {
- layer->onLayerDisplayed(presentFence);
+ layer->getBE().onLayerDisplayed(presentFence);
}
}
@@ -2239,10 +2238,11 @@
if (!mBuiltinDisplays[displayType].get()) {
ALOGV("Creating built in display %d", displayType);
mBuiltinDisplays[displayType] = new BBinder();
- // All non-virtual displays are currently considered secure.
- DisplayDeviceState info(displayType, true);
+ DisplayDeviceState info;
+ info.type = displayType;
info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ?
"Built-in Screen" : "External Screen";
+ info.isSecure = true; // All physical displays are currently considered secure.
mCurrentState.displays.add(mBuiltinDisplays[displayType], info);
mInterceptor->saveDisplayCreation(info);
}
@@ -2252,7 +2252,7 @@
ssize_t idx = mCurrentState.displays.indexOfKey(mBuiltinDisplays[displayType]);
if (idx >= 0) {
const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
- mInterceptor->saveDisplayDeletion(info.displayId);
+ mInterceptor->saveDisplayDeletion(info.sequenceId);
mCurrentState.displays.removeItemsAt(idx);
}
mBuiltinDisplays[displayType].clear();
@@ -2306,7 +2306,7 @@
*/
std::unique_ptr<RE::Surface> renderSurface = getRenderEngine().createSurface();
renderSurface->setCritical(state.type == DisplayDevice::DISPLAY_PRIMARY);
- renderSurface->setAsync(state.type >= DisplayDevice::DISPLAY_VIRTUAL);
+ renderSurface->setAsync(state.isVirtual());
renderSurface->setNativeWindow(nativeWindow.get());
const int displayWidth = renderSurface->queryWidth();
const int displayHeight = renderSurface->queryHeight();
@@ -2318,13 +2318,12 @@
// * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
// window's swap interval in eglMakeCurrent, so they'll override the
// interval we set here.
- if (state.type >= DisplayDevice::DISPLAY_VIRTUAL) {
+ if (state.isVirtual()) {
nativeWindow->setSwapInterval(nativeWindow.get(), 0);
}
// virtual displays are always considered enabled
- auto initialPowerMode = (state.type >= DisplayDevice::DISPLAY_VIRTUAL) ? HWC_POWER_MODE_NORMAL
- : HWC_POWER_MODE_OFF;
+ auto initialPowerMode = state.isVirtual() ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
sp<DisplayDevice> hw =
new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
@@ -2430,7 +2429,7 @@
mCreateBufferQueue(&bqProducer, &bqConsumer, false);
int32_t hwcId = -1;
- if (state.isVirtualDisplay()) {
+ if (state.isVirtual()) {
// Virtual displays without a surface are dormant:
// they have external state (layer stack, projection,
// etc.) but no internal state (i.e. a DisplayDevice).
@@ -2477,7 +2476,7 @@
mDisplays.add(display,
setupNewDisplayDeviceInternal(display, hwcId, state, dispSurface,
producer));
- if (!state.isVirtualDisplay()) {
+ if (!state.isVirtual()) {
mEventThread->onHotplugReceived(state.type, true);
}
}
@@ -2920,7 +2919,7 @@
if (!displayDevice->makeCurrent()) {
ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
- displayDevice->getDisplayName().string());
+ displayDevice->getDisplayName().c_str());
getRenderEngine().resetCurrentSurface();
// |mStateLock| not needed as we are on the main thread
@@ -2954,7 +2953,7 @@
}
}
- if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
+ if (!displayDevice->isPrimary()) {
// just to be on the safe side, we don't set the
// scissor on the main display. It should never be needed
// anyways (though in theory it could since the API allows it).
@@ -3696,7 +3695,6 @@
int mode, bool stateLockHeld) {
ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
this);
- int32_t type = hw->getDisplayType();
int currentMode = hw->getPowerMode();
if (mode == currentMode) {
@@ -3704,7 +3702,7 @@
}
hw->setPowerMode(mode);
- if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
+ if (hw->isVirtual()) {
ALOGW("Trying to set power mode for virtual display");
return;
}
@@ -3716,14 +3714,14 @@
ALOGW("Surface Interceptor SavePowerMode: invalid display token");
return;
}
- mInterceptor->savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode);
+ mInterceptor->savePowerModeUpdate(mCurrentState.displays.valueAt(idx).sequenceId, mode);
}
+ int32_t type = hw->getDisplayType();
if (currentMode == HWC_POWER_MODE_OFF) {
// Turn on the display
getHwComposer().setPowerMode(type, mode);
- if (type == DisplayDevice::DISPLAY_PRIMARY &&
- mode != HWC_POWER_MODE_DOZE_SUSPEND) {
+ if (hw->isPrimary() && mode != HWC_POWER_MODE_DOZE_SUSPEND) {
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenAcquired();
resyncToHardwareVsync(true);
@@ -3745,8 +3743,7 @@
ALOGW("Couldn't set SCHED_OTHER on display off");
}
- if (type == DisplayDevice::DISPLAY_PRIMARY &&
- currentMode != HWC_POWER_MODE_DOZE_SUSPEND) {
+ if (hw->isPrimary() && currentMode != HWC_POWER_MODE_DOZE_SUSPEND) {
disableHardwareVsync(true); // also cancels any in-progress resync
// FIXME: eventthread only knows about the main display right now
@@ -3760,15 +3757,14 @@
mode == HWC_POWER_MODE_NORMAL) {
// Update display while dozing
getHwComposer().setPowerMode(type, mode);
- if (type == DisplayDevice::DISPLAY_PRIMARY &&
- currentMode == HWC_POWER_MODE_DOZE_SUSPEND) {
+ if (hw->isPrimary() && currentMode == HWC_POWER_MODE_DOZE_SUSPEND) {
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenAcquired();
resyncToHardwareVsync(true);
}
} else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
// Leave display going to doze
- if (type == DisplayDevice::DISPLAY_PRIMARY) {
+ if (hw->isPrimary()) {
disableHardwareVsync(true); // also cancels any in-progress resync
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenReleased();
@@ -3795,7 +3791,7 @@
if (hw == nullptr) {
ALOGE("Attempt to set power mode = %d for null display %p",
mMode, mDisplay.get());
- } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
+ } else if (hw->isVirtual()) {
ALOGW("Attempt to set power mode = %d for virtual display",
mMode);
} else {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 33706da..1c5fe43 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -45,6 +45,7 @@
#include <gui/LayerState.h>
#include <gui/OccupancyTracker.h>
+#include <gui/BufferQueue.h>
#include <hardware/hwcomposer_defs.h>
@@ -63,6 +64,7 @@
#include "SurfaceInterceptor.h"
#include "SurfaceTracing.h"
#include "StartPropertySetThread.h"
+#include "LayerBE.h"
#include "VSyncModulator.h"
#include "DisplayHardware/HWC2.h"
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 4596a21..e70506d 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -122,10 +122,10 @@
transaction->set_synchronous(false);
transaction->set_animation(false);
- addDisplaySurfaceLocked(transaction, display.displayId, display.surface);
- addDisplayLayerStackLocked(transaction, display.displayId, display.layerStack);
- addDisplaySizeLocked(transaction, display.displayId, display.width, display.height);
- addDisplayProjectionLocked(transaction, display.displayId, display.orientation,
+ addDisplaySurfaceLocked(transaction, display.sequenceId, display.surface);
+ addDisplayLayerStackLocked(transaction, display.sequenceId, display.layerStack);
+ addDisplaySizeLocked(transaction, display.sequenceId, display.width, display.height);
+ addDisplayProjectionLocked(transaction, display.sequenceId, display.orientation,
display.viewport, display.frame);
}
@@ -177,10 +177,10 @@
}
DisplayChange* SurfaceInterceptor::createDisplayChangeLocked(Transaction* transaction,
- int32_t displayId)
+ int32_t sequenceId)
{
DisplayChange* dispChange(transaction->add_display_change());
- dispChange->set_id(displayId);
+ dispChange->set_id(sequenceId);
return dispChange;
}
@@ -379,19 +379,19 @@
}
void SurfaceInterceptor::addDisplayChangesLocked(Transaction* transaction,
- const DisplayState& state, int32_t displayId)
+ const DisplayState& state, int32_t sequenceId)
{
if (state.what & DisplayState::eSurfaceChanged) {
- addDisplaySurfaceLocked(transaction, displayId, state.surface);
+ addDisplaySurfaceLocked(transaction, sequenceId, state.surface);
}
if (state.what & DisplayState::eLayerStackChanged) {
- addDisplayLayerStackLocked(transaction, displayId, state.layerStack);
+ addDisplayLayerStackLocked(transaction, sequenceId, state.layerStack);
}
if (state.what & DisplayState::eDisplaySizeChanged) {
- addDisplaySizeLocked(transaction, displayId, state.width, state.height);
+ addDisplaySizeLocked(transaction, sequenceId, state.width, state.height);
}
if (state.what & DisplayState::eDisplayProjectionChanged) {
- addDisplayProjectionLocked(transaction, displayId, state.orientation, state.viewport,
+ addDisplayProjectionLocked(transaction, sequenceId, state.orientation, state.viewport,
state.frame);
}
}
@@ -411,7 +411,7 @@
ssize_t dpyIdx = displays.indexOfKey(disp.token);
if (dpyIdx >= 0) {
const DisplayDeviceState& dispState(displays.valueAt(dpyIdx));
- addDisplayChangesLocked(transaction, disp, dispState.displayId);
+ addDisplayChangesLocked(transaction, disp, dispState.sequenceId);
}
}
}
@@ -448,7 +448,7 @@
event->set_when(timestamp);
}
-void SurfaceInterceptor::addDisplaySurfaceLocked(Transaction* transaction, int32_t displayId,
+void SurfaceInterceptor::addDisplaySurfaceLocked(Transaction* transaction, int32_t sequenceId,
const sp<const IGraphicBufferProducer>& surface)
{
if (surface == nullptr) {
@@ -457,7 +457,7 @@
uint64_t bufferQueueId = 0;
status_t err(surface->getUniqueId(&bufferQueueId));
if (err == NO_ERROR) {
- DisplayChange* dispChange(createDisplayChangeLocked(transaction, displayId));
+ DisplayChange* dispChange(createDisplayChangeLocked(transaction, sequenceId));
DispSurfaceChange* surfaceChange(dispChange->mutable_surface());
surfaceChange->set_buffer_queue_id(bufferQueueId);
surfaceChange->set_buffer_queue_name(surface->getConsumerName().string());
@@ -469,26 +469,26 @@
}
void SurfaceInterceptor::addDisplayLayerStackLocked(Transaction* transaction,
- int32_t displayId, uint32_t layerStack)
+ int32_t sequenceId, uint32_t layerStack)
{
- DisplayChange* dispChange(createDisplayChangeLocked(transaction, displayId));
+ DisplayChange* dispChange(createDisplayChangeLocked(transaction, sequenceId));
LayerStackChange* layerStackChange(dispChange->mutable_layer_stack());
layerStackChange->set_layer_stack(layerStack);
}
-void SurfaceInterceptor::addDisplaySizeLocked(Transaction* transaction, int32_t displayId,
+void SurfaceInterceptor::addDisplaySizeLocked(Transaction* transaction, int32_t sequenceId,
uint32_t w, uint32_t h)
{
- DisplayChange* dispChange(createDisplayChangeLocked(transaction, displayId));
+ DisplayChange* dispChange(createDisplayChangeLocked(transaction, sequenceId));
SizeChange* sizeChange(dispChange->mutable_size());
sizeChange->set_w(w);
sizeChange->set_h(h);
}
void SurfaceInterceptor::addDisplayProjectionLocked(Transaction* transaction,
- int32_t displayId, int32_t orientation, const Rect& viewport, const Rect& frame)
+ int32_t sequenceId, int32_t orientation, const Rect& viewport, const Rect& frame)
{
- DisplayChange* dispChange(createDisplayChangeLocked(transaction, displayId));
+ DisplayChange* dispChange(createDisplayChangeLocked(transaction, sequenceId));
ProjectionChange* projectionChange(dispChange->mutable_projection());
projectionChange->set_orientation(orientation);
Rectangle* viewportRect(projectionChange->mutable_viewport());
@@ -501,22 +501,22 @@
const DisplayDeviceState& info)
{
DisplayCreation* creation(increment->mutable_display_creation());
- creation->set_id(info.displayId);
+ creation->set_id(info.sequenceId);
creation->set_name(info.displayName);
creation->set_type(info.type);
creation->set_is_secure(info.isSecure);
}
-void SurfaceInterceptor::addDisplayDeletionLocked(Increment* increment, int32_t displayId) {
+void SurfaceInterceptor::addDisplayDeletionLocked(Increment* increment, int32_t sequenceId) {
DisplayDeletion* deletion(increment->mutable_display_deletion());
- deletion->set_id(displayId);
+ deletion->set_id(sequenceId);
}
-void SurfaceInterceptor::addPowerModeUpdateLocked(Increment* increment, int32_t displayId,
+void SurfaceInterceptor::addPowerModeUpdateLocked(Increment* increment, int32_t sequenceId,
int32_t mode)
{
PowerModeUpdate* powerModeUpdate(increment->mutable_power_mode_update());
- powerModeUpdate->set_id(displayId);
+ powerModeUpdate->set_id(sequenceId);
powerModeUpdate->set_mode(mode);
}
@@ -579,22 +579,22 @@
addDisplayCreationLocked(createTraceIncrementLocked(), info);
}
-void SurfaceInterceptor::saveDisplayDeletion(int32_t displayId) {
+void SurfaceInterceptor::saveDisplayDeletion(int32_t sequenceId) {
if (!mEnabled) {
return;
}
ATRACE_CALL();
std::lock_guard<std::mutex> protoGuard(mTraceMutex);
- addDisplayDeletionLocked(createTraceIncrementLocked(), displayId);
+ addDisplayDeletionLocked(createTraceIncrementLocked(), sequenceId);
}
-void SurfaceInterceptor::savePowerModeUpdate(int32_t displayId, int32_t mode) {
+void SurfaceInterceptor::savePowerModeUpdate(int32_t sequenceId, int32_t mode) {
if (!mEnabled) {
return;
}
ATRACE_CALL();
std::lock_guard<std::mutex> protoGuard(mTraceMutex);
- addPowerModeUpdateLocked(createTraceIncrementLocked(), displayId, mode);
+ addPowerModeUpdateLocked(createTraceIncrementLocked(), sequenceId, mode);
}
} // namespace impl
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index 96defcc..218a1d2 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -66,8 +66,8 @@
// Intercept display data
virtual void saveDisplayCreation(const DisplayDeviceState& info) = 0;
- virtual void saveDisplayDeletion(int32_t displayId) = 0;
- virtual void savePowerModeUpdate(int32_t displayId, int32_t mode) = 0;
+ virtual void saveDisplayDeletion(int32_t sequenceId) = 0;
+ virtual void savePowerModeUpdate(int32_t sequenceId, int32_t mode) = 0;
virtual void saveVSyncEvent(nsecs_t timestamp) = 0;
};
@@ -101,8 +101,8 @@
// Intercept display data
void saveDisplayCreation(const DisplayDeviceState& info) override;
- void saveDisplayDeletion(int32_t displayId) override;
- void savePowerModeUpdate(int32_t displayId, int32_t mode) override;
+ void saveDisplayDeletion(int32_t sequenceId) override;
+ void savePowerModeUpdate(int32_t sequenceId, int32_t mode) override;
void saveVSyncEvent(nsecs_t timestamp) override;
private:
@@ -127,8 +127,8 @@
uint32_t height, uint64_t frameNumber);
void addVSyncUpdateLocked(Increment* increment, nsecs_t timestamp);
void addDisplayCreationLocked(Increment* increment, const DisplayDeviceState& info);
- void addDisplayDeletionLocked(Increment* increment, int32_t displayId);
- void addPowerModeUpdateLocked(Increment* increment, int32_t displayId, int32_t mode);
+ void addDisplayDeletionLocked(Increment* increment, int32_t sequenceId);
+ void addPowerModeUpdateLocked(Increment* increment, int32_t sequenceId, int32_t mode);
// Add surface transactions to the trace
SurfaceChange* createSurfaceChangeLocked(Transaction* transaction, int32_t layerId);
@@ -155,17 +155,17 @@
const Vector<DisplayState>& changedDisplays, uint32_t transactionFlags);
// Add display transactions to the trace
- DisplayChange* createDisplayChangeLocked(Transaction* transaction, int32_t displayId);
- void addDisplaySurfaceLocked(Transaction* transaction, int32_t displayId,
+ DisplayChange* createDisplayChangeLocked(Transaction* transaction, int32_t sequenceId);
+ void addDisplaySurfaceLocked(Transaction* transaction, int32_t sequenceId,
const sp<const IGraphicBufferProducer>& surface);
- void addDisplayLayerStackLocked(Transaction* transaction, int32_t displayId,
+ void addDisplayLayerStackLocked(Transaction* transaction, int32_t sequenceId,
uint32_t layerStack);
- void addDisplaySizeLocked(Transaction* transaction, int32_t displayId, uint32_t w,
+ void addDisplaySizeLocked(Transaction* transaction, int32_t sequenceId, uint32_t w,
uint32_t h);
- void addDisplayProjectionLocked(Transaction* transaction, int32_t displayId,
+ void addDisplayProjectionLocked(Transaction* transaction, int32_t sequenceId,
int32_t orientation, const Rect& viewport, const Rect& frame);
void addDisplayChangesLocked(Transaction* transaction,
- const DisplayState& state, int32_t displayId);
+ const DisplayState& state, int32_t sequenceId);
bool mEnabled {false};
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index f39ca00..3a9cfd2 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -50,82 +50,50 @@
using android::Hwc2::Error;
using android::Hwc2::IComposer;
using android::Hwc2::IComposerClient;
+using android::Hwc2::RenderIntent;
-using HWC2Display = TestableSurfaceFlinger::HWC2Display;
+using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
+using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
using HotplugEvent = TestableSurfaceFlinger::HotplugEvent;
+using HWC2Display = TestableSurfaceFlinger::HWC2Display;
-constexpr int32_t DEFAULT_REFRESH_RATE = 1666666666;
+constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
constexpr int32_t DEFAULT_DPI = 320;
+constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
-constexpr int DEFAULT_CONFIG_ID = 0;
+/* ------------------------------------------------------------------------
+ * Boolean avoidance
+ *
+ * To make calls and template instantiations more readable, we define some
+ * local enums along with an implicit bool conversion.
+ */
+
+#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
+
+BOOL_SUBSTITUTE(Critical);
+BOOL_SUBSTITUTE(Async);
+BOOL_SUBSTITUTE(Secure);
+
+/* ------------------------------------------------------------------------
+ *
+ */
class DisplayTransactionTest : public testing::Test {
-protected:
+public:
DisplayTransactionTest();
~DisplayTransactionTest() override;
// --------------------------------------------------------------------
- // Precondition helpers
+ // Mock/Fake injection
- void setupComposer(int virtualDisplayCount);
- void setupFakeHwcDisplay(hwc2_display_t displayId, DisplayDevice::DisplayType type, int width,
- int height);
-
- struct FakeDisplayDeviceFactory {
- public:
- FakeDisplayDeviceFactory(TestableSurfaceFlinger& flinger, sp<BBinder>& displayToken,
- DisplayDevice::DisplayType type, int hwcId)
- : mFlinger(flinger), mDisplayToken(displayToken), mType(type), mHwcId(hwcId) {}
-
- sp<DisplayDevice> build() {
- return new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, false, mDisplayToken,
- mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0,
- 0, false, {}, 0, HWC_POWER_MODE_NORMAL);
- }
-
- FakeDisplayDeviceFactory& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
- mNativeWindow = nativeWindow;
- return *this;
- }
-
- FakeDisplayDeviceFactory& setDisplaySurface(const sp<DisplaySurface>& displaySurface) {
- mDisplaySurface = displaySurface;
- return *this;
- }
-
- FakeDisplayDeviceFactory& setRenderSurface(std::unique_ptr<RE::Surface> renderSurface) {
- mRenderSurface = std::move(renderSurface);
- return *this;
- }
-
- TestableSurfaceFlinger& mFlinger;
- sp<BBinder>& mDisplayToken;
- DisplayDevice::DisplayType mType;
- int mHwcId;
- sp<ANativeWindow> mNativeWindow;
- sp<DisplaySurface> mDisplaySurface;
- std::unique_ptr<RE::Surface> mRenderSurface;
- };
-
- sp<BBinder> setupFakeExistingPhysicalDisplay(hwc2_display_t displayId,
- DisplayDevice::DisplayType type);
-
- void setupFakeBufferQueueFactory();
- void setupFakeNativeWindowSurfaceFactory(int displayWidth, int displayHeight, bool critical,
- bool async);
- void expectFramebufferUsageSet(int width, int height, int grallocUsage);
- void expectHwcHotplugCalls(hwc2_display_t displayId, int displayWidth, int displayHeight);
-
- // --------------------------------------------------------------------
- // Call expectation helpers
-
- void expectRESurfaceCreationCalls();
- void expectPhysicalDisplayDeviceCreationCalls(hwc2_display_t displayId, int displayWidth,
- int displayHeight, bool critical, bool async);
+ void injectMockComposer(int virtualDisplayCount);
+ void injectFakeBufferQueueFactory();
+ void injectFakeNativeWindowSurfaceFactory();
// --------------------------------------------------------------------
// Postcondition helpers
+ bool hasHwcDisplay(hwc2_display_t displayId);
bool hasTransactionFlagSet(int flag);
bool hasDisplayDevice(sp<IBinder> displayToken);
sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
@@ -137,8 +105,6 @@
// --------------------------------------------------------------------
// Test instances
- std::unordered_set<HWC2::Capability> mCapabilities;
-
TestableSurfaceFlinger mFlinger;
mock::EventThread* mEventThread = new mock::EventThread();
mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
@@ -147,7 +113,7 @@
// by virtue of being stored into a std::unique_ptr. However we still need
// to keep a reference to them for use in setting up call expectations.
RE::mock::RenderEngine* mRenderEngine = new RE::mock::RenderEngine();
- Hwc2::mock::Composer* mComposer = new Hwc2::mock::Composer();
+ Hwc2::mock::Composer* mComposer = nullptr;
mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
mock::SurfaceInterceptor* mSurfaceInterceptor = new mock::SurfaceInterceptor();
@@ -157,7 +123,6 @@
mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
sp<mock::NativeWindow> mNativeWindow;
RE::mock::Surface* mRenderSurface = nullptr;
- std::vector<std::unique_ptr<HWC2Display>> mFakeHwcDisplays;
};
DisplayTransactionTest::DisplayTransactionTest() {
@@ -165,6 +130,13 @@
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+ // Default to no wide color display support configured
+ mFlinger.mutableHasWideColorDisplay() = false;
+ mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
+
+ // Default to using HWC virtual displays
+ mFlinger.mutableUseHwcVirtualDisplays() = true;
+
mFlinger.setCreateBufferQueueFunction([](auto, auto, auto) {
ADD_FAILURE() << "Unexpected request to create a buffer queue.";
});
@@ -180,7 +152,7 @@
mFlinger.setupRenderEngine(std::unique_ptr<RE::RenderEngine>(mRenderEngine));
mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
- setupComposer(0);
+ injectMockComposer(0);
}
DisplayTransactionTest::~DisplayTransactionTest() {
@@ -189,7 +161,8 @@
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
-void DisplayTransactionTest::setupComposer(int virtualDisplayCount) {
+void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
+ mComposer = new Hwc2::mock::Composer();
EXPECT_CALL(*mComposer, getCapabilities())
.WillOnce(Return(std::vector<IComposer::Capability>()));
EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount));
@@ -198,46 +171,7 @@
Mock::VerifyAndClear(mComposer);
}
-void DisplayTransactionTest::setupFakeHwcDisplay(hwc2_display_t displayId,
- DisplayDevice::DisplayType type, int width,
- int height) {
- auto display = std::make_unique<HWC2Display>(*mComposer, mCapabilities, displayId,
- HWC2::DisplayType::Physical);
- display->mutableIsConnected() = true;
- display->mutableConfigs().emplace(DEFAULT_CONFIG_ID,
- HWC2::Display::Config::Builder(*display, DEFAULT_CONFIG_ID)
- .setWidth(width)
- .setHeight(height)
- .setVsyncPeriod(DEFAULT_REFRESH_RATE)
- .setDpiX(DEFAULT_DPI)
- .setDpiY(DEFAULT_DPI)
- .build());
-
- mFlinger.mutableHwcDisplayData()[type].reset();
- mFlinger.mutableHwcDisplayData()[type].hwcDisplay = display.get();
- mFlinger.mutableHwcDisplaySlots().emplace(displayId, type);
-
- mFakeHwcDisplays.push_back(std::move(display));
-}
-
-sp<BBinder> DisplayTransactionTest::setupFakeExistingPhysicalDisplay(
- hwc2_display_t displayId, DisplayDevice::DisplayType type) {
- setupFakeHwcDisplay(displayId, type, 0, 0);
-
- sp<BBinder> displayToken = new BBinder();
- mFlinger.mutableBuiltinDisplays()[type] = displayToken;
- mFlinger.mutableDisplays()
- .add(displayToken,
- FakeDisplayDeviceFactory(mFlinger, displayToken, type, type).build());
-
- DisplayDeviceState state(type, true);
- mFlinger.mutableCurrentState().displays.add(displayToken, state);
- mFlinger.mutableDrawingState().displays.add(displayToken, state);
-
- return displayToken;
-}
-
-void DisplayTransactionTest::setupFakeBufferQueueFactory() {
+void DisplayTransactionTest::injectFakeBufferQueueFactory() {
// This setup is only expected once per test.
ASSERT_TRUE(mConsumer == nullptr && mProducer == nullptr);
@@ -250,9 +184,7 @@
});
}
-void DisplayTransactionTest::setupFakeNativeWindowSurfaceFactory(int displayWidth,
- int displayHeight, bool critical,
- bool async) {
+void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() {
// This setup is only expected once per test.
ASSERT_TRUE(mNativeWindowSurface == nullptr);
@@ -261,75 +193,10 @@
mFlinger.setCreateNativeWindowSurface(
[this](auto) { return std::unique_ptr<NativeWindowSurface>(mNativeWindowSurface); });
-
- EXPECT_CALL(*mNativeWindowSurface, getNativeWindow()).WillOnce(Return(mNativeWindow));
-
- EXPECT_CALL(*mNativeWindow, perform(19)).Times(1);
-
- EXPECT_CALL(*mRenderSurface, setAsync(async)).Times(1);
- EXPECT_CALL(*mRenderSurface, setCritical(critical)).Times(1);
- EXPECT_CALL(*mRenderSurface, setNativeWindow(mNativeWindow.get())).Times(1);
- EXPECT_CALL(*mRenderSurface, queryWidth()).WillOnce(Return(displayWidth));
- EXPECT_CALL(*mRenderSurface, queryHeight()).WillOnce(Return(displayHeight));
}
-void DisplayTransactionTest::expectFramebufferUsageSet(int width, int height, int grallocUsage) {
- EXPECT_CALL(*mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
- EXPECT_CALL(*mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
- EXPECT_CALL(*mConsumer, setConsumerUsageBits(grallocUsage)).WillRepeatedly(Return(NO_ERROR));
- EXPECT_CALL(*mConsumer, setDefaultBufferSize(width, height)).WillRepeatedly(Return(NO_ERROR));
- EXPECT_CALL(*mConsumer, setMaxAcquiredBufferCount(_)).WillRepeatedly(Return(NO_ERROR));
-
- EXPECT_CALL(*mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
-}
-
-void DisplayTransactionTest::expectHwcHotplugCalls(hwc2_display_t displayId, int displayWidth,
- int displayHeight) {
- EXPECT_CALL(*mComposer, getDisplayType(displayId, _))
- .WillOnce(DoAll(SetArgPointee<1>(IComposerClient::DisplayType::PHYSICAL),
- Return(Error::NONE)));
- EXPECT_CALL(*mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
- EXPECT_CALL(*mComposer, getDisplayConfigs(_, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::vector<unsigned>{0}), Return(Error::NONE)));
- EXPECT_CALL(*mComposer, getDisplayAttribute(displayId, 0, IComposerClient::Attribute::WIDTH, _))
- .WillOnce(DoAll(SetArgPointee<3>(displayWidth), Return(Error::NONE)));
- EXPECT_CALL(*mComposer,
- getDisplayAttribute(displayId, 0, IComposerClient::Attribute::HEIGHT, _))
- .WillOnce(DoAll(SetArgPointee<3>(displayHeight), Return(Error::NONE)));
- EXPECT_CALL(*mComposer,
- getDisplayAttribute(displayId, 0, IComposerClient::Attribute::VSYNC_PERIOD, _))
- .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_REFRESH_RATE), Return(Error::NONE)));
- EXPECT_CALL(*mComposer, getDisplayAttribute(displayId, 0, IComposerClient::Attribute::DPI_X, _))
- .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
- EXPECT_CALL(*mComposer, getDisplayAttribute(displayId, 0, IComposerClient::Attribute::DPI_Y, _))
- .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
-}
-
-void DisplayTransactionTest::expectRESurfaceCreationCalls() {
- // This setup is only expected once per test.
- ASSERT_TRUE(mRenderSurface == nullptr);
-
- mRenderSurface = new RE::mock::Surface();
- EXPECT_CALL(*mRenderEngine, createSurface())
- .WillOnce(Return(ByMove(std::unique_ptr<RE::Surface>(mRenderSurface))));
-}
-
-void DisplayTransactionTest::expectPhysicalDisplayDeviceCreationCalls(hwc2_display_t displayId,
- int displayWidth,
- int displayHeight,
- bool critical, bool async) {
- EXPECT_CALL(*mComposer, getActiveConfig(displayId, _))
- .WillOnce(DoAll(SetArgPointee<1>(DEFAULT_CONFIG_ID), Return(Error::NONE)));
- EXPECT_CALL(*mComposer, getColorModes(displayId, _)).Times(0);
- EXPECT_CALL(*mComposer, getHdrCapabilities(displayId, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
-
- setupFakeBufferQueueFactory();
- expectFramebufferUsageSet(displayWidth, displayHeight,
- GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER |
- GRALLOC_USAGE_HW_FB);
-
- setupFakeNativeWindowSurfaceFactory(displayWidth, displayHeight, critical, async);
+bool DisplayTransactionTest::hasHwcDisplay(hwc2_display_t displayId) {
+ return mFlinger.mutableHwcDisplaySlots().count(displayId) == 1;
}
bool DisplayTransactionTest::hasTransactionFlagSet(int flag) {
@@ -361,36 +228,654 @@
}
/* ------------------------------------------------------------------------
- * SurfaceFlinger::handleTransactionLocked(eDisplayTransactionNeeded)
+ *
*/
-TEST_F(DisplayTransactionTest, handleTransactionLockedProcessesHotplugConnectPrimary) {
- constexpr hwc2_display_t externalDisplayId = 102;
- constexpr hwc2_display_t displayId = 123;
- constexpr int displayWidth = 1920;
- constexpr int displayHeight = 1080;
+template <DisplayDevice::DisplayType type, DisplayDevice::DisplayType hwcId, int width, int height,
+ Critical critical, Async async, Secure secure, int grallocUsage>
+struct DisplayVariant {
+ // The display width and height
+ static constexpr int WIDTH = width;
+ static constexpr int HEIGHT = height;
+
+ static constexpr int GRALLOC_USAGE = grallocUsage;
+
+ // The type for this display
+ static constexpr DisplayDevice::DisplayType TYPE = type;
+ static constexpr DisplayDevice::DisplayType HWCOMPOSER_ID = hwcId;
+
+ // When creating native window surfaces for the framebuffer, whether those should be critical
+ static constexpr Critical CRITICAL = critical;
+
+ // When creating native window surfaces for the framebuffer, whether those should be async
+ static constexpr Async ASYNC = async;
+
+ // Whether the display should be treated as secure
+ static constexpr Secure SECURE = secure;
+
+ static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
+ auto injector = FakeDisplayDeviceInjector(test->mFlinger, TYPE, HWCOMPOSER_ID);
+ injector.setSecure(static_cast<bool>(SECURE));
+ return injector;
+ }
+
+ // Called by tests to set up any native window creation call expectations.
+ static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
+ .WillOnce(Return(test->mNativeWindow));
+ EXPECT_CALL(*test->mNativeWindow, perform(19)).WillRepeatedly(Return(NO_ERROR));
+
+ // For simplicity, we only expect to create a single render surface for
+ // each test.
+ ASSERT_TRUE(test->mRenderSurface == nullptr);
+ test->mRenderSurface = new RE::mock::Surface();
+ EXPECT_CALL(*test->mRenderEngine, createSurface())
+ .WillOnce(Return(ByMove(std::unique_ptr<RE::Surface>(test->mRenderSurface))));
+ EXPECT_CALL(*test->mRenderSurface, setAsync(static_cast<bool>(ASYNC))).Times(1);
+ EXPECT_CALL(*test->mRenderSurface, setCritical(static_cast<bool>(CRITICAL))).Times(1);
+ EXPECT_CALL(*test->mRenderSurface, setNativeWindow(test->mNativeWindow.get())).Times(1);
+ EXPECT_CALL(*test->mRenderSurface, queryWidth()).WillOnce(Return(WIDTH));
+ EXPECT_CALL(*test->mRenderSurface, queryHeight()).WillOnce(Return(HEIGHT));
+ }
+
+ static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
+ EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
+ EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
+ .WillRepeatedly(Return(NO_ERROR));
+ EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
+ .WillRepeatedly(Return(NO_ERROR));
+ EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
+ .WillRepeatedly(Return(NO_ERROR));
+ }
+
+ static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
+ }
+};
+
+template <hwc2_display_t hwcDisplayId, HWC2::DisplayType hwcDisplayType, typename DisplayVariant>
+struct HwcDisplayVariant {
+ // The display id supplied by the HWC
+ static constexpr hwc2_display_t HWC_DISPLAY_ID = hwcDisplayId;
+
+ // The HWC display type
+ static constexpr HWC2::DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
+
+ // The HWC active configuration id
+ // TODO(b/69807179): SurfaceFlinger does not correctly get the active
+ // config. Once it does, change this to non-zero so that it is properly
+ // covered.
+ // static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
+ static constexpr int HWC_ACTIVE_CONFIG_ID = 0;
+
+ static void injectPendingHotplugEvent(DisplayTransactionTest* test,
+ HWC2::Connection connection) {
+ test->mFlinger.mutablePendingHotplugEvents().emplace_back(
+ HotplugEvent{HWC_DISPLAY_ID, connection});
+ }
+
+ // Called by tests to inject a HWC display setup
+ static void injectHwcDisplay(DisplayTransactionTest* test) {
+ FakeHwcDisplayInjector(DisplayVariant::TYPE, HWC_DISPLAY_TYPE)
+ .setHwcDisplayId(HWC_DISPLAY_ID)
+ .setWidth(DisplayVariant::WIDTH)
+ .setHeight(DisplayVariant::HEIGHT)
+ .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
+ .inject(&test->mFlinger, test->mComposer);
+ }
+
+ static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getDisplayType(HWC_DISPLAY_ID, _))
+ .WillOnce(DoAll(SetArgPointee<1>(static_cast<IComposerClient::DisplayType>(
+ HWC_DISPLAY_TYPE)),
+ Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
+ EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<unsigned>{HWC_ACTIVE_CONFIG_ID}),
+ Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
+ IComposerClient::Attribute::WIDTH, _))
+ .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
+ IComposerClient::Attribute::HEIGHT, _))
+ .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
+ IComposerClient::Attribute::VSYNC_PERIOD, _))
+ .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_REFRESH_RATE), Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
+ IComposerClient::Attribute::DPI_X, _))
+ .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
+ IComposerClient::Attribute::DPI_Y, _))
+ .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
+ }
+
+ // Called by tests to set up HWC call expectations
+ static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
+ .WillOnce(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
+ }
+};
+
+struct NonHwcDisplayVariant {
+ static constexpr int HWC_ACTIVE_CONFIG_ID = 0;
+
+ static void injectHwcDisplay(DisplayTransactionTest*) {}
+
+ static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
+ }
+};
+
+// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
+constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
+ GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
+
+template <hwc2_display_t hwcDisplayId, DisplayDevice::DisplayType type, int width, int height,
+ Critical critical>
+struct PhysicalDisplayVariant
+ : public DisplayVariant<type, type, width, height, critical, Async::FALSE, Secure::TRUE,
+ GRALLOC_USAGE_PHYSICAL_DISPLAY>,
+ public HwcDisplayVariant<hwcDisplayId, HWC2::DisplayType::Physical,
+ DisplayVariant<type, type, width, height, critical, Async::FALSE,
+ Secure::TRUE, GRALLOC_USAGE_PHYSICAL_DISPLAY>> {};
+
+// A primary display is a physical display that is critical
+using PrimaryDisplayVariant =
+ PhysicalDisplayVariant<1001, DisplayDevice::DISPLAY_PRIMARY, 3840, 2160, Critical::TRUE>;
+
+// An external display is physical display that is not critical.
+using ExternalDisplayVariant =
+ PhysicalDisplayVariant<1002, DisplayDevice::DISPLAY_EXTERNAL, 1920, 1280, Critical::FALSE>;
+
+using TertiaryDisplayVariant =
+ PhysicalDisplayVariant<1003, DisplayDevice::DISPLAY_EXTERNAL, 1600, 1200, Critical::FALSE>;
+
+// A virtual display not supported by the HWC.
+constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
+
+template <int width, int height, Secure secure>
+struct NonHwcVirtualDisplayVariant
+ : public DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_ID_INVALID,
+ width, height, Critical::FALSE, Async::TRUE, secure,
+ GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>,
+ public NonHwcDisplayVariant {
+ using Base = DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_ID_INVALID,
+ width, height, Critical::FALSE, Async::TRUE, secure,
+ GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
+
+ static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
+ Base::setupNativeWindowSurfaceCreationCallExpectations(test);
+ EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
+ }
+};
+
+// A virtual display supported by the HWC.
+constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
+
+template <int width, int height, Secure secure>
+struct HwcVirtualDisplayVariant
+ : public DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_VIRTUAL, width,
+ height, Critical::FALSE, Async::TRUE, secure,
+ GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
+ public HwcDisplayVariant<1010, HWC2::DisplayType::Virtual,
+ NonHwcVirtualDisplayVariant<width, height, secure>> {
+ using Base =
+ DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_VIRTUAL, width,
+ height, Critical::FALSE, Async::TRUE, secure, GRALLOC_USAGE_HW_COMPOSER>;
+ using Self = HwcVirtualDisplayVariant<width, height, secure>;
+
+ static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
+ Base::setupNativeWindowSurfaceCreationCallExpectations(test);
+ EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
+ }
+
+ static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
+ .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
+ }
+};
+
+// For this variant, SurfaceFlinger should not configure itself with wide
+// display support, so the display should not be configured for wide-color
+// support.
+struct WideColorSupportNotConfiguredVariant {
+ static constexpr bool WIDE_COLOR_SUPPORTED = false;
+
+ static void injectConfigChange(DisplayTransactionTest* test) {
+ test->mFlinger.mutableHasWideColorDisplay() = false;
+ test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
+ }
+
+ static void setupComposerCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
+ EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
+ EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
+ }
+};
+
+// For this variant, SurfaceFlinger should configure itself with wide display
+// support, and the display should respond with an non-empty list of supported
+// color modes. Wide-color support should be configured.
+template <typename Display>
+struct WideColorP3ColorimetricSupportedVariant {
+ static constexpr bool WIDE_COLOR_SUPPORTED = true;
+
+ static void injectConfigChange(DisplayTransactionTest* test) {
+ test->mFlinger.mutableHasWideColorDisplay() = true;
+ test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
+ }
+
+ static void setupComposerCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::DISPLAY_P3})),
+ Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
+ .WillOnce(DoAll(SetArgPointee<2>(
+ std::vector<RenderIntent>({RenderIntent::COLORIMETRIC})),
+ Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB,
+ RenderIntent::COLORIMETRIC))
+ .WillOnce(Return(Error::NONE));
+ }
+};
+
+// For this variant, SurfaceFlinger should configure itself with wide color
+// display support, and the display should respond with an non-empty list of
+// supported color modes.
+template <typename Display>
+struct WideColorP3EnhanceSupportedVariant {
+ static constexpr bool WIDE_COLOR_SUPPORTED = true;
+
+ static void injectConfigChange(DisplayTransactionTest* test) {
+ test->mFlinger.mutableHasWideColorDisplay() = true;
+ test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::ENHANCED;
+ }
+
+ static void setupComposerCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::DISPLAY_P3})),
+ Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
+ .WillOnce(
+ DoAll(SetArgPointee<2>(std::vector<RenderIntent>({RenderIntent::ENHANCE})),
+ Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB, RenderIntent::ENHANCE))
+ .WillOnce(Return(Error::NONE));
+ }
+};
+
+// For this variant, SurfaceFlinger should configure itself with wide display
+// support, but the display should respond with an empty list of supported color
+// modes. Wide-color support for the display should not be configured.
+template <typename Display>
+struct WideColorNotSupportedVariant {
+ static constexpr bool WIDE_COLOR_SUPPORTED = false;
+
+ static void injectConfigChange(DisplayTransactionTest* test) {
+ test->mFlinger.mutableHasWideColorDisplay() = true;
+ }
+
+ static void setupComposerCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ setColorMode(Display::HWC_DISPLAY_ID, ColorMode::NATIVE,
+ RenderIntent::COLORIMETRIC))
+ .WillOnce(Return(Error::NONE));
+ }
+};
+
+// For this variant, the display is not a HWC display, so no HDR support should
+// be configured.
+struct NonHwcDisplayHdrSupportVariant {
+ static constexpr bool HDR10_SUPPORTED = false;
+ static constexpr bool HDR_HLG_SUPPORTED = false;
+ static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
+ static void setupComposerCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
+ }
+};
+
+// For this variant, the composer should respond with a non-empty list of HDR
+// modes containing HDR10, so HDR10 support should be configured.
+template <typename Display>
+struct Hdr10SupportedVariant {
+ static constexpr bool HDR10_SUPPORTED = true;
+ static constexpr bool HDR_HLG_SUPPORTED = false;
+ static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
+ static void setupComposerCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HDR10})),
+ Return(Error::NONE)));
+ }
+};
+
+// For this variant, the composer should respond with a non-empty list of HDR
+// modes containing HLG, so HLG support should be configured.
+template <typename Display>
+struct HdrHlgSupportedVariant {
+ static constexpr bool HDR10_SUPPORTED = false;
+ static constexpr bool HDR_HLG_SUPPORTED = true;
+ static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
+ static void setupComposerCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
+ .WillOnce(
+ DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HLG})), Return(Error::NONE)));
+ }
+};
+
+// For this variant, the composer should respond with a non-empty list of HDR
+// modes containing DOLBY_VISION, so DOLBY_VISION support should be configured.
+template <typename Display>
+struct HdrDolbyVisionSupportedVariant {
+ static constexpr bool HDR10_SUPPORTED = false;
+ static constexpr bool HDR_HLG_SUPPORTED = false;
+ static constexpr bool HDR_DOLBY_VISION_SUPPORTED = true;
+ static void setupComposerCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::DOLBY_VISION})),
+ Return(Error::NONE)));
+ }
+};
+
+// For this variant, the composer should respond with am empty list of HDR
+// modes, so no HDR support should be configured.
+template <typename Display>
+struct HdrNotSupportedVariant {
+ static constexpr bool HDR10_SUPPORTED = false;
+ static constexpr bool HDR_HLG_SUPPORTED = false;
+ static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
+ static void setupComposerCallExpectations(DisplayTransactionTest* test) {
+ EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
+ }
+};
+
+/* ------------------------------------------------------------------------
+ * Typical display configurations to test
+ */
+
+template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy>
+struct Case {
+ using Display = DisplayPolicy;
+ using WideColorSupport = WideColorSupportPolicy;
+ using HdrSupport = HdrSupportPolicy;
+};
+
+using SimplePrimaryDisplayCase =
+ Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
+ HdrNotSupportedVariant<PrimaryDisplayVariant>>;
+using SimpleExternalDisplayCase =
+ Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
+ HdrNotSupportedVariant<ExternalDisplayVariant>>;
+using SimpleTertiaryDisplayCase =
+ Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
+ HdrNotSupportedVariant<TertiaryDisplayVariant>>;
+using NonHwcVirtualDisplayCase =
+ Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
+ WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant>;
+using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
+using HwcVirtualDisplayCase =
+ Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
+ HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>>;
+using WideColorP3ColorimetricDisplayCase =
+ Case<PrimaryDisplayVariant, WideColorP3ColorimetricSupportedVariant<PrimaryDisplayVariant>,
+ HdrNotSupportedVariant<PrimaryDisplayVariant>>;
+using WideColorP3EnhanceDisplayCase =
+ Case<PrimaryDisplayVariant, WideColorP3EnhanceSupportedVariant<PrimaryDisplayVariant>,
+ HdrNotSupportedVariant<PrimaryDisplayVariant>>;
+using Hdr10DisplayCase =
+ Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
+ Hdr10SupportedVariant<PrimaryDisplayVariant>>;
+using HdrHlgDisplayCase =
+ Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
+ HdrHlgSupportedVariant<PrimaryDisplayVariant>>;
+using HdrDolbyVisionDisplayCase =
+ Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
+ HdrDolbyVisionSupportedVariant<PrimaryDisplayVariant>>;
+
+/* ------------------------------------------------------------------------
+ * SurfaceFlinger::setupNewDisplayDeviceInternal
+ */
+
+class SetupNewDisplayDeviceInternalTest : public DisplayTransactionTest {
+public:
+ template <typename T>
+ void setupNewDisplayDeviceInternalTest();
+};
+
+template <typename Case>
+void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
+ const sp<BBinder> displayToken = new BBinder();
+ const sp<mock::DisplaySurface> displaySurface = new mock::DisplaySurface();
+ const sp<mock::GraphicBufferProducer> producer = new mock::GraphicBufferProducer();
// --------------------------------------------------------------------
// Preconditions
- // An external display may already be set up
- setupFakeHwcDisplay(externalDisplayId, DisplayDevice::DISPLAY_EXTERNAL, 3840, 2160);
+ // Wide color displays support is configured appropriately
+ Case::WideColorSupport::injectConfigChange(this);
- // A hotplug connect comes in for a new display
- mFlinger.mutablePendingHotplugEvents().emplace_back(
- HotplugEvent{displayId, HWC2::Connection::Connected});
+ // The display is setup with the HWC.
+ Case::Display::injectHwcDisplay(this);
+
+ // SurfaceFlinger will use a test-controlled factory for native window
+ // surfaces.
+ injectFakeNativeWindowSurfaceFactory();
+
+ // --------------------------------------------------------------------
+ // Call Expectations
+
+ // Various native window calls will be made.
+ Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
+
+ // TODO(b/69807179): SurfaceFlinger does not correctly get the active config.
+ // Case::Display::setupHwcGetActiveConfigCallExpectations(this)
+
+ Case::WideColorSupport::setupComposerCallExpectations(this);
+ Case::HdrSupport::setupComposerCallExpectations(this);
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ DisplayDeviceState state;
+ state.type = Case::Display::TYPE;
+ state.isSecure = static_cast<bool>(Case::Display::SECURE);
+
+ auto device = mFlinger.setupNewDisplayDeviceInternal(displayToken, Case::Display::TYPE, state,
+ displaySurface, producer);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ ASSERT_TRUE(device != nullptr);
+ EXPECT_EQ(Case::Display::TYPE, device->getDisplayType());
+ EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
+ EXPECT_EQ(Case::Display::WIDTH, device->getWidth());
+ EXPECT_EQ(Case::Display::HEIGHT, device->getHeight());
+ EXPECT_EQ(Case::WideColorSupport::WIDE_COLOR_SUPPORTED, device->hasWideColorGamut());
+ EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
+ EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
+ EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
+ EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveConfig());
+}
+
+TEST_F(SetupNewDisplayDeviceInternalTest, createSimplePrimaryDisplay) {
+ setupNewDisplayDeviceInternalTest<SimplePrimaryDisplayCase>();
+}
+
+TEST_F(SetupNewDisplayDeviceInternalTest, createSimpleExternalDisplay) {
+ setupNewDisplayDeviceInternalTest<SimpleExternalDisplayCase>();
+}
+
+TEST_F(SetupNewDisplayDeviceInternalTest, createNonHwcVirtualDisplay) {
+ setupNewDisplayDeviceInternalTest<NonHwcVirtualDisplayCase>();
+}
+
+TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) {
+ // We need to resize this so that the HWC thinks the virtual display
+ // is something it created.
+ mFlinger.mutableHwcDisplayData().resize(3);
+
+ setupNewDisplayDeviceInternalTest<HwcVirtualDisplayCase>();
+}
+
+TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3Display) {
+ setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
+}
+
+TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3EnhanceDisplay) {
+ setupNewDisplayDeviceInternalTest<WideColorP3EnhanceDisplayCase>();
+}
+
+TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
+ setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
+}
+
+TEST_F(SetupNewDisplayDeviceInternalTest, createHdrHlgDisplay) {
+ setupNewDisplayDeviceInternalTest<HdrHlgDisplayCase>();
+}
+
+TEST_F(SetupNewDisplayDeviceInternalTest, createHdrDolbyVisionDisplay) {
+ setupNewDisplayDeviceInternalTest<HdrDolbyVisionDisplayCase>();
+}
+
+/* ------------------------------------------------------------------------
+ * SurfaceFlinger::handleTransactionLocked(eDisplayTransactionNeeded)
+ */
+
+class HandleTransactionLockedTest : public DisplayTransactionTest {
+public:
+ template <typename Case>
+ void setupCommonPreconditions();
+
+ template <typename Case>
+ void setupCommonCallExpectationsForConnectProcessing();
+
+ template <typename Case>
+ void setupCommonCallExpectationsForDisconnectProcessing();
+
+ template <typename Case>
+ void processesHotplugConnectCommon();
+
+ template <typename Case>
+ void ignoresHotplugConnectCommon();
+
+ template <typename Case>
+ void processesHotplugDisconnectCommon();
+
+ template <typename Case>
+ void verifyDisplayIsConnected(const sp<IBinder>& displayToken);
+
+ template <typename Case>
+ void verifyPhysicalDisplayIsConnected();
+
+ void verifyDisplayIsNotConnected(const sp<IBinder>& displayToken);
+};
+
+template <typename Case>
+void HandleTransactionLockedTest::setupCommonPreconditions() {
+ // Wide color displays support is configured appropriately
+ Case::WideColorSupport::injectConfigChange(this);
+
+ // SurfaceFlinger will use a test-controlled factory for BufferQueues
+ injectFakeBufferQueueFactory();
+
+ // SurfaceFlinger will use a test-controlled factory for native window
+ // surfaces.
+ injectFakeNativeWindowSurfaceFactory();
+}
+
+template <typename Case>
+void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessing() {
+ Case::Display::setupHwcHotplugCallExpectations(this);
+
+ Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
+ Case::Display::setupFramebufferProducerBufferQueueCallExpectations(this);
+ Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
+ Case::Display::setupHwcGetActiveConfigCallExpectations(this);
+
+ Case::WideColorSupport::setupComposerCallExpectations(this);
+ Case::HdrSupport::setupComposerCallExpectations(this);
+
+ EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
+ EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::TYPE, true)).Times(1);
+}
+
+template <typename Case>
+void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() {
+ EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
+ EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::TYPE, false)).Times(1);
+}
+
+template <typename Case>
+void HandleTransactionLockedTest::verifyDisplayIsConnected(const sp<IBinder>& displayToken) {
+ // The display device should have been set up in the list of displays.
+ ASSERT_TRUE(hasDisplayDevice(displayToken));
+ const auto& device = getDisplayDevice(displayToken);
+ EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
+ EXPECT_EQ(Case::Display::TYPE == DisplayDevice::DISPLAY_PRIMARY, device->isPrimary());
+
+ // The display should have been set up in the current display state
+ ASSERT_TRUE(hasCurrentDisplayState(displayToken));
+ const auto& current = getCurrentDisplayState(displayToken);
+ EXPECT_EQ(Case::Display::TYPE, current.type);
+
+ // The display should have been set up in the drawing display state
+ ASSERT_TRUE(hasDrawingDisplayState(displayToken));
+ const auto& draw = getDrawingDisplayState(displayToken);
+ EXPECT_EQ(Case::Display::TYPE, draw.type);
+}
+
+template <typename Case>
+void HandleTransactionLockedTest::verifyPhysicalDisplayIsConnected() {
+ // HWComposer should have an entry for the display
+ EXPECT_TRUE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
+
+ // The display should be set up as a built-in display.
+ static_assert(0 <= Case::Display::TYPE &&
+ Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
+ "Must use a valid physical display type index for the fixed-size array");
+ auto& displayToken = mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE];
+ ASSERT_TRUE(displayToken != nullptr);
+
+ verifyDisplayIsConnected<Case>(displayToken);
+}
+
+void HandleTransactionLockedTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
+ EXPECT_FALSE(hasDisplayDevice(displayToken));
+ EXPECT_FALSE(hasCurrentDisplayState(displayToken));
+ EXPECT_FALSE(hasDrawingDisplayState(displayToken));
+}
+
+template <typename Case>
+void HandleTransactionLockedTest::processesHotplugConnectCommon() {
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ setupCommonPreconditions<Case>();
+
+ // A hotplug connect event is enqueued for a display
+ Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
// --------------------------------------------------------------------
// Call Expectations
EXPECT_CALL(*mComposer, isUsingVrComposer()).WillOnce(Return(false));
- expectHwcHotplugCalls(displayId, displayWidth, displayHeight);
- expectRESurfaceCreationCalls();
- expectPhysicalDisplayDeviceCreationCalls(displayId, displayWidth, displayHeight, true, false);
- EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
-
- EXPECT_CALL(*mEventThread, onHotplugReceived(DisplayDevice::DISPLAY_PRIMARY, true)).Times(1);
+ setupCommonCallExpectationsForConnectProcessing<Case>();
// --------------------------------------------------------------------
// Invocation
@@ -400,36 +885,362 @@
// --------------------------------------------------------------------
// Postconditions
- // HWComposer should have an entry for the display
- EXPECT_TRUE(mFlinger.mutableHwcDisplaySlots().count(displayId) == 1);
-
- // The display should have set up as a primary built-in display.
- auto displayToken = mFlinger.mutableBuiltinDisplays()[DisplayDevice::DISPLAY_PRIMARY];
- ASSERT_TRUE(displayToken != nullptr);
-
- // The display device should have been set up in the list of displays.
- ASSERT_TRUE(hasDisplayDevice(displayToken));
- const auto& device = getDisplayDevice(displayToken);
- EXPECT_TRUE(device->isSecure());
- EXPECT_TRUE(device->isPrimary());
-
- // The display should have been set up in the current display state
- ASSERT_TRUE(hasCurrentDisplayState(displayToken));
- const auto& current = getCurrentDisplayState(displayToken);
- EXPECT_EQ(DisplayDevice::DISPLAY_PRIMARY, current.type);
-
- // The display should have been set up in the drawing display state
- ASSERT_TRUE(hasDrawingDisplayState(displayToken));
- const auto& draw = getDrawingDisplayState(displayToken);
- EXPECT_EQ(DisplayDevice::DISPLAY_PRIMARY, draw.type);
+ verifyPhysicalDisplayIsConnected<Case>();
// --------------------------------------------------------------------
// Cleanup conditions
- EXPECT_CALL(*mComposer, setVsyncEnabled(displayId, IComposerClient::Vsync::DISABLE))
+ EXPECT_CALL(*mComposer,
+ setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
.WillOnce(Return(Error::NONE));
EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
}
+template <typename Case>
+void HandleTransactionLockedTest::ignoresHotplugConnectCommon() {
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ setupCommonPreconditions<Case>();
+
+ // A hotplug connect event is enqueued for a display
+ Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // HWComposer should not have an entry for the display
+ EXPECT_FALSE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
+}
+
+template <typename Case>
+void HandleTransactionLockedTest::processesHotplugDisconnectCommon() {
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ setupCommonPreconditions<Case>();
+
+ // A hotplug disconnect event is enqueued for a display
+ Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
+
+ // The display is already completely set up.
+ Case::Display::injectHwcDisplay(this);
+ auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
+ existing.inject();
+
+ // --------------------------------------------------------------------
+ // Call Expectations
+
+ EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
+
+ setupCommonCallExpectationsForDisconnectProcessing<Case>();
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // HWComposer should not have an entry for the display
+ EXPECT_FALSE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
+
+ // The display should not be set up as a built-in display.
+ ASSERT_TRUE(0 <= Case::Display::TYPE &&
+ Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES);
+ auto displayToken = mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE];
+ EXPECT_TRUE(displayToken == nullptr);
+
+ // The existing token should have been removed
+ verifyDisplayIsNotConnected(existing.token());
+}
+
+TEST_F(HandleTransactionLockedTest, processesHotplugConnectPrimaryDisplay) {
+ processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
+}
+
+TEST_F(HandleTransactionLockedTest,
+ processesHotplugConnectPrimaryDisplayWithExternalAlreadyConnected) {
+ // Inject an external display.
+ ExternalDisplayVariant::injectHwcDisplay(this);
+
+ processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
+}
+
+TEST_F(HandleTransactionLockedTest, processesHotplugConnectExternalDisplay) {
+ // Inject a primary display.
+ PrimaryDisplayVariant::injectHwcDisplay(this);
+
+ processesHotplugConnectCommon<SimpleExternalDisplayCase>();
+}
+
+TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
+ // Inject both a primary and external display.
+ PrimaryDisplayVariant::injectHwcDisplay(this);
+ ExternalDisplayVariant::injectHwcDisplay(this);
+
+ EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
+
+ ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
+}
+
+TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfExternalForVrComposer) {
+ // Inject a primary display.
+ PrimaryDisplayVariant::injectHwcDisplay(this);
+
+ EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(true));
+
+ ignoresHotplugConnectCommon<SimpleExternalDisplayCase>();
+}
+
+TEST_F(HandleTransactionLockedTest, processHotplugDisconnectPrimaryDisplay) {
+ processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>();
+}
+
+TEST_F(HandleTransactionLockedTest, processHotplugDisconnectExternalDisplay) {
+ processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
+}
+
+TEST_F(HandleTransactionLockedTest, processesHotplugConnectThenDisconnectPrimary) {
+ using Case = SimplePrimaryDisplayCase;
+
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ setupCommonPreconditions<Case>();
+
+ // A hotplug connect event is enqueued for a display
+ Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
+ // A hotplug disconnect event is also enqueued for the same display
+ Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
+
+ // --------------------------------------------------------------------
+ // Call Expectations
+
+ EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
+
+ setupCommonCallExpectationsForConnectProcessing<Case>();
+ setupCommonCallExpectationsForDisconnectProcessing<Case>();
+
+ EXPECT_CALL(*mComposer,
+ setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
+ .WillOnce(Return(Error::NONE));
+ EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // HWComposer should not have an entry for the display
+ EXPECT_FALSE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
+
+ // The display should not be set up as a primary built-in display.
+ ASSERT_TRUE(0 <= Case::Display::TYPE &&
+ Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES);
+ auto displayToken = mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE];
+ EXPECT_TRUE(displayToken == nullptr);
+}
+
+TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
+ using Case = SimplePrimaryDisplayCase;
+
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ setupCommonPreconditions<Case>();
+
+ // The display is already completely set up.
+ Case::Display::injectHwcDisplay(this);
+ auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
+ existing.inject();
+
+ // A hotplug disconnect event is enqueued for a display
+ Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
+ // A hotplug connect event is also enqueued for the same display
+ Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
+
+ // --------------------------------------------------------------------
+ // Call Expectations
+
+ EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
+
+ setupCommonCallExpectationsForConnectProcessing<Case>();
+ setupCommonCallExpectationsForDisconnectProcessing<Case>();
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // The existing token should have been removed
+ verifyDisplayIsNotConnected(existing.token());
+ static_assert(0 <= Case::Display::TYPE &&
+ Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
+ "Display type must be a built-in display");
+ EXPECT_NE(existing.token(), mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE]);
+
+ // A new display should be connected in its place
+
+ verifyPhysicalDisplayIsConnected<Case>();
+
+ // --------------------------------------------------------------------
+ // Cleanup conditions
+
+ EXPECT_CALL(*mComposer,
+ setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
+ .WillOnce(Return(Error::NONE));
+ EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
+}
+
+TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAdded) {
+ using Case = HwcVirtualDisplayCase;
+
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ // The HWC supports at least one virtual display
+ injectMockComposer(1);
+
+ setupCommonPreconditions<Case>();
+
+ // A virtual display was added to the current state, and it has a
+ // surface(producer)
+ sp<BBinder> displayToken = new BBinder();
+ DisplayDeviceState info;
+ info.type = Case::Display::TYPE;
+ info.isSecure = static_cast<bool>(Case::Display::SECURE);
+
+ sp<mock::GraphicBufferProducer> surface{new mock::GraphicBufferProducer()};
+ info.surface = surface;
+ mFlinger.mutableCurrentState().displays.add(displayToken, info);
+
+ // --------------------------------------------------------------------
+ // Call Expectations
+
+ Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
+ Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
+
+ EXPECT_CALL(*surface, query(NATIVE_WINDOW_WIDTH, _))
+ .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::WIDTH), Return(NO_ERROR)));
+ EXPECT_CALL(*surface, query(NATIVE_WINDOW_HEIGHT, _))
+ .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::HEIGHT), Return(NO_ERROR)));
+ EXPECT_CALL(*surface, query(NATIVE_WINDOW_FORMAT, _))
+ .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT),
+ Return(NO_ERROR)));
+ EXPECT_CALL(*surface, query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, _))
+ .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
+
+ EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
+
+ EXPECT_CALL(*mProducer, connect(_, _, _, _)).Times(1);
+ EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
+
+ Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
+ Case::WideColorSupport::setupComposerCallExpectations(this);
+ Case::HdrSupport::setupComposerCallExpectations(this);
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // The display device should have been set up in the list of displays.
+ verifyDisplayIsConnected<Case>(displayToken);
+
+ // --------------------------------------------------------------------
+ // Cleanup conditions
+
+ EXPECT_CALL(*mComposer, destroyVirtualDisplay(Case::Display::HWC_DISPLAY_ID))
+ .WillOnce(Return(Error::NONE));
+ EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
+}
+
+TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAddedWithNoSurface) {
+ using Case = HwcVirtualDisplayCase;
+
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ // The HWC supports at least one virtual display
+ injectMockComposer(1);
+
+ setupCommonPreconditions<Case>();
+
+ // A virtual display was added to the current state, but it does not have a
+ // surface.
+ sp<BBinder> displayToken = new BBinder();
+
+ DisplayDeviceState info;
+ info.type = Case::Display::TYPE;
+ info.isSecure = static_cast<bool>(Case::Display::SECURE);
+
+ mFlinger.mutableCurrentState().displays.add(displayToken, info);
+
+ // --------------------------------------------------------------------
+ // Call Expectations
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // There will not be a display device set up.
+ EXPECT_FALSE(hasDisplayDevice(displayToken));
+
+ // The drawing display state will be set from the current display state.
+ ASSERT_TRUE(hasDrawingDisplayState(displayToken));
+ const auto& draw = getDrawingDisplayState(displayToken);
+ EXPECT_EQ(Case::Display::TYPE, draw.type);
+}
+
+TEST_F(HandleTransactionLockedTest, processesVirtualDisplayRemoval) {
+ using Case = HwcVirtualDisplayCase;
+
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ // A virtual display is set up but is removed from the current state.
+ mFlinger.mutableHwcDisplayData().resize(3);
+ Case::Display::injectHwcDisplay(this);
+ auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
+ existing.inject();
+ mFlinger.mutableCurrentState().displays.removeItem(existing.token());
+
+ // --------------------------------------------------------------------
+ // Call Expectations
+
+ EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
+
+ // --------------------------------------------------------------------
+ // Invocation
+
+ mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
+
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // The existing token should have been removed
+ verifyDisplayIsNotConnected(existing.token());
+}
+
} // namespace
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 2dd8e5f..d3b637b 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -60,6 +60,14 @@
* Forwarding for functions being tested
*/
+ auto setupNewDisplayDeviceInternal(const wp<IBinder>& display, int hwcId,
+ const DisplayDeviceState& state,
+ const sp<DisplaySurface>& dispSurface,
+ const sp<IGraphicBufferProducer>& producer) {
+ return mFlinger->setupNewDisplayDeviceInternal(display, hwcId, state, dispSurface,
+ producer);
+ }
+
auto handleTransactionLocked(uint32_t transactionFlags) {
return mFlinger->handleTransactionLocked(transactionFlags);
}
@@ -69,9 +77,12 @@
* post-conditions.
*/
+ auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; }
+
auto& mutableBuiltinDisplays() { return mFlinger->mBuiltinDisplays; }
auto& mutableCurrentState() { return mFlinger->mCurrentState; }
auto& mutableDisplays() { return mFlinger->mDisplays; }
+ auto& mutableDisplayColorSetting() { return mFlinger->mDisplayColorSetting; }
auto& mutableDrawingState() { return mFlinger->mDrawingState; }
auto& mutableEventControlThread() { return mFlinger->mEventControlThread; }
auto& mutableEventQueue() { return mFlinger->mEventQueue; }
@@ -79,6 +90,7 @@
auto& mutableInterceptor() { return mFlinger->mInterceptor; }
auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
+ auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; }
auto& mutableHwcDisplayData() { return mFlinger->getBE().mHwc->mDisplayData; }
auto& mutableHwcDisplaySlots() { return mFlinger->getBE().mHwc->mHwcDisplaySlots; }
@@ -101,6 +113,7 @@
* Wrapper classes for Read-write access to private data to set up
* preconditions and assert post-conditions.
*/
+
struct HWC2Display : public HWC2::Display {
HWC2Display(Hwc2::Composer& composer,
const std::unordered_set<HWC2::Capability>& capabilities, hwc2_display_t id,
@@ -115,7 +128,163 @@
auto& mutableConfigs() { return this->mConfigs; }
};
+ class FakeHwcDisplayInjector {
+ public:
+ static constexpr hwc2_display_t DEFAULT_HWC_DISPLAY_ID = 1000;
+ static constexpr int32_t DEFAULT_WIDTH = 1920;
+ static constexpr int32_t DEFAULT_HEIGHT = 1280;
+ static constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
+ static constexpr int32_t DEFAULT_DPI = 320;
+ static constexpr int32_t DEFAULT_ACTIVE_CONFIG = 0;
+
+ FakeHwcDisplayInjector(DisplayDevice::DisplayType type, HWC2::DisplayType hwcDisplayType)
+ : mType(type), mHwcDisplayType(hwcDisplayType) {}
+
+ auto& setHwcDisplayId(hwc2_display_t displayId) {
+ mHwcDisplayId = displayId;
+ return *this;
+ }
+
+ auto& setWidth(int32_t width) {
+ mWidth = width;
+ return *this;
+ }
+
+ auto& setHeight(int32_t height) {
+ mHeight = height;
+ return *this;
+ }
+
+ auto& setRefreshRate(int32_t refreshRate) {
+ mRefreshRate = refreshRate;
+ return *this;
+ }
+
+ auto& setDpiX(int32_t dpi) {
+ mDpiX = dpi;
+ return *this;
+ }
+
+ auto& setDpiY(int32_t dpi) {
+ mDpiY = dpi;
+ return *this;
+ }
+
+ auto& setActiveConfig(int32_t config) {
+ mActiveConfig = config;
+ return *this;
+ }
+
+ auto& addCapability(HWC2::Capability cap) {
+ mCapabilities.emplace(cap);
+ return *this;
+ }
+
+ void inject(TestableSurfaceFlinger* flinger, Hwc2::Composer* composer) {
+ auto display = std::make_unique<HWC2Display>(*composer, mCapabilities, mHwcDisplayId,
+ mHwcDisplayType);
+
+ auto config = HWC2::Display::Config::Builder(*display, mActiveConfig);
+ config.setWidth(mWidth);
+ config.setHeight(mHeight);
+ config.setVsyncPeriod(mRefreshRate);
+ config.setDpiX(mDpiX);
+ config.setDpiY(mDpiY);
+ display->mutableConfigs().emplace(mActiveConfig, config.build());
+ display->mutableIsConnected() = true;
+
+ ASSERT_TRUE(flinger->mutableHwcDisplayData().size() > static_cast<size_t>(mType));
+ flinger->mutableHwcDisplayData()[mType].reset();
+ flinger->mutableHwcDisplayData()[mType].hwcDisplay = display.get();
+ flinger->mutableHwcDisplaySlots().emplace(mHwcDisplayId, mType);
+
+ flinger->mFakeHwcDisplays.push_back(std::move(display));
+ }
+
+ private:
+ DisplayDevice::DisplayType mType;
+ HWC2::DisplayType mHwcDisplayType;
+ hwc2_display_t mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID;
+ int32_t mWidth = DEFAULT_WIDTH;
+ int32_t mHeight = DEFAULT_HEIGHT;
+ int32_t mRefreshRate = DEFAULT_REFRESH_RATE;
+ int32_t mDpiX = DEFAULT_DPI;
+ int32_t mDpiY = DEFAULT_DPI;
+ int32_t mActiveConfig = DEFAULT_ACTIVE_CONFIG;
+ std::unordered_set<HWC2::Capability> mCapabilities;
+ };
+
+ class FakeDisplayDeviceInjector {
+ public:
+ FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger, DisplayDevice::DisplayType type,
+ int hwcId)
+ : mFlinger(flinger), mType(type), mHwcId(hwcId) {}
+
+ sp<IBinder> token() const { return mDisplayToken; }
+
+ DisplayDeviceState& mutableDrawingDisplayState() {
+ return mFlinger.mutableDrawingState().displays.editValueFor(mDisplayToken);
+ }
+
+ DisplayDeviceState& mutableCurrentDisplayState() {
+ return mFlinger.mutableCurrentState().displays.editValueFor(mDisplayToken);
+ }
+
+ auto& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
+ mNativeWindow = nativeWindow;
+ return *this;
+ }
+
+ auto& setDisplaySurface(const sp<DisplaySurface>& displaySurface) {
+ mDisplaySurface = displaySurface;
+ return *this;
+ }
+
+ auto& setRenderSurface(std::unique_ptr<RE::Surface> renderSurface) {
+ mRenderSurface = std::move(renderSurface);
+ return *this;
+ }
+
+ auto& setSecure(bool secure) {
+ mSecure = secure;
+ return *this;
+ }
+
+ sp<DisplayDevice> inject() {
+ sp<DisplayDevice> device =
+ new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, mSecure, mDisplayToken,
+ mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0,
+ 0, false, HdrCapabilities(), 0, HWC_POWER_MODE_NORMAL);
+ mFlinger.mutableDisplays().add(mDisplayToken, device);
+
+ DisplayDeviceState state;
+ state.type = mType;
+ state.isSecure = mSecure;
+ mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
+ mFlinger.mutableDrawingState().displays.add(mDisplayToken, state);
+
+ if (mType < DisplayDevice::DISPLAY_VIRTUAL) {
+ mFlinger.mutableBuiltinDisplays()[mType] = mDisplayToken;
+ }
+
+ return device;
+ }
+
+ private:
+ TestableSurfaceFlinger& mFlinger;
+ sp<BBinder> mDisplayToken = new BBinder();
+ DisplayDevice::DisplayType mType;
+ int mHwcId;
+ sp<ANativeWindow> mNativeWindow;
+ sp<DisplaySurface> mDisplaySurface;
+ std::unique_ptr<RE::Surface> mRenderSurface;
+ bool mSecure = false;
+ };
+
sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(SurfaceFlinger::SkipInitialization);
+
+ // We need to keep a reference to these so they are properly destroyed.
+ std::vector<std::unique_ptr<HWC2Display>> mFakeHwcDisplays;
};
} // namespace android