summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot2018-02-22 02:26:32 -0600
committerandroid-build-team Robot2018-02-22 02:26:32 -0600
commitabbf1e49f2e8fc29cc5db113c163201f8709712d (patch)
treee5dd7f99f1b70ee78a15c759596ec7b58888d5a1
parent5fc99d0d4886b9daf423872dbd8fcafc36931ab0 (diff)
parent0dd5a5870a0431233b54867d15a26138bb17a087 (diff)
downloadplatform-hardware-interfaces-abbf1e49f2e8fc29cc5db113c163201f8709712d.tar.gz
platform-hardware-interfaces-abbf1e49f2e8fc29cc5db113c163201f8709712d.tar.xz
platform-hardware-interfaces-abbf1e49f2e8fc29cc5db113c163201f8709712d.zip
Snap for 4615953 from 0dd5a5870a0431233b54867d15a26138bb17a087 to pi-release
Change-Id: I0ad9d8071b7f0d467a741607313c9d7af1be216e
-rw-r--r--authsecret/1.0/IAuthSecret.hal2
-rw-r--r--automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp28
-rw-r--r--automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h23
-rw-r--r--camera/device/3.4/default/ExternalCameraDevice.cpp2
-rw-r--r--camera/device/3.4/default/ExternalCameraDeviceSession.cpp321
-rw-r--r--camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h26
-rw-r--r--confirmationui/1.0/vts/OWNERS3
-rw-r--r--confirmationui/1.0/vts/functional/Android.bp30
-rw-r--r--confirmationui/1.0/vts/functional/VtsHalConfirmationUIV1_0TargetTest.cpp428
-rw-r--r--gnss/1.1/Android.bp1
-rw-r--r--gnss/1.1/IGnssMeasurement.hal2
-rw-r--r--gnss/1.1/IGnssMeasurementCallback.hal80
-rw-r--r--gnss/1.1/vts/functional/gnss_hal_test_cases.cpp4
-rw-r--r--graphics/composer/2.1/default/Android.bp43
-rw-r--r--graphics/composer/2.1/default/ComposerBase.h132
-rw-r--r--graphics/composer/2.1/default/ComposerClient.cpp1205
-rw-r--r--graphics/composer/2.1/default/ComposerClient.h225
-rw-r--r--graphics/composer/2.1/default/Hwc.cpp817
-rw-r--r--graphics/composer/2.1/default/Hwc.h242
-rw-r--r--graphics/composer/2.1/default/passthrough.cpp25
-rw-r--r--graphics/composer/2.1/utils/command-buffer/Android.bp11
-rw-r--r--graphics/composer/2.1/utils/hal/Android.bp37
-rw-r--r--graphics/composer/2.1/utils/hal/include/composer-hal/2.1/Composer.h157
-rw-r--r--graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h396
-rw-r--r--graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h594
-rw-r--r--graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerHal.h137
-rw-r--r--graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h536
-rw-r--r--graphics/composer/2.1/utils/hwc2on1adapter/Android.bp76
-rw-r--r--graphics/composer/2.1/utils/hwc2on1adapter/CleanSpec.mk52
-rw-r--r--graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp2637
-rw-r--r--graphics/composer/2.1/utils/hwc2on1adapter/MiniFence.cpp42
-rw-r--r--graphics/composer/2.1/utils/hwc2on1adapter/include/hwc2on1adapter/HWC2On1Adapter.h738
-rw-r--r--graphics/composer/2.1/utils/hwc2on1adapter/include/hwc2on1adapter/MiniFence.h59
-rw-r--r--graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp33
-rw-r--r--graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp887
-rw-r--r--graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h123
-rw-r--r--graphics/composer/2.1/utils/passthrough/Android.bp22
-rw-r--r--graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h670
-rw-r--r--graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h152
-rw-r--r--graphics/composer/2.1/utils/vts/Android.bp38
-rw-r--r--graphics/composer/2.1/utils/vts/ComposerVts.cpp324
-rw-r--r--graphics/composer/2.1/utils/vts/GraphicsComposerCallback.cpp (renamed from graphics/composer/2.1/vts/functional/GraphicsComposerCallback.cpp)71
-rw-r--r--graphics/composer/2.1/utils/vts/TestCommandReader.cpp62
-rw-r--r--graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h126
-rw-r--r--graphics/composer/2.1/utils/vts/include/composer-vts/2.1/GraphicsComposerCallback.h (renamed from graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h)47
-rw-r--r--graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h (renamed from graphics/composer/2.1/vts/functional/TestCommandReader.h)17
-rw-r--r--graphics/composer/2.1/vts/functional/Android.bp33
-rw-r--r--graphics/composer/2.1/vts/functional/TestCommandReader.cpp62
-rw-r--r--graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp345
-rw-r--r--graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.h134
-rw-r--r--graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp681
-rw-r--r--graphics/composer/2.2/default/Android.bp31
-rw-r--r--graphics/composer/2.2/default/OWNERS5
-rw-r--r--graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc6
-rw-r--r--graphics/composer/2.2/default/service.cpp55
-rw-r--r--graphics/composer/2.2/utils/hal/Android.bp35
-rw-r--r--graphics/composer/2.2/utils/hal/include/composer-hal/2.2/Composer.h74
-rw-r--r--graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h162
-rw-r--r--graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h103
-rw-r--r--graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h66
-rw-r--r--graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerResources.h105
-rw-r--r--graphics/composer/2.2/utils/passthrough/Android.bp14
-rw-r--r--graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h208
-rw-r--r--graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h79
-rw-r--r--graphics/composer/2.2/utils/vts/Android.bp39
-rw-r--r--graphics/composer/2.2/utils/vts/ComposerVts.cpp (renamed from graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerTestUtils.cpp)16
-rw-r--r--graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h (renamed from graphics/composer/2.2/vts/functional/include/2.2/VtsHalGraphicsComposerTestUtils.h)18
-rw-r--r--graphics/composer/2.2/vts/functional/Android.bp38
-rw-r--r--graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp25
-rw-r--r--neuralnetworks/1.1/types.hal8
70 files changed, 10198 insertions, 3827 deletions
diff --git a/authsecret/1.0/IAuthSecret.hal b/authsecret/1.0/IAuthSecret.hal
index 6b573b3a..9a0fd5fd 100644
--- a/authsecret/1.0/IAuthSecret.hal
+++ b/authsecret/1.0/IAuthSecret.hal
@@ -42,5 +42,5 @@ interface IAuthSecret {
42 * 42 *
43 * @param secret blob derived from the primary user's credential. 43 * @param secret blob derived from the primary user's credential.
44 */ 44 */
45 primaryUserCredential(vec<uint8_t> secret); 45 oneway primaryUserCredential(vec<uint8_t> secret);
46}; 46};
diff --git a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp
index 57050d75..d904ad06 100644
--- a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp
+++ b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp
@@ -54,7 +54,7 @@ static const float kNanoToSeconds = 0.000000001f;
54#include <android/hardware/automotive/evs/1.0/IEvsDisplay.h> 54#include <android/hardware/automotive/evs/1.0/IEvsDisplay.h>
55 55
56#include <VtsHalHidlTargetTestBase.h> 56#include <VtsHalHidlTargetTestBase.h>
57 57#include <VtsHalHidlTargetTestEnvBase.h>
58 58
59using namespace ::android::hardware::automotive::evs::V1_0; 59using namespace ::android::hardware::automotive::evs::V1_0;
60using ::android::hardware::Return; 60using ::android::hardware::Return;
@@ -64,13 +64,28 @@ using ::android::hardware::hidl_handle;
64using ::android::hardware::hidl_string; 64using ::android::hardware::hidl_string;
65using ::android::sp; 65using ::android::sp;
66 66
67// Test environment for Evs HIDL HAL.
68class EvsHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
69 public:
70 // get the test environment singleton
71 static EvsHidlEnvironment* Instance() {
72 static EvsHidlEnvironment* instance = new EvsHidlEnvironment;
73 return instance;
74 }
75
76 virtual void registerTestServices() override { registerTestService<IEvsEnumerator>(); }
77
78 private:
79 EvsHidlEnvironment() {}
80};
67 81
68// The main test class for EVS 82// The main test class for EVS
69class EvsHidlTest : public ::testing::VtsHalHidlTargetTestBase { 83class EvsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
70public: 84public:
71 virtual void SetUp() override { 85 virtual void SetUp() override {
72 // Make sure we can connect to the enumerator 86 // Make sure we can connect to the enumerator
73 pEnumerator = IEvsEnumerator::getService(kEnumeratorName); 87 pEnumerator = getService<IEvsEnumerator>(
88 EvsHidlEnvironment::Instance()->getServiceName<IEvsEnumerator>(kEnumeratorName));
74 ASSERT_NE(pEnumerator.get(), nullptr); 89 ASSERT_NE(pEnumerator.get(), nullptr);
75 } 90 }
76 91
@@ -480,3 +495,12 @@ TEST_F(EvsHidlTest, CameraToDisplayRoundTrip) {
480 // Explicitly release the display 495 // Explicitly release the display
481 pEnumerator->closeDisplay(pDisplay); 496 pEnumerator->closeDisplay(pDisplay);
482} 497}
498
499int main(int argc, char** argv) {
500 ::testing::AddGlobalTestEnvironment(EvsHidlEnvironment::Instance());
501 ::testing::InitGoogleTest(&argc, argv);
502 EvsHidlEnvironment::Instance()->init(&argc, argv);
503 int status = RUN_ALL_TESTS();
504 ALOGI("Test result = %d", status);
505 return status;
506}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 7938b731..096500e1 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -342,12 +342,6 @@ const ConfigDeclaration kVehicleProperties[]{
342 }, 342 },
343 .initialValue = {.int32Values = {toInt(VehicleGear::GEAR_PARK)}}}, 343 .initialValue = {.int32Values = {toInt(VehicleGear::GEAR_PARK)}}},
344 344
345 {.config = {.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
346 .access = VehiclePropertyAccess::READ_WRITE,
347 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
348 .areaConfigs = {VehicleAreaConfig{.minInt32Value = 0, .maxInt32Value = 10}}},
349 .initialValue = {.int32Values = {7}}},
350
351 {.config = 345 {.config =
352 { 346 {
353 .prop = toInt(VehicleProperty::IGNITION_STATE), 347 .prop = toInt(VehicleProperty::IGNITION_STATE),
@@ -420,6 +414,23 @@ const ConfigDeclaration kVehicleProperties[]{
420 }, 414 },
421 }, 415 },
422 416
417 {.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE),
418 .access = VehiclePropertyAccess::READ_WRITE,
419 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
420 .configArray = {3}},
421 .initialValue = {.int32Values = {toInt(VehicleApPowerState::ON_FULL), 0}}},
422
423 {.config = {.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
424 .access = VehiclePropertyAccess::READ_WRITE,
425 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
426 .areaConfigs = {VehicleAreaConfig{.minInt32Value = 0, .maxInt32Value = 100}}},
427 .initialValue = {.int32Values = {100}}},
428
429 {.config = {.prop = toInt(VehicleProperty::AP_POWER_BOOTUP_REASON),
430 .access = VehiclePropertyAccess::READ,
431 .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
432 .initialValue = {.int32Values = {toInt(VehicleApPowerBootupReason::USER_POWER_ON)}}},
433
423 { 434 {
424 .config = {.prop = OBD2_LIVE_FRAME, 435 .config = {.prop = OBD2_LIVE_FRAME,
425 .access = VehiclePropertyAccess::READ, 436 .access = VehiclePropertyAccess::READ,
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index b6470f5e..14f82bcf 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -131,7 +131,7 @@ Return<void> ExternalCameraDevice::open(
131 131
132 session = new ExternalCameraDeviceSession( 132 session = new ExternalCameraDeviceSession(
133 callback, mCfg, mSupportedFormats, mCroppingType, 133 callback, mCfg, mSupportedFormats, mCroppingType,
134 mCameraCharacteristics, std::move(fd)); 134 mCameraCharacteristics, mCameraId, std::move(fd));
135 if (session == nullptr) { 135 if (session == nullptr) {
136 ALOGE("%s: camera device session allocation failed", __FUNCTION__); 136 ALOGE("%s: camera device session allocation failed", __FUNCTION__);
137 mLock.unlock(); 137 mLock.unlock();
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index d6d9ff89..5346f803 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -46,6 +46,21 @@ const int kBadFramesAfterStreamOn = 1; // drop x frames after streamOn to get ri
46 // bad frames. TODO: develop a better bad frame detection 46 // bad frames. TODO: develop a better bad frame detection
47 // method 47 // method
48 48
49bool tryLock(Mutex& mutex)
50{
51 static const int kDumpLockRetries = 50;
52 static const int kDumpLockSleep = 60000;
53 bool locked = false;
54 for (int i = 0; i < kDumpLockRetries; ++i) {
55 if (mutex.tryLock() == NO_ERROR) {
56 locked = true;
57 break;
58 }
59 usleep(kDumpLockSleep);
60 }
61 return locked;
62}
63
49} // Anonymous namespace 64} // Anonymous namespace
50 65
51// Static instances 66// Static instances
@@ -59,12 +74,14 @@ ExternalCameraDeviceSession::ExternalCameraDeviceSession(
59 const std::vector<SupportedV4L2Format>& sortedFormats, 74 const std::vector<SupportedV4L2Format>& sortedFormats,
60 const CroppingType& croppingType, 75 const CroppingType& croppingType,
61 const common::V1_0::helper::CameraMetadata& chars, 76 const common::V1_0::helper::CameraMetadata& chars,
77 const std::string& cameraId,
62 unique_fd v4l2Fd) : 78 unique_fd v4l2Fd) :
63 mCallback(callback), 79 mCallback(callback),
64 mCfg(cfg), 80 mCfg(cfg),
65 mCameraCharacteristics(chars), 81 mCameraCharacteristics(chars),
66 mSupportedFormats(sortedFormats), 82 mSupportedFormats(sortedFormats),
67 mCroppingType(croppingType), 83 mCroppingType(croppingType),
84 mCameraId(cameraId),
68 mV4l2Fd(std::move(v4l2Fd)), 85 mV4l2Fd(std::move(v4l2Fd)),
69 mOutputThread(new OutputThread(this, mCroppingType)), 86 mOutputThread(new OutputThread(this, mCroppingType)),
70 mMaxThumbResolution(getMaxThumbResolution()), 87 mMaxThumbResolution(getMaxThumbResolution()),
@@ -119,8 +136,79 @@ ExternalCameraDeviceSession::~ExternalCameraDeviceSession() {
119 } 136 }
120} 137}
121 138
122void ExternalCameraDeviceSession::dumpState(const native_handle_t*) { 139
123 // TODO: b/72261676 dump more runtime information 140void ExternalCameraDeviceSession::dumpState(const native_handle_t* handle) {
141 if (handle->numFds != 1 || handle->numInts != 0) {
142 ALOGE("%s: handle must contain 1 FD and 0 integers! Got %d FDs and %d ints",
143 __FUNCTION__, handle->numFds, handle->numInts);
144 return;
145 }
146 int fd = handle->data[0];
147
148 bool intfLocked = tryLock(mInterfaceLock);
149 if (!intfLocked) {
150 dprintf(fd, "!! ExternalCameraDeviceSession interface may be deadlocked !!\n");
151 }
152
153 if (isClosed()) {
154 dprintf(fd, "External camera %s is closed\n", mCameraId.c_str());
155 return;
156 }
157
158 bool streaming = false;
159 size_t v4L2BufferCount = 0;
160 SupportedV4L2Format streamingFmt;
161 std::unordered_set<uint32_t> inflightFrames;
162 {
163 Mutex::Autolock _l(mLock);
164 bool sessionLocked = tryLock(mLock);
165 if (!sessionLocked) {
166 dprintf(fd, "!! ExternalCameraDeviceSession mLock may be deadlocked !!\n");
167 }
168 streaming = mV4l2Streaming;
169 streamingFmt = mV4l2StreamingFmt;
170 v4L2BufferCount = mV4L2BufferCount;
171 inflightFrames = mInflightFrames;
172 if (sessionLocked) {
173 mLock.unlock();
174 }
175 }
176
177 dprintf(fd, "External camera %s V4L2 FD %d, cropping type %s, %s\n",
178 mCameraId.c_str(), mV4l2Fd.get(),
179 (mCroppingType == VERTICAL) ? "vertical" : "horizontal",
180 streaming ? "streaming" : "not streaming");
181 if (streaming) {
182 // TODO: dump fps later
183 dprintf(fd, "Current V4L2 format %c%c%c%c %dx%d\n",
184 streamingFmt.fourcc & 0xFF,
185 (streamingFmt.fourcc >> 8) & 0xFF,
186 (streamingFmt.fourcc >> 16) & 0xFF,
187 (streamingFmt.fourcc >> 24) & 0xFF,
188 streamingFmt.width, streamingFmt.height);
189
190 size_t numDequeuedV4l2Buffers = 0;
191 {
192 std::lock_guard<std::mutex> lk(mV4l2BufferLock);
193 numDequeuedV4l2Buffers = mNumDequeuedV4l2Buffers;
194 }
195 dprintf(fd, "V4L2 buffer queue size %zu, dequeued %zu\n",
196 v4L2BufferCount, numDequeuedV4l2Buffers);
197 }
198
199 dprintf(fd, "In-flight frames (not sorted):");
200 for (const auto& frameNumber : inflightFrames) {
201 dprintf(fd, "%d, ", frameNumber);
202 }
203 dprintf(fd, "\n");
204 mOutputThread->dump(fd);
205 dprintf(fd, "\n");
206
207 if (intfLocked) {
208 mInterfaceLock.unlock();
209 }
210
211 return;
124} 212}
125 213
126Return<void> ExternalCameraDeviceSession::constructDefaultRequestSettings( 214Return<void> ExternalCameraDeviceSession::constructDefaultRequestSettings(
@@ -281,21 +369,20 @@ Return<Status> ExternalCameraDeviceSession::flush() {
281 369
282Return<void> ExternalCameraDeviceSession::close() { 370Return<void> ExternalCameraDeviceSession::close() {
283 Mutex::Autolock _il(mInterfaceLock); 371 Mutex::Autolock _il(mInterfaceLock);
284 Mutex::Autolock _l(mLock); 372 bool closed = isClosed();
285 if (!mClosed) { 373 if (!closed) {
286 // TODO: b/72261676 Cleanup inflight buffers/V4L2 buffer queue 374 mOutputThread->flush();
287 ALOGV("%s: closing V4L2 camera FD %d", __FUNCTION__, mV4l2Fd.get()); 375 mOutputThread->requestExit();
288 mV4l2Fd.reset(); 376 mOutputThread->join();
289 mOutputThread->requestExit(); // TODO: join?
290 377
291 // free all imported buffers 378 Mutex::Autolock _l(mLock);
292 for(auto& pair : mCirculatingBuffers) { 379 // free all buffers
293 CirculatingBuffers& buffers = pair.second; 380 for(auto pair : mStreamMap) {
294 for (auto& p2 : buffers) { 381 cleanupBuffersLocked(/*Stream ID*/pair.first);
295 sHandleImporter.freeBuffer(p2.second);
296 }
297 } 382 }
298 383 v4l2StreamOffLocked();
384 ALOGV("%s: closing V4L2 camera FD %d", __FUNCTION__, mV4l2Fd.get());
385 mV4l2Fd.reset();
299 mClosed = true; 386 mClosed = true;
300 } 387 }
301 return Void(); 388 return Void();
@@ -431,25 +518,22 @@ Status ExternalCameraDeviceSession::processOneCaptureRequest(const CaptureReques
431 // TODO: program fps range per capture request here 518 // TODO: program fps range per capture request here
432 // or limit the set of availableFpsRange 519 // or limit the set of availableFpsRange
433 520
434 sp<V4L2Frame> frameIn = dequeueV4l2FrameLocked(); 521
522 nsecs_t shutterTs = 0;
523 sp<V4L2Frame> frameIn = dequeueV4l2FrameLocked(&shutterTs);
435 if ( frameIn == nullptr) { 524 if ( frameIn == nullptr) {
436 ALOGE("%s: V4L2 deque frame failed!", __FUNCTION__); 525 ALOGE("%s: V4L2 deque frame failed!", __FUNCTION__);
437 return Status::INTERNAL_ERROR; 526 return Status::INTERNAL_ERROR;
438 } 527 }
439 // TODO: This can probably be replaced by use v4lbuffer timestamp
440 // if the device supports it
441 nsecs_t shutterTs = systemTime(SYSTEM_TIME_MONOTONIC);
442 528
443 529 std::shared_ptr<HalRequest> halReq = std::make_shared<HalRequest>();
444 // TODO: reduce object copy in this path 530 halReq->frameNumber = request.frameNumber;
445 HalRequest halReq = { 531 halReq->setting = mLatestReqSetting;
446 .frameNumber = request.frameNumber, 532 halReq->frameIn = frameIn;
447 .setting = mLatestReqSetting, 533 halReq->shutterTs = shutterTs;
448 .frameIn = frameIn, 534 halReq->buffers.resize(numOutputBufs);
449 .shutterTs = shutterTs};
450 halReq.buffers.resize(numOutputBufs);
451 for (size_t i = 0; i < numOutputBufs; i++) { 535 for (size_t i = 0; i < numOutputBufs; i++) {
452 HalStreamBuffer& halBuf = halReq.buffers[i]; 536 HalStreamBuffer& halBuf = halReq->buffers[i];
453 int streamId = halBuf.streamId = request.outputBuffers[i].streamId; 537 int streamId = halBuf.streamId = request.outputBuffers[i].streamId;
454 halBuf.bufferId = request.outputBuffers[i].bufferId; 538 halBuf.bufferId = request.outputBuffers[i].bufferId;
455 const Stream& stream = mStreamMap[streamId]; 539 const Stream& stream = mStreamMap[streamId];
@@ -461,7 +545,7 @@ Status ExternalCameraDeviceSession::processOneCaptureRequest(const CaptureReques
461 halBuf.acquireFence = allFences[i]; 545 halBuf.acquireFence = allFences[i];
462 halBuf.fenceTimeout = false; 546 halBuf.fenceTimeout = false;
463 } 547 }
464 mInflightFrames.insert(halReq.frameNumber); 548 mInflightFrames.insert(halReq->frameNumber);
465 // Send request to OutputThread for the rest of processing 549 // Send request to OutputThread for the rest of processing
466 mOutputThread->submitRequest(halReq); 550 mOutputThread->submitRequest(halReq);
467 mFirstRequest = false; 551 mFirstRequest = false;
@@ -487,30 +571,31 @@ void ExternalCameraDeviceSession::notifyError(
487} 571}
488 572
489//TODO: refactor with processCaptureResult 573//TODO: refactor with processCaptureResult
490Status ExternalCameraDeviceSession::processCaptureRequestError(const HalRequest& req) { 574Status ExternalCameraDeviceSession::processCaptureRequestError(
575 const std::shared_ptr<HalRequest>& req) {
491 // Return V4L2 buffer to V4L2 buffer queue 576 // Return V4L2 buffer to V4L2 buffer queue
492 enqueueV4l2Frame(req.frameIn); 577 enqueueV4l2Frame(req->frameIn);
493 578
494 // NotifyShutter 579 // NotifyShutter
495 notifyShutter(req.frameNumber, req.shutterTs); 580 notifyShutter(req->frameNumber, req->shutterTs);
496 581
497 notifyError(/*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_REQUEST); 582 notifyError(/*frameNum*/req->frameNumber, /*stream*/-1, ErrorCode::ERROR_REQUEST);
498 583
499 // Fill output buffers 584 // Fill output buffers
500 hidl_vec<CaptureResult> results; 585 hidl_vec<CaptureResult> results;
501 results.resize(1); 586 results.resize(1);
502 CaptureResult& result = results[0]; 587 CaptureResult& result = results[0];
503 result.frameNumber = req.frameNumber; 588 result.frameNumber = req->frameNumber;
504 result.partialResult = 1; 589 result.partialResult = 1;
505 result.inputBuffer.streamId = -1; 590 result.inputBuffer.streamId = -1;
506 result.outputBuffers.resize(req.buffers.size()); 591 result.outputBuffers.resize(req->buffers.size());
507 for (size_t i = 0; i < req.buffers.size(); i++) { 592 for (size_t i = 0; i < req->buffers.size(); i++) {
508 result.outputBuffers[i].streamId = req.buffers[i].streamId; 593 result.outputBuffers[i].streamId = req->buffers[i].streamId;
509 result.outputBuffers[i].bufferId = req.buffers[i].bufferId; 594 result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
510 result.outputBuffers[i].status = BufferStatus::ERROR; 595 result.outputBuffers[i].status = BufferStatus::ERROR;
511 if (req.buffers[i].acquireFence >= 0) { 596 if (req->buffers[i].acquireFence >= 0) {
512 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0); 597 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
513 handle->data[0] = req.buffers[i].acquireFence; 598 handle->data[0] = req->buffers[i].acquireFence;
514 result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false); 599 result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false);
515 } 600 }
516 } 601 }
@@ -518,7 +603,7 @@ Status ExternalCameraDeviceSession::processCaptureRequestError(const HalRequest&
518 // update inflight records 603 // update inflight records
519 { 604 {
520 Mutex::Autolock _l(mLock); 605 Mutex::Autolock _l(mLock);
521 mInflightFrames.erase(req.frameNumber); 606 mInflightFrames.erase(req->frameNumber);
522 } 607 }
523 608
524 // Callback into framework 609 // Callback into framework
@@ -527,51 +612,51 @@ Status ExternalCameraDeviceSession::processCaptureRequestError(const HalRequest&
527 return Status::OK; 612 return Status::OK;
528} 613}
529 614
530Status ExternalCameraDeviceSession::processCaptureResult(HalRequest& req) { 615Status ExternalCameraDeviceSession::processCaptureResult(std::shared_ptr<HalRequest>& req) {
531 // Return V4L2 buffer to V4L2 buffer queue 616 // Return V4L2 buffer to V4L2 buffer queue
532 enqueueV4l2Frame(req.frameIn); 617 enqueueV4l2Frame(req->frameIn);
533 618
534 // NotifyShutter 619 // NotifyShutter
535 notifyShutter(req.frameNumber, req.shutterTs); 620 notifyShutter(req->frameNumber, req->shutterTs);
536 621
537 // Fill output buffers 622 // Fill output buffers
538 hidl_vec<CaptureResult> results; 623 hidl_vec<CaptureResult> results;
539 results.resize(1); 624 results.resize(1);
540 CaptureResult& result = results[0]; 625 CaptureResult& result = results[0];
541 result.frameNumber = req.frameNumber; 626 result.frameNumber = req->frameNumber;
542 result.partialResult = 1; 627 result.partialResult = 1;
543 result.inputBuffer.streamId = -1; 628 result.inputBuffer.streamId = -1;
544 result.outputBuffers.resize(req.buffers.size()); 629 result.outputBuffers.resize(req->buffers.size());
545 for (size_t i = 0; i < req.buffers.size(); i++) { 630 for (size_t i = 0; i < req->buffers.size(); i++) {
546 result.outputBuffers[i].streamId = req.buffers[i].streamId; 631 result.outputBuffers[i].streamId = req->buffers[i].streamId;
547 result.outputBuffers[i].bufferId = req.buffers[i].bufferId; 632 result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
548 if (req.buffers[i].fenceTimeout) { 633 if (req->buffers[i].fenceTimeout) {
549 result.outputBuffers[i].status = BufferStatus::ERROR; 634 result.outputBuffers[i].status = BufferStatus::ERROR;
550 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0); 635 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
551 handle->data[0] = req.buffers[i].acquireFence; 636 handle->data[0] = req->buffers[i].acquireFence;
552 result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false); 637 result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false);
553 notifyError(req.frameNumber, req.buffers[i].streamId, ErrorCode::ERROR_BUFFER); 638 notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
554 } else { 639 } else {
555 result.outputBuffers[i].status = BufferStatus::OK; 640 result.outputBuffers[i].status = BufferStatus::OK;
556 // TODO: refactor 641 // TODO: refactor
557 if (req.buffers[i].acquireFence > 0) { 642 if (req->buffers[i].acquireFence > 0) {
558 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0); 643 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
559 handle->data[0] = req.buffers[i].acquireFence; 644 handle->data[0] = req->buffers[i].acquireFence;
560 result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false); 645 result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false);
561 } 646 }
562 } 647 }
563 } 648 }
564 649
565 // Fill capture result metadata 650 // Fill capture result metadata
566 fillCaptureResult(req.setting, req.shutterTs); 651 fillCaptureResult(req->setting, req->shutterTs);
567 const camera_metadata_t *rawResult = req.setting.getAndLock(); 652 const camera_metadata_t *rawResult = req->setting.getAndLock();
568 V3_2::implementation::convertToHidl(rawResult, &result.result); 653 V3_2::implementation::convertToHidl(rawResult, &result.result);
569 req.setting.unlock(rawResult); 654 req->setting.unlock(rawResult);
570 655
571 // update inflight records 656 // update inflight records
572 { 657 {
573 Mutex::Autolock _l(mLock); 658 Mutex::Autolock _l(mLock);
574 mInflightFrames.erase(req.frameNumber); 659 mInflightFrames.erase(req->frameNumber);
575 } 660 }
576 661
577 // Callback into framework 662 // Callback into framework
@@ -1302,7 +1387,7 @@ ssize_t ExternalCameraDeviceSession::getJpegBufferSize(
1302 1387
1303int ExternalCameraDeviceSession::OutputThread::createJpegLocked( 1388int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
1304 HalStreamBuffer &halBuf, 1389 HalStreamBuffer &halBuf,
1305 HalRequest &req) 1390 const std::shared_ptr<HalRequest>& req)
1306{ 1391{
1307 int ret; 1392 int ret;
1308 auto lfail = [&](auto... args) { 1393 auto lfail = [&](auto... args) {
@@ -1329,17 +1414,17 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
1329 int jpegQuality, thumbQuality; 1414 int jpegQuality, thumbQuality;
1330 Size thumbSize; 1415 Size thumbSize;
1331 1416
1332 if (req.setting.exists(ANDROID_JPEG_QUALITY)) { 1417 if (req->setting.exists(ANDROID_JPEG_QUALITY)) {
1333 camera_metadata_entry entry = 1418 camera_metadata_entry entry =
1334 req.setting.find(ANDROID_JPEG_QUALITY); 1419 req->setting.find(ANDROID_JPEG_QUALITY);
1335 jpegQuality = entry.data.u8[0]; 1420 jpegQuality = entry.data.u8[0];
1336 } else { 1421 } else {
1337 return lfail("%s: ANDROID_JPEG_QUALITY not set",__FUNCTION__); 1422 return lfail("%s: ANDROID_JPEG_QUALITY not set",__FUNCTION__);
1338 } 1423 }
1339 1424
1340 if (req.setting.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) { 1425 if (req->setting.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) {
1341 camera_metadata_entry entry = 1426 camera_metadata_entry entry =
1342 req.setting.find(ANDROID_JPEG_THUMBNAIL_QUALITY); 1427 req->setting.find(ANDROID_JPEG_THUMBNAIL_QUALITY);
1343 thumbQuality = entry.data.u8[0]; 1428 thumbQuality = entry.data.u8[0];
1344 } else { 1429 } else {
1345 return lfail( 1430 return lfail(
@@ -1347,9 +1432,9 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
1347 __FUNCTION__); 1432 __FUNCTION__);
1348 } 1433 }
1349 1434
1350 if (req.setting.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) { 1435 if (req->setting.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
1351 camera_metadata_entry entry = 1436 camera_metadata_entry entry =
1352 req.setting.find(ANDROID_JPEG_THUMBNAIL_SIZE); 1437 req->setting.find(ANDROID_JPEG_THUMBNAIL_SIZE);
1353 thumbSize = Size { static_cast<uint32_t>(entry.data.i32[0]), 1438 thumbSize = Size { static_cast<uint32_t>(entry.data.i32[0]),
1354 static_cast<uint32_t>(entry.data.i32[1]) 1439 static_cast<uint32_t>(entry.data.i32[1])
1355 }; 1440 };
@@ -1409,7 +1494,7 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
1409 /* Combine camera characteristics with request settings to form EXIF 1494 /* Combine camera characteristics with request settings to form EXIF
1410 * metadata */ 1495 * metadata */
1411 common::V1_0::helper::CameraMetadata meta(parent->mCameraCharacteristics); 1496 common::V1_0::helper::CameraMetadata meta(parent->mCameraCharacteristics);
1412 meta.append(req.setting); 1497 meta.append(req->setting);
1413 1498
1414 /* Generate EXIF object */ 1499 /* Generate EXIF object */
1415 std::unique_ptr<ExifUtils> utils(ExifUtils::create()); 1500 std::unique_ptr<ExifUtils> utils(ExifUtils::create());
@@ -1473,7 +1558,7 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
1473} 1558}
1474 1559
1475bool ExternalCameraDeviceSession::OutputThread::threadLoop() { 1560bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
1476 HalRequest req; 1561 std::shared_ptr<HalRequest> req;
1477 auto parent = mParent.promote(); 1562 auto parent = mParent.promote();
1478 if (parent == nullptr) { 1563 if (parent == nullptr) {
1479 ALOGE("%s: session has been disconnected!", __FUNCTION__); 1564 ALOGE("%s: session has been disconnected!", __FUNCTION__);
@@ -1484,7 +1569,7 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
1484 // regularly to prevent v4l buffer queue filled with stale buffers 1569 // regularly to prevent v4l buffer queue filled with stale buffers
1485 // when app doesn't program a preveiw request 1570 // when app doesn't program a preveiw request
1486 waitForNextRequest(&req); 1571 waitForNextRequest(&req);
1487 if (req.frameIn == nullptr) { 1572 if (req == nullptr) {
1488 // No new request, wait again 1573 // No new request, wait again
1489 return true; 1574 return true;
1490 } 1575 }
@@ -1492,17 +1577,17 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
1492 auto onDeviceError = [&](auto... args) { 1577 auto onDeviceError = [&](auto... args) {
1493 ALOGE(args...); 1578 ALOGE(args...);
1494 parent->notifyError( 1579 parent->notifyError(
1495 req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE); 1580 req->frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
1496 signalRequestDone(); 1581 signalRequestDone();
1497 return false; 1582 return false;
1498 }; 1583 };
1499 1584
1500 if (req.frameIn->mFourcc != V4L2_PIX_FMT_MJPEG) { 1585 if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG) {
1501 return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__, 1586 return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
1502 req.frameIn->mFourcc & 0xFF, 1587 req->frameIn->mFourcc & 0xFF,
1503 (req.frameIn->mFourcc >> 8) & 0xFF, 1588 (req->frameIn->mFourcc >> 8) & 0xFF,
1504 (req.frameIn->mFourcc >> 16) & 0xFF, 1589 (req->frameIn->mFourcc >> 16) & 0xFF,
1505 (req.frameIn->mFourcc >> 24) & 0xFF); 1590 (req->frameIn->mFourcc >> 24) & 0xFF);
1506 } 1591 }
1507 1592
1508 std::unique_lock<std::mutex> lk(mBufferLock); 1593 std::unique_lock<std::mutex> lk(mBufferLock);
@@ -1510,7 +1595,7 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
1510 // TODO: see if we can save some computation by converting to YV12 here 1595 // TODO: see if we can save some computation by converting to YV12 here
1511 uint8_t* inData; 1596 uint8_t* inData;
1512 size_t inDataSize; 1597 size_t inDataSize;
1513 req.frameIn->map(&inData, &inDataSize); 1598 req->frameIn->map(&inData, &inDataSize);
1514 // TODO: profile 1599 // TODO: profile
1515 // TODO: in some special case maybe we can decode jpg directly to gralloc output? 1600 // TODO: in some special case maybe we can decode jpg directly to gralloc output?
1516 int res = libyuv::MJPGToI420( 1601 int res = libyuv::MJPGToI420(
@@ -1538,7 +1623,7 @@ bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
1538 1623
1539 ALOGV("%s processing new request", __FUNCTION__); 1624 ALOGV("%s processing new request", __FUNCTION__);
1540 const int kSyncWaitTimeoutMs = 500; 1625 const int kSyncWaitTimeoutMs = 500;
1541 for (auto& halBuf : req.buffers) { 1626 for (auto& halBuf : req->buffers) {
1542 if (halBuf.acquireFence != -1) { 1627 if (halBuf.acquireFence != -1) {
1543 int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs); 1628 int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs);
1544 if (ret) { 1629 if (ret) {
@@ -1695,9 +1780,9 @@ Status ExternalCameraDeviceSession::OutputThread::allocateIntermediateBuffers(
1695 return Status::OK; 1780 return Status::OK;
1696} 1781}
1697 1782
1698Status ExternalCameraDeviceSession::OutputThread::submitRequest(const HalRequest& req) { 1783Status ExternalCameraDeviceSession::OutputThread::submitRequest(
1784 const std::shared_ptr<HalRequest>& req) {
1699 std::unique_lock<std::mutex> lk(mRequestListLock); 1785 std::unique_lock<std::mutex> lk(mRequestListLock);
1700 // TODO: reduce object copy in this path
1701 mRequestList.push_back(req); 1786 mRequestList.push_back(req);
1702 lk.unlock(); 1787 lk.unlock();
1703 mRequestCond.notify_one(); 1788 mRequestCond.notify_one();
@@ -1712,10 +1797,10 @@ void ExternalCameraDeviceSession::OutputThread::flush() {
1712 } 1797 }
1713 1798
1714 std::unique_lock<std::mutex> lk(mRequestListLock); 1799 std::unique_lock<std::mutex> lk(mRequestListLock);
1715 std::list<HalRequest> reqs = mRequestList; 1800 std::list<std::shared_ptr<HalRequest>> reqs = std::move(mRequestList);
1716 mRequestList.clear(); 1801 mRequestList.clear();
1717 if (mProcessingRequest) { 1802 if (mProcessingRequest) {
1718 std::chrono::seconds timeout = std::chrono::seconds(kReqWaitTimeoutSec); 1803 std::chrono::seconds timeout = std::chrono::seconds(kFlushWaitTimeoutSec);
1719 auto st = mRequestDoneCond.wait_for(lk, timeout); 1804 auto st = mRequestDoneCond.wait_for(lk, timeout);
1720 if (st == std::cv_status::timeout) { 1805 if (st == std::cv_status::timeout) {
1721 ALOGE("%s: wait for inflight request finish timeout!", __FUNCTION__); 1806 ALOGE("%s: wait for inflight request finish timeout!", __FUNCTION__);
@@ -1728,33 +1813,57 @@ void ExternalCameraDeviceSession::OutputThread::flush() {
1728 } 1813 }
1729} 1814}
1730 1815
1731void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(HalRequest* out) { 1816void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(
1817 std::shared_ptr<HalRequest>* out) {
1732 if (out == nullptr) { 1818 if (out == nullptr) {
1733 ALOGE("%s: out is null", __FUNCTION__); 1819 ALOGE("%s: out is null", __FUNCTION__);
1734 return; 1820 return;
1735 } 1821 }
1736 1822
1737 std::unique_lock<std::mutex> lk(mRequestListLock); 1823 std::unique_lock<std::mutex> lk(mRequestListLock);
1824 int waitTimes = 0;
1738 while (mRequestList.empty()) { 1825 while (mRequestList.empty()) {
1739 std::chrono::seconds timeout = std::chrono::seconds(kReqWaitTimeoutSec); 1826 if (exitPending()) {
1827 return;
1828 }
1829 std::chrono::milliseconds timeout = std::chrono::milliseconds(kReqWaitTimeoutMs);
1740 auto st = mRequestCond.wait_for(lk, timeout); 1830 auto st = mRequestCond.wait_for(lk, timeout);
1741 if (st == std::cv_status::timeout) { 1831 if (st == std::cv_status::timeout) {
1742 // no new request, return 1832 waitTimes++;
1743 return; 1833 if (waitTimes == kReqWaitTimesMax) {
1834 // no new request, return
1835 return;
1836 }
1744 } 1837 }
1745 } 1838 }
1746 *out = mRequestList.front(); 1839 *out = mRequestList.front();
1747 mRequestList.pop_front(); 1840 mRequestList.pop_front();
1748 mProcessingRequest = true; 1841 mProcessingRequest = true;
1842 mProcessingFrameNumer = (*out)->frameNumber;
1749} 1843}
1750 1844
1751void ExternalCameraDeviceSession::OutputThread::signalRequestDone() { 1845void ExternalCameraDeviceSession::OutputThread::signalRequestDone() {
1752 std::unique_lock<std::mutex> lk(mRequestListLock); 1846 std::unique_lock<std::mutex> lk(mRequestListLock);
1753 mProcessingRequest = false; 1847 mProcessingRequest = false;
1848 mProcessingFrameNumer = 0;
1754 lk.unlock(); 1849 lk.unlock();
1755 mRequestDoneCond.notify_one(); 1850 mRequestDoneCond.notify_one();
1756} 1851}
1757 1852
1853void ExternalCameraDeviceSession::OutputThread::dump(int fd) {
1854 std::lock_guard<std::mutex> lk(mRequestListLock);
1855 if (mProcessingRequest) {
1856 dprintf(fd, "OutputThread processing frame %d\n", mProcessingFrameNumer);
1857 } else {
1858 dprintf(fd, "OutputThread not processing any frames\n");
1859 }
1860 dprintf(fd, "OutputThread request list contains frame: ");
1861 for (const auto& req : mRequestList) {
1862 dprintf(fd, "%d, ", req->frameNumber);
1863 }
1864 dprintf(fd, "\n");
1865}
1866
1758void ExternalCameraDeviceSession::cleanupBuffersLocked(int id) { 1867void ExternalCameraDeviceSession::cleanupBuffersLocked(int id) {
1759 for (auto& pair : mCirculatingBuffers.at(id)) { 1868 for (auto& pair : mCirculatingBuffers.at(id)) {
1760 sHandleImporter.freeBuffer(pair.second); 1869 sHandleImporter.freeBuffer(pair.second);
@@ -2016,15 +2125,25 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(const SupportedV4L2Fo
2016 return OK; 2125 return OK;
2017} 2126}
2018 2127
2019sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked() { 2128sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked(/*out*/nsecs_t* shutterTs) {
2020 sp<V4L2Frame> ret = nullptr; 2129 sp<V4L2Frame> ret = nullptr;
2021 2130
2131 if (shutterTs == nullptr) {
2132 ALOGE("%s: shutterTs must not be null!", __FUNCTION__);
2133 return ret;
2134 }
2135
2022 { 2136 {
2023 std::unique_lock<std::mutex> lk(mV4l2BufferLock); 2137 std::unique_lock<std::mutex> lk(mV4l2BufferLock);
2024 if (mNumDequeuedV4l2Buffers == mV4L2BufferCount) { 2138 if (mNumDequeuedV4l2Buffers == mV4L2BufferCount) {
2025 std::chrono::seconds timeout = std::chrono::seconds(kBufferWaitTimeoutSec); 2139 std::chrono::seconds timeout = std::chrono::seconds(kBufferWaitTimeoutSec);
2026 mLock.unlock(); 2140 mLock.unlock();
2027 auto st = mV4L2BufferReturned.wait_for(lk, timeout); 2141 auto st = mV4L2BufferReturned.wait_for(lk, timeout);
2142 // Here we introduce a case where mV4l2BufferLock is acquired before mLock, while
2143 // the normal lock acquisition order is reversed, but this is fine because in most of
2144 // cases we are protected by mInterfaceLock. The only thread that can compete these
2145 // locks are the OutputThread, where we do need to make sure we don't acquire mLock then
2146 // mV4l2BufferLock
2028 mLock.lock(); 2147 mLock.lock();
2029 if (st == std::cv_status::timeout) { 2148 if (st == std::cv_status::timeout) {
2030 ALOGE("%s: wait for V4L2 buffer return timeout!", __FUNCTION__); 2149 ALOGE("%s: wait for V4L2 buffer return timeout!", __FUNCTION__);
@@ -2051,6 +2170,15 @@ sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked() {
2051 // TODO: try to dequeue again 2170 // TODO: try to dequeue again
2052 } 2171 }
2053 2172
2173 if (buffer.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) {
2174 // Ideally we should also check for V4L2_BUF_FLAG_TSTAMP_SRC_SOE, but
2175 // even V4L2_BUF_FLAG_TSTAMP_SRC_EOF is better than capture a timestamp now
2176 *shutterTs = static_cast<nsecs_t>(buffer.timestamp.tv_sec)*1000000000LL +
2177 buffer.timestamp.tv_usec * 1000LL;
2178 } else {
2179 *shutterTs = systemTime(SYSTEM_TIME_MONOTONIC);
2180 }
2181
2054 { 2182 {
2055 std::lock_guard<std::mutex> lk(mV4l2BufferLock); 2183 std::lock_guard<std::mutex> lk(mV4l2BufferLock);
2056 mNumDequeuedV4l2Buffers++; 2184 mNumDequeuedV4l2Buffers++;
@@ -2061,15 +2189,20 @@ sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked() {
2061} 2189}
2062 2190
2063void ExternalCameraDeviceSession::enqueueV4l2Frame(const sp<V4L2Frame>& frame) { 2191void ExternalCameraDeviceSession::enqueueV4l2Frame(const sp<V4L2Frame>& frame) {
2064 Mutex::Autolock _l(mLock); 2192 {
2065 frame->unmap(); 2193 // Release mLock before acquiring mV4l2BufferLock to avoid potential
2066 v4l2_buffer buffer{}; 2194 // deadlock
2067 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2195 Mutex::Autolock _l(mLock);
2068 buffer.memory = V4L2_MEMORY_MMAP; 2196 frame->unmap();
2069 buffer.index = frame->mBufferIndex; 2197 v4l2_buffer buffer{};
2070 if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) { 2198 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2071 ALOGE("%s: QBUF index %d fails: %s", __FUNCTION__, frame->mBufferIndex, strerror(errno)); 2199 buffer.memory = V4L2_MEMORY_MMAP;
2072 return; 2200 buffer.index = frame->mBufferIndex;
2201 if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
2202 ALOGE("%s: QBUF index %d fails: %s", __FUNCTION__,
2203 frame->mBufferIndex, strerror(errno));
2204 return;
2205 }
2073 } 2206 }
2074 2207
2075 { 2208 {
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index 43656c84..9c0ad7f5 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -91,6 +91,7 @@ struct ExternalCameraDeviceSession : public virtual RefBase {
91 const std::vector<SupportedV4L2Format>& sortedFormats, 91 const std::vector<SupportedV4L2Format>& sortedFormats,
92 const CroppingType& croppingType, 92 const CroppingType& croppingType,
93 const common::V1_0::helper::CameraMetadata& chars, 93 const common::V1_0::helper::CameraMetadata& chars,
94 const std::string& cameraId,
94 unique_fd v4l2Fd); 95 unique_fd v4l2Fd);
95 virtual ~ExternalCameraDeviceSession(); 96 virtual ~ExternalCameraDeviceSession();
96 // Call by CameraDevice to dump active device states 97 // Call by CameraDevice to dump active device states
@@ -180,7 +181,7 @@ protected:
180 int v4l2StreamOffLocked(); 181 int v4l2StreamOffLocked();
181 182
182 // TODO: change to unique_ptr for better tracking 183 // TODO: change to unique_ptr for better tracking
183 sp<V4L2Frame> dequeueV4l2FrameLocked(); // Called with mLock hold 184 sp<V4L2Frame> dequeueV4l2FrameLocked(/*out*/nsecs_t* shutterTs); // Called with mLock hold
184 void enqueueV4l2Frame(const sp<V4L2Frame>&); 185 void enqueueV4l2Frame(const sp<V4L2Frame>&);
185 186
186 // Check if input Stream is one of supported stream setting on this device 187 // Check if input Stream is one of supported stream setting on this device
@@ -198,8 +199,8 @@ protected:
198 199
199 Status processOneCaptureRequest(const CaptureRequest& request); 200 Status processOneCaptureRequest(const CaptureRequest& request);
200 201
201 Status processCaptureResult(HalRequest&); 202 Status processCaptureResult(std::shared_ptr<HalRequest>&);
202 Status processCaptureRequestError(const HalRequest&); 203 Status processCaptureRequestError(const std::shared_ptr<HalRequest>&);
203 void notifyShutter(uint32_t frameNumber, nsecs_t shutterTs); 204 void notifyShutter(uint32_t frameNumber, nsecs_t shutterTs);
204 void notifyError(uint32_t frameNumber, int32_t streamId, ErrorCode ec); 205 void notifyError(uint32_t frameNumber, int32_t streamId, ErrorCode ec);
205 void invokeProcessCaptureResultCallback( 206 void invokeProcessCaptureResultCallback(
@@ -219,8 +220,9 @@ protected:
219 Status allocateIntermediateBuffers( 220 Status allocateIntermediateBuffers(
220 const Size& v4lSize, const Size& thumbSize, 221 const Size& v4lSize, const Size& thumbSize,
221 const hidl_vec<Stream>& streams); 222 const hidl_vec<Stream>& streams);
222 Status submitRequest(const HalRequest&); 223 Status submitRequest(const std::shared_ptr<HalRequest>&);
223 void flush(); 224 void flush();
225 void dump(int fd);
224 virtual bool threadLoop() override; 226 virtual bool threadLoop() override;
225 227
226 private: 228 private:
@@ -232,9 +234,11 @@ protected:
232 static int getCropRect( 234 static int getCropRect(
233 CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out); 235 CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out);
234 236
235 static const int kReqWaitTimeoutSec = 3; 237 static const int kFlushWaitTimeoutSec = 3; // 3 sec
238 static const int kReqWaitTimeoutMs = 33; // 33ms
239 static const int kReqWaitTimesMax = 90; // 33ms * 90 ~= 3 sec
236 240
237 void waitForNextRequest(HalRequest* out); 241 void waitForNextRequest(std::shared_ptr<HalRequest>* out);
238 void signalRequestDone(); 242 void signalRequestDone();
239 243
240 int cropAndScaleLocked( 244 int cropAndScaleLocked(
@@ -254,16 +258,18 @@ protected:
254 void *out, size_t maxOutSize, 258 void *out, size_t maxOutSize,
255 size_t &actualCodeSize); 259 size_t &actualCodeSize);
256 260
257 int createJpegLocked(HalStreamBuffer &halBuf, HalRequest &req); 261 int createJpegLocked(HalStreamBuffer &halBuf, const std::shared_ptr<HalRequest>& req);
258 262
259 const wp<ExternalCameraDeviceSession> mParent; 263 const wp<ExternalCameraDeviceSession> mParent;
260 const CroppingType mCroppingType; 264 const CroppingType mCroppingType;
261 265
262 mutable std::mutex mRequestListLock; // Protect acccess to mRequestList 266 mutable std::mutex mRequestListLock; // Protect acccess to mRequestList,
267 // mProcessingRequest and mProcessingFrameNumer
263 std::condition_variable mRequestCond; // signaled when a new request is submitted 268 std::condition_variable mRequestCond; // signaled when a new request is submitted
264 std::condition_variable mRequestDoneCond; // signaled when a request is done processing 269 std::condition_variable mRequestDoneCond; // signaled when a request is done processing
265 std::list<HalRequest> mRequestList; 270 std::list<std::shared_ptr<HalRequest>> mRequestList;
266 bool mProcessingRequest = false; 271 bool mProcessingRequest = false;
272 uint32_t mProcessingFrameNumer = 0;
267 273
268 // V4L2 frameIn 274 // V4L2 frameIn
269 // (MJPG decode)-> mYu12Frame 275 // (MJPG decode)-> mYu12Frame
@@ -287,7 +293,9 @@ protected:
287 const common::V1_0::helper::CameraMetadata mCameraCharacteristics; 293 const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
288 const std::vector<SupportedV4L2Format> mSupportedFormats; 294 const std::vector<SupportedV4L2Format> mSupportedFormats;
289 const CroppingType mCroppingType; 295 const CroppingType mCroppingType;
296 const std::string& mCameraId;
290 unique_fd mV4l2Fd; 297 unique_fd mV4l2Fd;
298
291 // device is closed either 299 // device is closed either
292 // - closed by user 300 // - closed by user
293 // - init failed 301 // - init failed
diff --git a/confirmationui/1.0/vts/OWNERS b/confirmationui/1.0/vts/OWNERS
new file mode 100644
index 00000000..e7aa8b4b
--- /dev/null
+++ b/confirmationui/1.0/vts/OWNERS
@@ -0,0 +1,3 @@
1jdanis@google.com
2swillden@google.com
3yim@google.com
diff --git a/confirmationui/1.0/vts/functional/Android.bp b/confirmationui/1.0/vts/functional/Android.bp
new file mode 100644
index 00000000..823e035a
--- /dev/null
+++ b/confirmationui/1.0/vts/functional/Android.bp
@@ -0,0 +1,30 @@
1//
2// Copyright (C) 2018 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17cc_test {
18 name: "VtsHalConfirmationUIV1_0TargetTest",
19 defaults: ["VtsHalTargetTestDefaults"],
20 srcs: [
21 "VtsHalConfirmationUIV1_0TargetTest.cpp",
22 ],
23 static_libs: [
24 "android.hardware.confirmationui@1.0",
25 "android.hardware.keymaster@4.0",
26 "libcrypto",
27 "libcn-cbor",
28 "android.hardware.confirmationui-support-lib",
29 ],
30}
diff --git a/confirmationui/1.0/vts/functional/VtsHalConfirmationUIV1_0TargetTest.cpp b/confirmationui/1.0/vts/functional/VtsHalConfirmationUIV1_0TargetTest.cpp
new file mode 100644
index 00000000..463bb40a
--- /dev/null
+++ b/confirmationui/1.0/vts/functional/VtsHalConfirmationUIV1_0TargetTest.cpp
@@ -0,0 +1,428 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "ConfirmationIOHidlHalTest"
18#include <cutils/log.h>
19
20#include <algorithm>
21#include <iostream>
22#include <memory>
23
24#include <android/hardware/confirmationui/1.0/IConfirmationResultCallback.h>
25#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
26#include <android/hardware/confirmationui/1.0/types.h>
27#include <android/hardware/confirmationui/support/confirmationui_utils.h>
28
29#include <VtsHalHidlTargetCallbackBase.h>
30#include <VtsHalHidlTargetTestBase.h>
31
32#include <openssl/hmac.h>
33#include <openssl/sha.h>
34
35#include <cn-cbor/cn-cbor.h>
36
37using ::android::sp;
38
39using ::std::string;
40
41namespace android {
42namespace hardware {
43
44namespace confirmationui {
45namespace V1_0 {
46
47namespace test {
48namespace {
49class HMacImplementation {
50 public:
51 static support::NullOr<support::array<uint8_t, 32>> hmac256(
52 const uint8_t key[32], std::initializer_list<support::ByteBufferProxy> buffers) {
53 HMAC_CTX hmacCtx;
54 HMAC_CTX_init(&hmacCtx);
55 if (!HMAC_Init_ex(&hmacCtx, key, 32, EVP_sha256(), nullptr)) {
56 return {};
57 }
58 for (auto& buffer : buffers) {
59 if (!HMAC_Update(&hmacCtx, buffer.data(), buffer.size())) {
60 return {};
61 }
62 }
63 support::array<uint8_t, 32> result;
64 if (!HMAC_Final(&hmacCtx, result.data(), nullptr)) {
65 return {};
66 }
67 return result;
68 }
69};
70
71using HMacer = support::HMac<HMacImplementation>;
72
73constexpr uint8_t testKeyByte = static_cast<uint8_t>(TestKeyBits::BYTE);
74
75template <typename... Data>
76hidl_vec<uint8_t> testHMAC(const Data&... data) {
77 constexpr uint8_t testKey[32] = {testKeyByte, testKeyByte, testKeyByte, testKeyByte,
78 testKeyByte, testKeyByte, testKeyByte, testKeyByte,
79 testKeyByte, testKeyByte, testKeyByte, testKeyByte,
80 testKeyByte, testKeyByte, testKeyByte, testKeyByte};
81 constexpr uint8_t hmac_size_bytes = sizeof testKey;
82
83 auto hmac = HMacer::hmac256(testKey, data...);
84 if (!hmac.isOk()) {
85 EXPECT_TRUE(false) << "Failed to compute test hmac. This is a self-test error.";
86 return {};
87 }
88 hidl_vec<uint8_t> result(hmac_size_bytes);
89 copy(hmac.value().data(), hmac.value().data() + hmac_size_bytes, result.data());
90 return result;
91}
92
93using ::android::hardware::keymaster::V4_0::HardwareAuthToken;
94using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType;
95
96template <typename T>
97auto toBytes(const T& v) -> const uint8_t (&)[sizeof(T)] {
98 return *reinterpret_cast<const uint8_t(*)[sizeof(T)]>(&v);
99}
100
101HardwareAuthToken makeTestToken(const TestModeCommands command, uint64_t timestamp = 0) {
102 HardwareAuthToken auth_token;
103 auth_token.challenge = static_cast<uint64_t>(command);
104 auth_token.userId = 0;
105 auth_token.authenticatorId = 0;
106 auth_token.authenticatorType = HardwareAuthenticatorType::NONE;
107 auth_token.timestamp = timestamp;
108
109 // Canonical form of auth-token v0
110 // version (1 byte)
111 // challenge (8 bytes)
112 // user_id (8 bytes)
113 // authenticator_id (8 bytes)
114 // authenticator_type (4 bytes)
115 // timestamp (8 bytes)
116 // total 37 bytes
117 auth_token.mac = testHMAC("\0",
118 toBytes(auth_token.challenge), //
119 toBytes(auth_token.userId), //
120 toBytes(auth_token.authenticatorId), //
121 toBytes(support::hton(auth_token.authenticatorType)), //
122 toBytes(support::hton(auth_token.timestamp))); //
123
124 return auth_token;
125}
126
127#define DEBUG_CONFRIMATIONUI_UTILS_TEST
128
129#ifdef DEBUG_CONFRIMATIONUI_UTILS_TEST
130std::ostream& hexdump(std::ostream& out, const uint8_t* data, size_t size) {
131 for (size_t i = 0; i < size; ++i) {
132 uint8_t byte = data[i];
133 out << std::hex << std::setw(2) << std::setfill('0') << (unsigned)byte;
134 switch (i & 0xf) {
135 case 0xf:
136 out << "\n";
137 break;
138 case 7:
139 out << " ";
140 break;
141 default:
142 out << " ";
143 break;
144 }
145 }
146 return out;
147}
148#endif
149
150constexpr char hex_value[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
152 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
153 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // '0'..'9'
154 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'A'..'F'
155 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
156 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'a'..'f'
157 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
158 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
159 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
161 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
162 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
163 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
166
167std::string hex2str(std::string a) {
168 std::string b;
169 size_t num = a.size() / 2;
170 b.resize(num);
171 for (size_t i = 0; i < num; i++) {
172 b[i] = (hex_value[a[i * 2] & 0xFF] << 4) + (hex_value[a[i * 2 + 1] & 0xFF]);
173 }
174 return b;
175}
176
177} // namespace
178
179class ConfirmationArgs {
180 public:
181 ResponseCode error_;
182 hidl_vec<uint8_t> formattedMessage_;
183 hidl_vec<uint8_t> confirmationToken_;
184 bool verifyConfirmationToken() {
185 static constexpr char confirmationPrefix[] = "confirmation token";
186 EXPECT_EQ(32U, confirmationToken_.size());
187 return 32U == confirmationToken_.size() &&
188 !memcmp(confirmationToken_.data(),
189 testHMAC(confirmationPrefix, formattedMessage_).data(), 32);
190 }
191};
192
193class ConfirmationTestCallback : public ::testing::VtsHalHidlTargetCallbackBase<ConfirmationArgs>,
194 public IConfirmationResultCallback {
195 public:
196 Return<void> result(ResponseCode error, const hidl_vec<uint8_t>& formattedMessage,
197 const hidl_vec<uint8_t>& confirmationToken) override {
198 ConfirmationArgs args;
199 args.error_ = error;
200 args.formattedMessage_ = formattedMessage;
201 args.confirmationToken_ = confirmationToken;
202 NotifyFromCallback(args);
203 return Void();
204 }
205};
206
207class ConfirmationUIHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
208 public:
209 // get the test environment singleton
210 static ConfirmationUIHidlEnvironment* Instance() {
211 static ConfirmationUIHidlEnvironment* instance = new ConfirmationUIHidlEnvironment;
212 return instance;
213 }
214
215 void registerTestServices() override { registerTestService<IConfirmationUI>(); }
216
217 private:
218 ConfirmationUIHidlEnvironment(){};
219
220 GTEST_DISALLOW_COPY_AND_ASSIGN_(ConfirmationUIHidlEnvironment);
221};
222
223class ConfirmationUIHidlTest : public ::testing::VtsHalHidlTargetTestBase {
224 public:
225 void TearDown() override { confirmator().abort(); }
226
227 static void SetUpTestCase() {
228 string service_name =
229 ConfirmationUIHidlEnvironment::Instance()->getServiceName<IConfirmationUI>();
230 confirmator_ = IConfirmationUI::getService(service_name);
231 ASSERT_NE(nullptr, confirmator_.get());
232 }
233
234 static void TearDownTestCase() { confirmator_.clear(); }
235
236 static IConfirmationUI& confirmator() { return *confirmator_; }
237
238 private:
239 static sp<IConfirmationUI> confirmator_;
240};
241
242sp<IConfirmationUI> ConfirmationUIHidlTest::confirmator_;
243
244#define ASSERT_HAL_CALL(expected, call) \
245 { \
246 auto result = call; \
247 ASSERT_TRUE(result.isOk()); \
248 ASSERT_EQ(expected, static_cast<decltype(expected)>(result)); \
249 }
250
251struct CnCborDeleter {
252 void operator()(cn_cbor* ptr) { cn_cbor_free(ptr); }
253};
254
255typedef std::unique_ptr<cn_cbor, CnCborDeleter> CnCborPtr;
256
257// Simulates the User taping Ok
258TEST_F(ConfirmationUIHidlTest, UserOkTest) {
259 static constexpr char test_prompt[] = "Me first, gimme gimme!";
260 static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
261 sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
262 hidl_string prompt_text(test_prompt);
263 hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
264 ASSERT_HAL_CALL(ResponseCode::OK,
265 confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
266
267 ASSERT_HAL_CALL(ResponseCode::OK, confirmator().deliverSecureInputEvent(
268 makeTestToken(TestModeCommands::OK_EVENT)));
269
270 auto result = conf_cb->WaitForCallback();
271 ASSERT_EQ(ResponseCode::OK, result.args->error_);
272
273 ASSERT_TRUE(result.args->verifyConfirmationToken());
274
275 cn_cbor_errback cn_cbor_error;
276 auto parsed_message =
277 CnCborPtr(cn_cbor_decode(result.args->formattedMessage_.data(),
278 result.args->formattedMessage_.size(), &cn_cbor_error));
279 // is parsable CBOR
280 ASSERT_TRUE(parsed_message.get());
281 // is a map
282 ASSERT_EQ(CN_CBOR_MAP, parsed_message->type);
283
284 // the message must have exactly 2 key value pairs.
285 // cn_cbor holds 2*<no_of_pairs> in the length field
286 ASSERT_EQ(4, parsed_message->length);
287 // map has key "prompt"
288 auto prompt = cn_cbor_mapget_string(parsed_message.get(), "prompt");
289 ASSERT_TRUE(prompt);
290 ASSERT_EQ(CN_CBOR_TEXT, prompt->type);
291 ASSERT_EQ(22, prompt->length);
292 ASSERT_EQ(0, memcmp(test_prompt, prompt->v.str, 22));
293 // map has key "extra"
294 auto extra_out = cn_cbor_mapget_string(parsed_message.get(), "extra");
295 ASSERT_TRUE(extra_out);
296 ASSERT_EQ(CN_CBOR_BYTES, extra_out->type);
297 ASSERT_EQ(3, extra_out->length);
298 ASSERT_EQ(0, memcmp(test_extra, extra_out->v.bytes, 3));
299}
300
301// Initiates a confirmation prompt with a message that is too long
302TEST_F(ConfirmationUIHidlTest, MessageTooLongTest) {
303 static constexpr uint8_t test_extra[static_cast<uint32_t>(MessageSize::MAX)] = {};
304 static constexpr char test_prompt[] = "D\'oh!";
305 sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
306 hidl_string prompt_text(test_prompt);
307 hidl_vec<uint8_t> extra(test_extra, test_extra + sizeof(test_extra));
308 ASSERT_HAL_CALL(ResponseCode::UIErrorMessageTooLong,
309 confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
310}
311
312// If the message gets very long some HAL implementations might fail even before the message
313// reaches the trusted app implementation. But the HAL must still diagnose the correct error.
314TEST_F(ConfirmationUIHidlTest, MessageWayTooLongTest) {
315 static constexpr uint8_t test_extra[static_cast<uint32_t>(MessageSize::MAX) * 10] = {};
316 static constexpr char test_prompt[] = "D\'oh!";
317 sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
318 hidl_string prompt_text(test_prompt);
319 hidl_vec<uint8_t> extra(test_extra, test_extra + sizeof(test_extra));
320 ASSERT_HAL_CALL(ResponseCode::UIErrorMessageTooLong,
321 confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
322}
323
324// Simulates the User tapping the Cancel
325TEST_F(ConfirmationUIHidlTest, UserCancelTest) {
326 static constexpr char test_prompt[] = "Me first, gimme gimme!";
327 static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
328 sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
329 hidl_string prompt_text(test_prompt);
330 hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
331 ASSERT_HAL_CALL(ResponseCode::OK,
332 confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
333
334 ASSERT_HAL_CALL(ResponseCode::OK, confirmator().deliverSecureInputEvent(
335 makeTestToken(TestModeCommands::CANCEL_EVENT)));
336
337 auto result = conf_cb->WaitForCallback();
338 ASSERT_EQ(ResponseCode::Canceled, result.args->error_);
339
340 ASSERT_EQ(0U, result.args->confirmationToken_.size());
341 ASSERT_EQ(0U, result.args->formattedMessage_.size());
342}
343
344// Simulates the framework candelling an ongoing prompt
345TEST_F(ConfirmationUIHidlTest, AbortTest) {
346 static constexpr char test_prompt[] = "Me first, gimme gimme!";
347 static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
348 sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
349 hidl_string prompt_text(test_prompt);
350 hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
351 ASSERT_HAL_CALL(ResponseCode::OK,
352 confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
353
354 confirmator().abort();
355
356 auto result = conf_cb->WaitForCallback();
357 ASSERT_EQ(ResponseCode::Aborted, result.args->error_);
358 ASSERT_EQ(0U, result.args->confirmationToken_.size());
359 ASSERT_EQ(0U, result.args->formattedMessage_.size());
360}
361
362// Passing malformed UTF-8 to the confirmation UI
363// This test passes a string that ends in the middle of a multibyte character
364TEST_F(ConfirmationUIHidlTest, MalformedUTF8Test1) {
365 static constexpr char test_prompt[] = {char(0xc0), 0};
366 static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
367 sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
368 hidl_string prompt_text(test_prompt);
369 hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
370 ASSERT_HAL_CALL(ResponseCode::UIErrorMalformedUTF8Encoding,
371 confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
372}
373
374// Passing malformed UTF-8 to the confirmation UI
375// This test passes a string with a 5-byte character.
376TEST_F(ConfirmationUIHidlTest, MalformedUTF8Test2) {
377 static constexpr char test_prompt[] = {char(0xf8), char(0x82), char(0x82),
378 char(0x82), char(0x82), 0};
379 static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
380 sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
381 hidl_string prompt_text(test_prompt);
382 hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
383 ASSERT_HAL_CALL(ResponseCode::UIErrorMalformedUTF8Encoding,
384 confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
385}
386
387// Passing malformed UTF-8 to the confirmation UI
388// This test passes a string with a 2-byte character followed by a stray non UTF-8 character.
389TEST_F(ConfirmationUIHidlTest, MalformedUTF8Test3) {
390 static constexpr char test_prompt[] = {char(0xc0), char(0x82), char(0x83), 0};
391 static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
392 sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
393 hidl_string prompt_text(test_prompt);
394 hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
395 ASSERT_HAL_CALL(ResponseCode::UIErrorMalformedUTF8Encoding,
396 confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
397}
398
399// Test the implementation of HMAC SHA 256 against a golden blob.
400TEST(ConfirmationUITestSelfTest, HMAC256SelfTest) {
401 const char key_str[32] = "keykeykeykeykeykeykeykeykeykeyk";
402 const uint8_t(&key)[32] = *reinterpret_cast<const uint8_t(*)[32]>(key_str);
403 auto expected = hex2str("2377fbcaa7fb3f6c20cfa1d9ebc60e9922cf58c909e25e300f3cb57f7805c886");
404 auto result = HMacer::hmac256(key, "value1", "value2", "value3");
405
406#ifdef DEBUG_CONFRIMATIONUI_UTILS_TEST
407 hexdump(std::cout, reinterpret_cast<const uint8_t*>(expected.data()), 32) << std::endl;
408 hexdump(std::cout, result.value().data(), 32) << std::endl;
409#endif
410
411 support::ByteBufferProxy expected_bytes(expected);
412 ASSERT_TRUE(result.isOk());
413 ASSERT_EQ(expected, result.value());
414}
415
416} // namespace test
417} // namespace V1_0
418} // namespace confirmationui
419} // namespace hardware
420} // namespace android
421
422int main(int argc, char** argv) {
423 ::testing::InitGoogleTest(&argc, argv);
424 std::vector<std::string> positional_args;
425 int status = RUN_ALL_TESTS();
426 ALOGI("Test result = %d", status);
427 return status;
428}
diff --git a/gnss/1.1/Android.bp b/gnss/1.1/Android.bp
index 417b4f5b..4ae4439a 100644
--- a/gnss/1.1/Android.bp
+++ b/gnss/1.1/Android.bp
@@ -11,6 +11,7 @@ hidl_interface {
11 "IGnssCallback.hal", 11 "IGnssCallback.hal",
12 "IGnssConfiguration.hal", 12 "IGnssConfiguration.hal",
13 "IGnssMeasurement.hal", 13 "IGnssMeasurement.hal",
14 "IGnssMeasurementCallback.hal",
14 ], 15 ],
15 interfaces: [ 16 interfaces: [
16 "android.hardware.gnss@1.0", 17 "android.hardware.gnss@1.0",
diff --git a/gnss/1.1/IGnssMeasurement.hal b/gnss/1.1/IGnssMeasurement.hal
index 75df5a8a..cd83ae35 100644
--- a/gnss/1.1/IGnssMeasurement.hal
+++ b/gnss/1.1/IGnssMeasurement.hal
@@ -17,7 +17,7 @@
17package android.hardware.gnss@1.1; 17package android.hardware.gnss@1.1;
18 18
19import @1.0::IGnssMeasurement; 19import @1.0::IGnssMeasurement;
20import @1.0::IGnssMeasurementCallback; 20import IGnssMeasurementCallback;
21 21
22/** 22/**
23 * Extended interface for GNSS Measurements support. 23 * Extended interface for GNSS Measurements support.
diff --git a/gnss/1.1/IGnssMeasurementCallback.hal b/gnss/1.1/IGnssMeasurementCallback.hal
new file mode 100644
index 00000000..5a60a56b
--- /dev/null
+++ b/gnss/1.1/IGnssMeasurementCallback.hal
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.hardware.gnss@1.1;
18
19import @1.0::IGnssMeasurementCallback;
20
21/** The callback interface to report measurements from the HAL. */
22interface IGnssMeasurementCallback extends @1.0::IGnssMeasurementCallback {
23 /**
24 * Flags indicating the Accumulated Delta Range's states.
25 */
26 enum GnssAccumulatedDeltaRangeState
27 : @1.0::IGnssMeasurementCallback.GnssAccumulatedDeltaRangeState {
28 ADR_STATE_HALF_CYCLE_RESOLVED = 1 << 3, // Carrier-phase half-cycle ambiguity resolved
29 };
30
31 /**
32 * Extends a GNSS Measurement, adding the new enum.
33 */
34 struct GnssMeasurement {
35 /**
36 * GNSS measurement information for a single satellite and frequency, as in the 1.0
37 * version of the HAL.
38 *
39 * In this version of the HAL, these fields of the
40 * @1.0::IGnssMeasurementCallback.GnssMeasurement v1_0 struct are deprecated, and
41 * are no longer used by the framework:
42 * carrierCycles
43 * carrierPhase
44 * carrierPhaseUncertainty
45 *
46 * Similar information about carrier phase signal tracking is still reported in these
47 * fields of @1.0::IGnssMeasurementCallback.GnssMeasurement v1_0:
48 * accumulatedDeltaRangeM
49 * accumulatedDeltaRangeUncertaintyM
50 */
51 @1.0::IGnssMeasurementCallback.GnssMeasurement v1_0;
52
53 /**
54 * Provides the state of Accumulated Delta Range values, including additional information
55 * beyond version 1.0 of the HAL. See GnssAccumulatedDeltaRangeState.
56 *
57 * In this (1.1) version of the HAL, this value is used by the framework, not the
58 * value provided by v1_0.accumulatedDeltaRangeState.
59 */
60 bitfield<GnssAccumulatedDeltaRangeState> accumulatedDeltaRangeState;
61 };
62
63 /**
64 * Complete set of GNSS Measurement data, same as 1.0 with additional enum in measurements.
65 */
66 struct GnssData {
67 /** The full set of satellite measurement observations. */
68 vec<GnssMeasurement> measurements;
69
70 /** The GNSS clock time reading. */
71 GnssClock clock;
72 };
73
74 /**
75 * Callback for the hal to pass a GnssData structure back to the client.
76 *
77 * @param data Contains a reading of GNSS measurements.
78 */
79 gnssMeasurementCb(GnssData data);
80};
diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
index 264a11db..a0a1c736 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
@@ -396,6 +396,10 @@ TEST_F(GnssHalTest, InjectBestLocation) {
396 396
397 ASSERT_TRUE(result.isOk()); 397 ASSERT_TRUE(result.isOk());
398 EXPECT_TRUE(result); 398 EXPECT_TRUE(result);
399
400 auto resultVoid = gnss_hal_->deleteAidingData(IGnss::GnssAidingData::DELETE_ALL);
401
402 ASSERT_TRUE(resultVoid.isOk());
399} 403}
400 404
401/* 405/*
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index b46a1deb..2de1e3ca 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -1,34 +1,12 @@
1cc_library_static {
2 name: "libhwcomposer-client",
3 vendor_available: true,
4 defaults: ["hidl_defaults"],
5 export_include_dirs: ["."],
6 srcs: ["ComposerClient.cpp"],
7 shared_libs: [
8 "android.hardware.graphics.composer@2.1",
9 "android.hardware.graphics.mapper@2.0",
10 "libbase",
11 "libcutils",
12 "libfmq",
13 "libhardware",
14 "libhidlbase",
15 "libhidltransport",
16 "liblog",
17 "libsync",
18 "libutils",
19 ],
20 header_libs: [
21 "android.hardware.graphics.composer@2.1-command-buffer",
22 ],
23}
24
25cc_library_shared { 1cc_library_shared {
26 name: "android.hardware.graphics.composer@2.1-impl", 2 name: "android.hardware.graphics.composer@2.1-impl",
27 defaults: ["hidl_defaults"], 3 defaults: ["hidl_defaults"],
28 proprietary: true, 4 vendor: true,
29 relative_install_path: "hw", 5 relative_install_path: "hw",
30 srcs: ["Hwc.cpp"], 6 srcs: ["passthrough.cpp"],
31 static_libs: ["libhwcomposer-client"], 7 header_libs: [
8 "android.hardware.graphics.composer@2.1-passthrough",
9 ],
32 shared_libs: [ 10 shared_libs: [
33 "android.hardware.graphics.composer@2.1", 11 "android.hardware.graphics.composer@2.1",
34 "android.hardware.graphics.mapper@2.0", 12 "android.hardware.graphics.mapper@2.0",
@@ -44,26 +22,21 @@ cc_library_shared {
44 "libhwc2on1adapter", 22 "libhwc2on1adapter",
45 "libhwc2onfbadapter", 23 "libhwc2onfbadapter",
46 ], 24 ],
47 header_libs: [ 25 cflags: [
48 "android.hardware.graphics.composer@2.1-command-buffer", 26 "-DLOG_TAG=\"ComposerHal\""
49 ], 27 ],
50} 28}
51 29
52cc_binary { 30cc_binary {
53 name: "android.hardware.graphics.composer@2.1-service", 31 name: "android.hardware.graphics.composer@2.1-service",
54 defaults: ["hidl_defaults"], 32 defaults: ["hidl_defaults"],
55 proprietary: true, 33 vendor: true,
56 relative_install_path: "hw", 34 relative_install_path: "hw",
57 srcs: ["service.cpp"], 35 srcs: ["service.cpp"],
58 init_rc: ["android.hardware.graphics.composer@2.1-service.rc"], 36 init_rc: ["android.hardware.graphics.composer@2.1-service.rc"],
59 static_libs: ["libhwcomposer-client"],
60 shared_libs: [ 37 shared_libs: [
61 "android.hardware.graphics.composer@2.1", 38 "android.hardware.graphics.composer@2.1",
62 "libbase",
63 "libbinder", 39 "libbinder",
64 "libcutils",
65 "libfmq",
66 "libhardware",
67 "libhidlbase", 40 "libhidlbase",
68 "libhidltransport", 41 "libhidltransport",
69 "liblog", 42 "liblog",
diff --git a/graphics/composer/2.1/default/ComposerBase.h b/graphics/composer/2.1/default/ComposerBase.h
deleted file mode 100644
index e1c9d333..00000000
--- a/graphics/composer/2.1/default/ComposerBase.h
+++ /dev/null
@@ -1,132 +0,0 @@
1/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_BASE_H
18#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_BASE_H
19
20#include <android/hardware/graphics/composer/2.1/IComposer.h>
21#include <hardware/hwcomposer2.h>
22
23namespace android {
24namespace hardware {
25namespace graphics {
26namespace composer {
27namespace V2_1 {
28namespace implementation {
29
30using android::hardware::graphics::common::V1_0::PixelFormat;
31using android::hardware::graphics::common::V1_0::Transform;
32using android::hardware::graphics::common::V1_0::Dataspace;
33using android::hardware::graphics::common::V1_0::ColorMode;
34using android::hardware::graphics::common::V1_0::ColorTransform;
35using android::hardware::graphics::common::V1_0::Hdr;
36
37class ComposerBase {
38public:
39 virtual ~ComposerBase() {};
40
41 virtual bool hasCapability(hwc2_capability_t capability) = 0;
42
43 virtual void removeClient() = 0;
44 virtual void enableCallback(bool enable) = 0;
45 virtual uint32_t getMaxVirtualDisplayCount() = 0;
46 virtual Error createVirtualDisplay(uint32_t width, uint32_t height,
47 PixelFormat* format, Display* outDisplay) = 0;
48 virtual Error destroyVirtualDisplay(Display display) = 0;
49 virtual Error createLayer(Display display, Layer* outLayer) = 0;
50 virtual Error destroyLayer(Display display, Layer layer) = 0;
51
52 virtual Error getActiveConfig(Display display, Config* outConfig) = 0;
53 virtual Error getClientTargetSupport(Display display,
54 uint32_t width, uint32_t height,
55 PixelFormat format, Dataspace dataspace) = 0;
56 virtual Error getColorModes(Display display,
57 hidl_vec<ColorMode>* outModes) = 0;
58 virtual Error getDisplayAttribute(Display display, Config config,
59 IComposerClient::Attribute attribute, int32_t* outValue) = 0;
60 virtual Error getDisplayConfigs(Display display,
61 hidl_vec<Config>* outConfigs) = 0;
62 virtual Error getDisplayName(Display display, hidl_string* outName) = 0;
63 virtual Error getDisplayType(Display display,
64 IComposerClient::DisplayType* outType) = 0;
65 virtual Error getDozeSupport(Display display, bool* outSupport) = 0;
66 virtual Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
67 float* outMaxLuminance, float* outMaxAverageLuminance,
68 float* outMinLuminance) = 0;
69
70 virtual Error setActiveConfig(Display display, Config config) = 0;
71 virtual Error setColorMode(Display display, ColorMode mode) = 0;
72 virtual Error setPowerMode(Display display,
73 IComposerClient::PowerMode mode) = 0;
74 virtual Error setVsyncEnabled(Display display,
75 IComposerClient::Vsync enabled) = 0;
76
77 virtual Error setColorTransform(Display display, const float* matrix,
78 int32_t hint) = 0;
79 virtual Error setClientTarget(Display display, buffer_handle_t target,
80 int32_t acquireFence, int32_t dataspace,
81 const std::vector<hwc_rect_t>& damage) = 0;
82 virtual Error setOutputBuffer(Display display, buffer_handle_t buffer,
83 int32_t releaseFence) = 0;
84 virtual Error validateDisplay(Display display,
85 std::vector<Layer>* outChangedLayers,
86 std::vector<IComposerClient::Composition>* outCompositionTypes,
87 uint32_t* outDisplayRequestMask,
88 std::vector<Layer>* outRequestedLayers,
89 std::vector<uint32_t>* outRequestMasks) = 0;
90 virtual Error acceptDisplayChanges(Display display) = 0;
91 virtual Error presentDisplay(Display display, int32_t* outPresentFence,
92 std::vector<Layer>* outLayers,
93 std::vector<int32_t>* outReleaseFences) = 0;
94
95 virtual Error setLayerCursorPosition(Display display, Layer layer,
96 int32_t x, int32_t y) = 0;
97 virtual Error setLayerBuffer(Display display, Layer layer,
98 buffer_handle_t buffer, int32_t acquireFence) = 0;
99 virtual Error setLayerSurfaceDamage(Display display, Layer layer,
100 const std::vector<hwc_rect_t>& damage) = 0;
101 virtual Error setLayerBlendMode(Display display, Layer layer,
102 int32_t mode) = 0;
103 virtual Error setLayerColor(Display display, Layer layer,
104 IComposerClient::Color color) = 0;
105 virtual Error setLayerCompositionType(Display display, Layer layer,
106 int32_t type) = 0;
107 virtual Error setLayerDataspace(Display display, Layer layer,
108 int32_t dataspace) = 0;
109 virtual Error setLayerDisplayFrame(Display display, Layer layer,
110 const hwc_rect_t& frame) = 0;
111 virtual Error setLayerPlaneAlpha(Display display, Layer layer,
112 float alpha) = 0;
113 virtual Error setLayerSidebandStream(Display display, Layer layer,
114 buffer_handle_t stream) = 0;
115 virtual Error setLayerSourceCrop(Display display, Layer layer,
116 const hwc_frect_t& crop) = 0;
117 virtual Error setLayerTransform(Display display, Layer layer,
118 int32_t transform) = 0;
119 virtual Error setLayerVisibleRegion(Display display, Layer layer,
120 const std::vector<hwc_rect_t>& visible) = 0;
121 virtual Error setLayerZOrder(Display display, Layer layer,
122 uint32_t z) = 0;
123};
124
125} // namespace implementation
126} // namespace V2_1
127} // namespace composer
128} // namespace graphics
129} // namespace hardware
130} // namespace android
131
132#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_BASE_H
diff --git a/graphics/composer/2.1/default/ComposerClient.cpp b/graphics/composer/2.1/default/ComposerClient.cpp
deleted file mode 100644
index 0fcb9de8..00000000
--- a/graphics/composer/2.1/default/ComposerClient.cpp
+++ /dev/null
@@ -1,1205 +0,0 @@
1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "HwcPassthrough"
18
19#include <android/hardware/graphics/mapper/2.0/IMapper.h>
20#include <log/log.h>
21
22#include "ComposerBase.h"
23#include "ComposerClient.h"
24
25namespace android {
26namespace hardware {
27namespace graphics {
28namespace composer {
29namespace V2_1 {
30namespace implementation {
31
32namespace {
33
34using MapperError = android::hardware::graphics::mapper::V2_0::Error;
35using android::hardware::graphics::mapper::V2_0::IMapper;
36
37class HandleImporter {
38public:
39 bool initialize()
40 {
41 // allow only one client
42 if (mInitialized) {
43 return false;
44 }
45
46 mMapper = IMapper::getService();
47
48 mInitialized = true;
49 return true;
50 }
51
52 void cleanup()
53 {
54 mMapper.clear();
55 mInitialized = false;
56 }
57
58 // In IComposer, any buffer_handle_t is owned by the caller and we need to
59 // make a clone for hwcomposer2. We also need to translate empty handle
60 // to nullptr. This function does that, in-place.
61 bool importBuffer(buffer_handle_t& handle)
62 {
63 if (!handle) {
64 return true;
65 }
66
67 if (!handle->numFds && !handle->numInts) {
68 handle = nullptr;
69 return true;
70 }
71
72 MapperError error;
73 buffer_handle_t importedHandle;
74 mMapper->importBuffer(
75 hidl_handle(handle),
76 [&](const auto& tmpError, const auto& tmpBufferHandle) {
77 error = tmpError;
78 importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
79 });
80 if (error != MapperError::NONE) {
81 return false;
82 }
83
84 handle = importedHandle;
85
86 return true;
87 }
88
89 void freeBuffer(buffer_handle_t handle)
90 {
91 if (!handle) {
92 return;
93 }
94
95 mMapper->freeBuffer(const_cast<native_handle_t*>(handle));
96 }
97
98private:
99 bool mInitialized = false;
100 sp<IMapper> mMapper;
101};
102
103HandleImporter sHandleImporter;
104
105} // anonymous namespace
106
107BufferCacheEntry::BufferCacheEntry()
108 : mHandle(nullptr)
109{
110}
111
112BufferCacheEntry::BufferCacheEntry(BufferCacheEntry&& other)
113{
114 mHandle = other.mHandle;
115 other.mHandle = nullptr;
116}
117
118BufferCacheEntry& BufferCacheEntry::operator=(buffer_handle_t handle)
119{
120 clear();
121 mHandle = handle;
122 return *this;
123}
124
125BufferCacheEntry::~BufferCacheEntry()
126{
127 clear();
128}
129
130void BufferCacheEntry::clear()
131{
132 if (mHandle) {
133 sHandleImporter.freeBuffer(mHandle);
134 }
135}
136
137ComposerClient::ComposerClient(ComposerBase& hal)
138 : mHal(hal), mWriter(kWriterInitialSize)
139{
140}
141
142ComposerClient::~ComposerClient()
143{
144 // We want to call hwc2_close here (and move hwc2_open to the
145 // constructor), with the assumption that hwc2_close would
146 //
147 // - clean up all resources owned by the client
148 // - make sure all displays are blank (since there is no layer)
149 //
150 // But since SF used to crash at this point, different hwcomposer2
151 // implementations behave differently on hwc2_close. Our only portable
152 // choice really is to abort(). But that is not an option anymore
153 // because we might also have VTS or VR as clients that can come and go.
154 //
155 // Below we manually clean all resources (layers and virtual
156 // displays), and perform a presentDisplay afterwards.
157 ALOGW("destroying composer client");
158
159 mHal.enableCallback(false);
160
161 // no need to grab the mutex as any in-flight hwbinder call would have
162 // kept the client alive
163 for (const auto& dpy : mDisplayData) {
164 ALOGW("destroying client resources for display %" PRIu64, dpy.first);
165
166 for (const auto& ly : dpy.second.Layers) {
167 mHal.destroyLayer(dpy.first, ly.first);
168 }
169
170 if (dpy.second.IsVirtual) {
171 mHal.destroyVirtualDisplay(dpy.first);
172 } else {
173 ALOGW("performing a final presentDisplay");
174
175 std::vector<Layer> changedLayers;
176 std::vector<IComposerClient::Composition> compositionTypes;
177 uint32_t displayRequestMask = 0;
178 std::vector<Layer> requestedLayers;
179 std::vector<uint32_t> requestMasks;
180 mHal.validateDisplay(dpy.first, &changedLayers, &compositionTypes,
181 &displayRequestMask, &requestedLayers, &requestMasks);
182
183 mHal.acceptDisplayChanges(dpy.first);
184
185 int32_t presentFence = -1;
186 std::vector<Layer> releasedLayers;
187 std::vector<int32_t> releaseFences;
188 mHal.presentDisplay(dpy.first, &presentFence, &releasedLayers, &releaseFences);
189 if (presentFence >= 0) {
190 close(presentFence);
191 }
192 for (auto fence : releaseFences) {
193 if (fence >= 0) {
194 close(fence);
195 }
196 }
197 }
198 }
199
200 mDisplayData.clear();
201
202 sHandleImporter.cleanup();
203
204 mHal.removeClient();
205
206 ALOGW("removed composer client");
207}
208
209void ComposerClient::initialize()
210{
211 mReader = createCommandReader();
212 if (!sHandleImporter.initialize()) {
213 LOG_ALWAYS_FATAL("failed to initialize handle importer");
214 }
215}
216
217void ComposerClient::onHotplug(Display display,
218 IComposerCallback::Connection connected)
219{
220 {
221 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
222
223 if (connected == IComposerCallback::Connection::CONNECTED) {
224 mDisplayData.emplace(display, DisplayData(false));
225 } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
226 mDisplayData.erase(display);
227 }
228 }
229
230 auto ret = mCallback->onHotplug(display, connected);
231 ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s",
232 ret.description().c_str());
233}
234
235void ComposerClient::onRefresh(Display display)
236{
237 auto ret = mCallback->onRefresh(display);
238 ALOGE_IF(!ret.isOk(), "failed to send onRefresh: %s",
239 ret.description().c_str());
240}
241
242void ComposerClient::onVsync(Display display, int64_t timestamp)
243{
244 auto ret = mCallback->onVsync(display, timestamp);
245 ALOGE_IF(!ret.isOk(), "failed to send onVsync: %s",
246 ret.description().c_str());
247}
248
249Return<void> ComposerClient::registerCallback(
250 const sp<IComposerCallback>& callback)
251{
252 // no locking as we require this function to be called only once
253 mCallback = callback;
254 mHal.enableCallback(callback != nullptr);
255
256 return Void();
257}
258
259Return<uint32_t> ComposerClient::getMaxVirtualDisplayCount()
260{
261 return mHal.getMaxVirtualDisplayCount();
262}
263
264Return<void> ComposerClient::createVirtualDisplay(uint32_t width,
265 uint32_t height, PixelFormat formatHint, uint32_t outputBufferSlotCount,
266 createVirtualDisplay_cb hidl_cb)
267{
268 Display display = 0;
269 Error err = mHal.createVirtualDisplay(width, height,
270 &formatHint, &display);
271 if (err == Error::NONE) {
272 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
273
274 auto dpy = mDisplayData.emplace(display, DisplayData(true)).first;
275 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
276 }
277
278 hidl_cb(err, display, formatHint);
279 return Void();
280}
281
282Return<Error> ComposerClient::destroyVirtualDisplay(Display display)
283{
284 Error err = mHal.destroyVirtualDisplay(display);
285 if (err == Error::NONE) {
286 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
287
288 mDisplayData.erase(display);
289 }
290
291 return err;
292}
293
294Return<void> ComposerClient::createLayer(Display display,
295 uint32_t bufferSlotCount, createLayer_cb hidl_cb)
296{
297 Layer layer = 0;
298 Error err = mHal.createLayer(display, &layer);
299 if (err == Error::NONE) {
300 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
301 auto dpy = mDisplayData.find(display);
302 // The display entry may have already been removed by onHotplug.
303 if (dpy != mDisplayData.end()) {
304 auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
305 ly->second.Buffers.resize(bufferSlotCount);
306 } else {
307 err = Error::BAD_DISPLAY;
308 // Note: We do not destroy the layer on this error as the hotplug
309 // disconnect invalidates the display id. The implementation should
310 // ensure all layers for the display are destroyed.
311 }
312 }
313
314 hidl_cb(err, layer);
315 return Void();
316}
317
318Return<Error> ComposerClient::destroyLayer(Display display, Layer layer)
319{
320 Error err = mHal.destroyLayer(display, layer);
321 if (err == Error::NONE) {
322 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
323
324 auto dpy = mDisplayData.find(display);
325 // The display entry may have already been removed by onHotplug.
326 if (dpy != mDisplayData.end()) {
327 dpy->second.Layers.erase(layer);
328 }
329 }
330
331 return err;
332}
333
334Return<void> ComposerClient::getActiveConfig(Display display,
335 getActiveConfig_cb hidl_cb)
336{
337 Config config = 0;
338 Error err = mHal.getActiveConfig(display, &config);
339
340 hidl_cb(err, config);
341 return Void();
342}
343
344Return<Error> ComposerClient::getClientTargetSupport(Display display,
345 uint32_t width, uint32_t height,
346 PixelFormat format, Dataspace dataspace)
347{
348 Error err = mHal.getClientTargetSupport(display,
349 width, height, format, dataspace);
350 return err;
351}
352
353Return<void> ComposerClient::getColorModes(Display display,
354 getColorModes_cb hidl_cb)
355{
356 hidl_vec<ColorMode> modes;
357 Error err = mHal.getColorModes(display, &modes);
358
359 hidl_cb(err, modes);
360 return Void();
361}
362
363Return<void> ComposerClient::getDisplayAttribute(Display display,
364 Config config, Attribute attribute,
365 getDisplayAttribute_cb hidl_cb)
366{
367 int32_t value = 0;
368 Error err = mHal.getDisplayAttribute(display, config, attribute, &value);
369
370 hidl_cb(err, value);
371 return Void();
372}
373
374Return<void> ComposerClient::getDisplayConfigs(Display display,
375 getDisplayConfigs_cb hidl_cb)
376{
377 hidl_vec<Config> configs;
378 Error err = mHal.getDisplayConfigs(display, &configs);
379
380 hidl_cb(err, configs);
381 return Void();
382}
383
384Return<void> ComposerClient::getDisplayName(Display display,
385 getDisplayName_cb hidl_cb)
386{
387 hidl_string name;
388 Error err = mHal.getDisplayName(display, &name);
389
390 hidl_cb(err, name);
391 return Void();
392}
393
394Return<void> ComposerClient::getDisplayType(Display display,
395 getDisplayType_cb hidl_cb)
396{
397 DisplayType type = DisplayType::INVALID;
398 Error err = mHal.getDisplayType(display, &type);
399
400 hidl_cb(err, type);
401 return Void();
402}
403
404Return<void> ComposerClient::getDozeSupport(Display display,
405 getDozeSupport_cb hidl_cb)
406{
407 bool support = false;
408 Error err = mHal.getDozeSupport(display, &support);
409
410 hidl_cb(err, support);
411 return Void();
412}
413
414Return<void> ComposerClient::getHdrCapabilities(Display display,
415 getHdrCapabilities_cb hidl_cb)
416{
417 hidl_vec<Hdr> types;
418 float max_lumi = 0.0f;
419 float max_avg_lumi = 0.0f;
420 float min_lumi = 0.0f;
421 Error err = mHal.getHdrCapabilities(display, &types,
422 &max_lumi, &max_avg_lumi, &min_lumi);
423
424 hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
425 return Void();
426}
427
428Return<Error> ComposerClient::setClientTargetSlotCount(Display display,
429 uint32_t clientTargetSlotCount)
430{
431 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
432
433 auto dpy = mDisplayData.find(display);
434 if (dpy == mDisplayData.end()) {
435 return Error::BAD_DISPLAY;
436 }
437
438 dpy->second.ClientTargets.resize(clientTargetSlotCount);
439
440 return Error::NONE;
441}
442
443Return<Error> ComposerClient::setActiveConfig(Display display, Config config)
444{
445 Error err = mHal.setActiveConfig(display, config);
446 return err;
447}
448
449Return<Error> ComposerClient::setColorMode(Display display, ColorMode mode)
450{
451 Error err = mHal.setColorMode(display, mode);
452 return err;
453}
454
455Return<Error> ComposerClient::setPowerMode(Display display, PowerMode mode)
456{
457 Error err = mHal.setPowerMode(display, mode);
458 return err;
459}
460
461Return<Error> ComposerClient::setVsyncEnabled(Display display, Vsync enabled)
462{
463 Error err = mHal.setVsyncEnabled(display, enabled);
464 return err;
465}
466
467Return<Error> ComposerClient::setInputCommandQueue(
468 const MQDescriptorSync<uint32_t>& descriptor)
469{
470 std::lock_guard<std::mutex> lock(mCommandMutex);
471 return mReader->setMQDescriptor(descriptor) ?
472 Error::NONE : Error::NO_RESOURCES;
473}
474
475Return<void> ComposerClient::getOutputCommandQueue(
476 getOutputCommandQueue_cb hidl_cb)
477{
478 // no locking as we require this function to be called inside
479 // executeCommands_cb
480
481 auto outDescriptor = mWriter.getMQDescriptor();
482 if (outDescriptor) {
483 hidl_cb(Error::NONE, *outDescriptor);
484 } else {
485 hidl_cb(Error::NO_RESOURCES, CommandQueueType::Descriptor());
486 }
487
488 return Void();
489}
490
491Return<void> ComposerClient::executeCommands(uint32_t inLength,
492 const hidl_vec<hidl_handle>& inHandles,
493 executeCommands_cb hidl_cb)
494{
495 std::lock_guard<std::mutex> lock(mCommandMutex);
496
497 bool outChanged = false;
498 uint32_t outLength = 0;
499 hidl_vec<hidl_handle> outHandles;
500
501 if (!mReader->readQueue(inLength, inHandles)) {
502 hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
503 return Void();
504 }
505
506 Error err = mReader->parse();
507 if (err == Error::NONE &&
508 !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
509 err = Error::NO_RESOURCES;
510 }
511
512 hidl_cb(err, outChanged, outLength, outHandles);
513
514 mReader->reset();
515 mWriter.reset();
516
517 return Void();
518}
519
520std::unique_ptr<ComposerClient::CommandReader>
521ComposerClient::createCommandReader()
522{
523 return std::unique_ptr<ComposerClient::CommandReader>(
524 new CommandReader(*this));
525}
526
527ComposerClient::CommandReader::CommandReader(ComposerClient& client)
528 : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
529{
530}
531
532ComposerClient::CommandReader::~CommandReader()
533{
534}
535
536Error ComposerClient::CommandReader::parse()
537{
538 IComposerClient::Command command;
539 uint16_t length = 0;
540
541 while (!isEmpty()) {
542 if (!beginCommand(&command, &length)) {
543 break;
544 }
545
546 bool parsed = parseCommand(command, length);
547 endCommand();
548
549 if (!parsed) {
550 ALOGE("failed to parse command 0x%x, length %" PRIu16,
551 command, length);
552 break;
553 }
554 }
555
556 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
557}
558
559bool ComposerClient::CommandReader::parseCommand(
560 IComposerClient::Command command, uint16_t length) {
561 switch (command) {
562 case IComposerClient::Command::SELECT_DISPLAY:
563 return parseSelectDisplay(length);
564 case IComposerClient::Command::SELECT_LAYER:
565 return parseSelectLayer(length);
566 case IComposerClient::Command::SET_COLOR_TRANSFORM:
567 return parseSetColorTransform(length);
568 case IComposerClient::Command::SET_CLIENT_TARGET:
569 return parseSetClientTarget(length);
570 case IComposerClient::Command::SET_OUTPUT_BUFFER:
571 return parseSetOutputBuffer(length);
572 case IComposerClient::Command::VALIDATE_DISPLAY:
573 return parseValidateDisplay(length);
574 case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
575 return parsePresentOrValidateDisplay(length);
576 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
577 return parseAcceptDisplayChanges(length);
578 case IComposerClient::Command::PRESENT_DISPLAY:
579 return parsePresentDisplay(length);
580 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
581 return parseSetLayerCursorPosition(length);
582 case IComposerClient::Command::SET_LAYER_BUFFER:
583 return parseSetLayerBuffer(length);
584 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
585 return parseSetLayerSurfaceDamage(length);
586 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
587 return parseSetLayerBlendMode(length);
588 case IComposerClient::Command::SET_LAYER_COLOR:
589 return parseSetLayerColor(length);
590 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
591 return parseSetLayerCompositionType(length);
592 case IComposerClient::Command::SET_LAYER_DATASPACE:
593 return parseSetLayerDataspace(length);
594 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
595 return parseSetLayerDisplayFrame(length);
596 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
597 return parseSetLayerPlaneAlpha(length);
598 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
599 return parseSetLayerSidebandStream(length);
600 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
601 return parseSetLayerSourceCrop(length);
602 case IComposerClient::Command::SET_LAYER_TRANSFORM:
603 return parseSetLayerTransform(length);
604 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
605 return parseSetLayerVisibleRegion(length);
606 case IComposerClient::Command::SET_LAYER_Z_ORDER:
607 return parseSetLayerZOrder(length);
608 default:
609 return false;
610 }
611}
612
613bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
614{
615 if (length != CommandWriterBase::kSelectDisplayLength) {
616 return false;
617 }
618
619 mDisplay = read64();
620 mWriter.selectDisplay(mDisplay);
621
622 return true;
623}
624
625bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
626{
627 if (length != CommandWriterBase::kSelectLayerLength) {
628 return false;
629 }
630
631 mLayer = read64();
632
633 return true;
634}
635
636bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
637{
638 if (length != CommandWriterBase::kSetColorTransformLength) {
639 return false;
640 }
641
642 float matrix[16];
643 for (int i = 0; i < 16; i++) {
644 matrix[i] = readFloat();
645 }
646 auto transform = readSigned();
647
648 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
649 if (err != Error::NONE) {
650 mWriter.setError(getCommandLoc(), err);
651 }
652
653 return true;
654}
655
656bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
657{
658 // 4 parameters followed by N rectangles
659 if ((length - 4) % 4 != 0) {
660 return false;
661 }
662
663 bool useCache = false;
664 auto slot = read();
665 auto clientTarget = readHandle(&useCache);
666 auto fence = readFence();
667 auto dataspace = readSigned();
668 auto damage = readRegion((length - 4) / 4);
669 bool closeFence = true;
670
671 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
672 slot, useCache, clientTarget, &clientTarget);
673 if (err == Error::NONE) {
674 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
675 dataspace, damage);
676 auto updateBufErr = updateBuffer(BufferCache::CLIENT_TARGETS, slot,
677 useCache, clientTarget);
678 if (err == Error::NONE) {
679 closeFence = false;
680 err = updateBufErr;
681 }
682 }
683 if (closeFence) {
684 close(fence);
685 }
686 if (err != Error::NONE) {
687 mWriter.setError(getCommandLoc(), err);
688 }
689
690 return true;
691}
692
693bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
694{
695 if (length != CommandWriterBase::kSetOutputBufferLength) {
696 return false;
697 }
698
699 bool useCache = false;
700 auto slot = read();
701 auto outputBuffer = readHandle(&useCache);
702 auto fence = readFence();
703 bool closeFence = true;
704
705 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
706 slot, useCache, outputBuffer, &outputBuffer);
707 if (err == Error::NONE) {
708 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
709 auto updateBufErr = updateBuffer(BufferCache::OUTPUT_BUFFERS,
710 slot, useCache, outputBuffer);
711 if (err == Error::NONE) {
712 closeFence = false;
713 err = updateBufErr;
714 }
715 }
716 if (closeFence) {
717 close(fence);
718 }
719 if (err != Error::NONE) {
720 mWriter.setError(getCommandLoc(), err);
721 }
722
723 return true;
724}
725
726bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
727{
728 if (length != CommandWriterBase::kValidateDisplayLength) {
729 return false;
730 }
731
732 std::vector<Layer> changedLayers;
733 std::vector<IComposerClient::Composition> compositionTypes;
734 uint32_t displayRequestMask = 0x0;
735 std::vector<Layer> requestedLayers;
736 std::vector<uint32_t> requestMasks;
737
738 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
739 &compositionTypes, &displayRequestMask,
740 &requestedLayers, &requestMasks);
741 if (err == Error::NONE) {
742 mWriter.setChangedCompositionTypes(changedLayers,
743 compositionTypes);
744 mWriter.setDisplayRequests(displayRequestMask,
745 requestedLayers, requestMasks);
746 } else {
747 mWriter.setError(getCommandLoc(), err);
748 }
749
750 return true;
751}
752
753bool ComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length)
754{
755 if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
756 return false;
757 }
758
759 // First try to Present as is.
760 if (mHal.hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
761 int presentFence = -1;
762 std::vector<Layer> layers;
763 std::vector<int> fences;
764 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
765 if (err == Error::NONE) {
766 mWriter.setPresentOrValidateResult(1);
767 mWriter.setPresentFence(presentFence);
768 mWriter.setReleaseFences(layers, fences);
769 return true;
770 }
771 }
772
773 // Present has failed. We need to fallback to validate
774 std::vector<Layer> changedLayers;
775 std::vector<IComposerClient::Composition> compositionTypes;
776 uint32_t displayRequestMask = 0x0;
777 std::vector<Layer> requestedLayers;
778 std::vector<uint32_t> requestMasks;
779
780 auto err = mHal.validateDisplay(mDisplay, &changedLayers, &compositionTypes,
781 &displayRequestMask, &requestedLayers, &requestMasks);
782 if (err == Error::NONE) {
783 mWriter.setPresentOrValidateResult(0);
784 mWriter.setChangedCompositionTypes(changedLayers,
785 compositionTypes);
786 mWriter.setDisplayRequests(displayRequestMask,
787 requestedLayers, requestMasks);
788 } else {
789 mWriter.setError(getCommandLoc(), err);
790 }
791
792 return true;
793}
794
795bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
796{
797 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
798 return false;
799 }
800
801 auto err = mHal.acceptDisplayChanges(mDisplay);
802 if (err != Error::NONE) {
803 mWriter.setError(getCommandLoc(), err);
804 }
805
806 return true;
807}
808
809bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
810{
811 if (length != CommandWriterBase::kPresentDisplayLength) {
812 return false;
813 }
814
815 int presentFence = -1;
816 std::vector<Layer> layers;
817 std::vector<int> fences;
818 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
819 if (err == Error::NONE) {
820 mWriter.setPresentFence(presentFence);
821 mWriter.setReleaseFences(layers, fences);
822 } else {
823 mWriter.setError(getCommandLoc(), err);
824 }
825
826 return true;
827}
828
829bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
830{
831 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
832 return false;
833 }
834
835 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
836 readSigned(), readSigned());
837 if (err != Error::NONE) {
838 mWriter.setError(getCommandLoc(), err);
839 }
840
841 return true;
842}
843
844bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
845{
846 if (length != CommandWriterBase::kSetLayerBufferLength) {
847 return false;
848 }
849
850 bool useCache = false;
851 auto slot = read();
852 auto buffer = readHandle(&useCache);
853 auto fence = readFence();
854 bool closeFence = true;
855
856 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
857 slot, useCache, buffer, &buffer);
858 if (err == Error::NONE) {
859 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
860 auto updateBufErr = updateBuffer(BufferCache::LAYER_BUFFERS, slot,
861 useCache, buffer);
862 if (err == Error::NONE) {
863 closeFence = false;
864 err = updateBufErr;
865 }
866 }
867 if (closeFence) {
868 close(fence);
869 }
870 if (err != Error::NONE) {
871 mWriter.setError(getCommandLoc(), err);
872 }
873
874 return true;
875}
876
877bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
878{
879 // N rectangles
880 if (length % 4 != 0) {
881 return false;
882 }
883
884 auto damage = readRegion(length / 4);
885 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
886 if (err != Error::NONE) {
887 mWriter.setError(getCommandLoc(), err);
888 }
889
890 return true;
891}
892
893bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
894{
895 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
896 return false;
897 }
898
899 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
900 if (err != Error::NONE) {
901 mWriter.setError(getCommandLoc(), err);
902 }
903
904 return true;
905}
906
907bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
908{
909 if (length != CommandWriterBase::kSetLayerColorLength) {
910 return false;
911 }
912
913 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
914 if (err != Error::NONE) {
915 mWriter.setError(getCommandLoc(), err);
916 }
917
918 return true;
919}
920
921bool ComposerClient::CommandReader::parseSetLayerCompositionType(
922 uint16_t length)
923{
924 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
925 return false;
926 }
927
928 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
929 if (err != Error::NONE) {
930 mWriter.setError(getCommandLoc(), err);
931 }
932
933 return true;
934}
935
936bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
937{
938 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
939 return false;
940 }
941
942 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
943 if (err != Error::NONE) {
944 mWriter.setError(getCommandLoc(), err);
945 }
946
947 return true;
948}
949
950bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
951{
952 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
953 return false;
954 }
955
956 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
957 if (err != Error::NONE) {
958 mWriter.setError(getCommandLoc(), err);
959 }
960
961 return true;
962}
963
964bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
965{
966 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
967 return false;
968 }
969
970 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
971 if (err != Error::NONE) {
972 mWriter.setError(getCommandLoc(), err);
973 }
974
975 return true;
976}
977
978bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
979{
980 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
981 return false;
982 }
983
984 auto stream = readHandle();
985
986 auto err = lookupLayerSidebandStream(stream, &stream);
987 if (err == Error::NONE) {
988 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
989 auto updateErr = updateLayerSidebandStream(stream);
990 if (err == Error::NONE) {
991 err = updateErr;
992 }
993 }
994 if (err != Error::NONE) {
995 mWriter.setError(getCommandLoc(), err);
996 }
997
998 return true;
999}
1000
1001bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
1002{
1003 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
1004 return false;
1005 }
1006
1007 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
1008 if (err != Error::NONE) {
1009 mWriter.setError(getCommandLoc(), err);
1010 }
1011
1012 return true;
1013}
1014
1015bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
1016{
1017 if (length != CommandWriterBase::kSetLayerTransformLength) {
1018 return false;
1019 }
1020
1021 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
1022 if (err != Error::NONE) {
1023 mWriter.setError(getCommandLoc(), err);
1024 }
1025
1026 return true;
1027}
1028
1029bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
1030{
1031 // N rectangles
1032 if (length % 4 != 0) {
1033 return false;
1034 }
1035
1036 auto region = readRegion(length / 4);
1037 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1038 if (err != Error::NONE) {
1039 mWriter.setError(getCommandLoc(), err);
1040 }
1041
1042 return true;
1043}
1044
1045bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
1046{
1047 if (length != CommandWriterBase::kSetLayerZOrderLength) {
1048 return false;
1049 }
1050
1051 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1052 if (err != Error::NONE) {
1053 mWriter.setError(getCommandLoc(), err);
1054 }
1055
1056 return true;
1057}
1058
1059hwc_rect_t ComposerClient::CommandReader::readRect()
1060{
1061 return hwc_rect_t{
1062 readSigned(),
1063 readSigned(),
1064 readSigned(),
1065 readSigned(),
1066 };
1067}
1068
1069std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
1070{
1071 std::vector<hwc_rect_t> region;
1072 region.reserve(count);
1073 while (count > 0) {
1074 region.emplace_back(readRect());
1075 count--;
1076 }
1077
1078 return region;
1079}
1080
1081hwc_frect_t ComposerClient::CommandReader::readFRect()
1082{
1083 return hwc_frect_t{
1084 readFloat(),
1085 readFloat(),
1086 readFloat(),
1087 readFloat(),
1088 };
1089}
1090
1091Error ComposerClient::CommandReader::lookupBufferCacheEntryLocked(
1092 BufferCache cache, uint32_t slot, BufferCacheEntry** outEntry)
1093{
1094 auto dpy = mClient.mDisplayData.find(mDisplay);
1095 if (dpy == mClient.mDisplayData.end()) {
1096 return Error::BAD_DISPLAY;
1097 }
1098
1099 BufferCacheEntry* entry = nullptr;
1100 switch (cache) {
1101 case BufferCache::CLIENT_TARGETS:
1102 if (slot < dpy->second.ClientTargets.size()) {
1103 entry = &dpy->second.ClientTargets[slot];
1104 }
1105 break;
1106 case BufferCache::OUTPUT_BUFFERS:
1107 if (slot < dpy->second.OutputBuffers.size()) {
1108 entry = &dpy->second.OutputBuffers[slot];
1109 }
1110 break;
1111 case BufferCache::LAYER_BUFFERS:
1112 {
1113 auto ly = dpy->second.Layers.find(mLayer);
1114 if (ly == dpy->second.Layers.end()) {
1115 return Error::BAD_LAYER;
1116 }
1117 if (slot < ly->second.Buffers.size()) {
1118 entry = &ly->second.Buffers[slot];
1119 }
1120 }
1121 break;
1122 case BufferCache::LAYER_SIDEBAND_STREAMS:
1123 {
1124 auto ly = dpy->second.Layers.find(mLayer);
1125 if (ly == dpy->second.Layers.end()) {
1126 return Error::BAD_LAYER;
1127 }
1128 if (slot == 0) {
1129 entry = &ly->second.SidebandStream;
1130 }
1131 }
1132 break;
1133 default:
1134 break;
1135 }
1136
1137 if (!entry) {
1138 ALOGW("invalid buffer slot %" PRIu32, slot);
1139 return Error::BAD_PARAMETER;
1140 }
1141
1142 *outEntry = entry;
1143
1144 return Error::NONE;
1145}
1146
1147Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1148 uint32_t slot, bool useCache, buffer_handle_t handle,
1149 buffer_handle_t* outHandle)
1150{
1151 if (useCache) {
1152 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1153
1154 BufferCacheEntry* entry;
1155 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
1156 if (error != Error::NONE) {
1157 return error;
1158 }
1159
1160 // input handle is ignored
1161 *outHandle = entry->getHandle();
1162 } else if (cache == BufferCache::LAYER_SIDEBAND_STREAMS) {
1163 if (handle) {
1164 *outHandle = native_handle_clone(handle);
1165 if (*outHandle == nullptr) {
1166 return Error::NO_RESOURCES;
1167 }
1168 }
1169 } else {
1170 if (!sHandleImporter.importBuffer(handle)) {
1171 return Error::NO_RESOURCES;
1172 }
1173
1174 *outHandle = handle;
1175 }
1176
1177 return Error::NONE;
1178}
1179
1180Error ComposerClient::CommandReader::updateBuffer(BufferCache cache,
1181 uint32_t slot, bool useCache, buffer_handle_t handle)
1182{
1183 // handle was looked up from cache
1184 if (useCache) {
1185 return Error::NONE;
1186 }
1187
1188 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1189
1190 BufferCacheEntry* entry = nullptr;
1191 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
1192 if (error != Error::NONE) {
1193 return error;
1194 }
1195
1196 *entry = handle;
1197 return Error::NONE;
1198}
1199
1200} // namespace implementation
1201} // namespace V2_1
1202} // namespace composer
1203} // namespace graphics
1204} // namespace hardware
1205} // namespace android
diff --git a/graphics/composer/2.1/default/ComposerClient.h b/graphics/composer/2.1/default/ComposerClient.h
deleted file mode 100644
index 104ed5af..00000000
--- a/graphics/composer/2.1/default/ComposerClient.h
+++ /dev/null
@@ -1,225 +0,0 @@
1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_CLIENT_H
18#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_CLIENT_H
19
20#include <mutex>
21#include <unordered_map>
22#include <vector>
23
24#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
25#include <hardware/hwcomposer2.h>
26#include "ComposerBase.h"
27
28namespace android {
29namespace hardware {
30namespace graphics {
31namespace composer {
32namespace V2_1 {
33namespace implementation {
34
35class BufferCacheEntry {
36public:
37 BufferCacheEntry();
38 BufferCacheEntry(BufferCacheEntry&& other);
39
40 BufferCacheEntry(const BufferCacheEntry& other) = delete;
41 BufferCacheEntry& operator=(const BufferCacheEntry& other) = delete;
42
43 BufferCacheEntry& operator=(buffer_handle_t handle);
44 ~BufferCacheEntry();
45
46 buffer_handle_t getHandle() const { return mHandle; }
47
48private:
49 void clear();
50
51 buffer_handle_t mHandle;
52};
53
54class ComposerClient : public IComposerClient {
55public:
56 ComposerClient(ComposerBase& hal);
57 virtual ~ComposerClient();
58
59 void initialize();
60
61 void onHotplug(Display display, IComposerCallback::Connection connected);
62 void onRefresh(Display display);
63 void onVsync(Display display, int64_t timestamp);
64
65 // IComposerClient interface
66 Return<void> registerCallback(
67 const sp<IComposerCallback>& callback) override;
68 Return<uint32_t> getMaxVirtualDisplayCount() override;
69 Return<void> createVirtualDisplay(uint32_t width, uint32_t height,
70 PixelFormat formatHint, uint32_t outputBufferSlotCount,
71 createVirtualDisplay_cb hidl_cb) override;
72 Return<Error> destroyVirtualDisplay(Display display) override;
73 Return<void> createLayer(Display display, uint32_t bufferSlotCount,
74 createLayer_cb hidl_cb) override;
75 Return<Error> destroyLayer(Display display, Layer layer) override;
76 Return<void> getActiveConfig(Display display,
77 getActiveConfig_cb hidl_cb) override;
78 Return<Error> getClientTargetSupport(Display display,
79 uint32_t width, uint32_t height,
80 PixelFormat format, Dataspace dataspace) override;
81 Return<void> getColorModes(Display display,
82 getColorModes_cb hidl_cb) override;
83 Return<void> getDisplayAttribute(Display display,
84 Config config, Attribute attribute,
85 getDisplayAttribute_cb hidl_cb) override;
86 Return<void> getDisplayConfigs(Display display,
87 getDisplayConfigs_cb hidl_cb) override;
88 Return<void> getDisplayName(Display display,
89 getDisplayName_cb hidl_cb) override;
90 Return<void> getDisplayType(Display display,
91 getDisplayType_cb hidl_cb) override;
92 Return<void> getDozeSupport(Display display,
93 getDozeSupport_cb hidl_cb) override;
94 Return<void> getHdrCapabilities(Display display,
95 getHdrCapabilities_cb hidl_cb) override;
96 Return<Error> setActiveConfig(Display display, Config config) override;
97 Return<Error> setColorMode(Display display, ColorMode mode) override;
98 Return<Error> setPowerMode(Display display, PowerMode mode) override;
99 Return<Error> setVsyncEnabled(Display display, Vsync enabled) override;
100 Return<Error> setClientTargetSlotCount(Display display,
101 uint32_t clientTargetSlotCount) override;
102 Return<Error> setInputCommandQueue(
103 const MQDescriptorSync<uint32_t>& descriptor) override;
104 Return<void> getOutputCommandQueue(
105 getOutputCommandQueue_cb hidl_cb) override;
106 Return<void> executeCommands(uint32_t inLength,
107 const hidl_vec<hidl_handle>& inHandles,
108 executeCommands_cb hidl_cb) override;
109
110protected:
111 struct LayerBuffers {
112 std::vector<BufferCacheEntry> Buffers;
113 // the handle is a sideband stream handle, not a buffer handle
114 BufferCacheEntry SidebandStream;
115 };
116
117 struct DisplayData {
118 bool IsVirtual;
119
120 std::vector<BufferCacheEntry> ClientTargets;
121 std::vector<BufferCacheEntry> OutputBuffers;
122
123 std::unordered_map<Layer, LayerBuffers> Layers;
124
125 DisplayData(bool isVirtual) : IsVirtual(isVirtual) {}
126 };
127
128 class CommandReader : public CommandReaderBase {
129 public:
130 CommandReader(ComposerClient& client);
131 virtual ~CommandReader();
132
133 Error parse();
134
135 protected:
136 virtual bool parseCommand(IComposerClient::Command command,
137 uint16_t length);
138
139 bool parseSelectDisplay(uint16_t length);
140 bool parseSelectLayer(uint16_t length);
141 bool parseSetColorTransform(uint16_t length);
142 bool parseSetClientTarget(uint16_t length);
143 bool parseSetOutputBuffer(uint16_t length);
144 bool parseValidateDisplay(uint16_t length);
145 bool parsePresentOrValidateDisplay(uint16_t length);
146 bool parseAcceptDisplayChanges(uint16_t length);
147 bool parsePresentDisplay(uint16_t length);
148 bool parseSetLayerCursorPosition(uint16_t length);
149 bool parseSetLayerBuffer(uint16_t length);
150 bool parseSetLayerSurfaceDamage(uint16_t length);
151 bool parseSetLayerBlendMode(uint16_t length);
152 bool parseSetLayerColor(uint16_t length);
153 bool parseSetLayerCompositionType(uint16_t length);
154 bool parseSetLayerDataspace(uint16_t length);
155 bool parseSetLayerDisplayFrame(uint16_t length);
156 bool parseSetLayerPlaneAlpha(uint16_t length);
157 bool parseSetLayerSidebandStream(uint16_t length);
158 bool parseSetLayerSourceCrop(uint16_t length);
159 bool parseSetLayerTransform(uint16_t length);
160 bool parseSetLayerVisibleRegion(uint16_t length);
161 bool parseSetLayerZOrder(uint16_t length);
162
163 hwc_rect_t readRect();
164 std::vector<hwc_rect_t> readRegion(size_t count);
165 hwc_frect_t readFRect();
166
167 enum class BufferCache {
168 CLIENT_TARGETS,
169 OUTPUT_BUFFERS,
170 LAYER_BUFFERS,
171 LAYER_SIDEBAND_STREAMS,
172 };
173 Error lookupBufferCacheEntryLocked(BufferCache cache, uint32_t slot,
174 BufferCacheEntry** outEntry);
175 Error lookupBuffer(BufferCache cache, uint32_t slot,
176 bool useCache, buffer_handle_t handle,
177 buffer_handle_t* outHandle);
178 Error updateBuffer(BufferCache cache, uint32_t slot,
179 bool useCache, buffer_handle_t handle);
180
181 Error lookupLayerSidebandStream(buffer_handle_t handle,
182 buffer_handle_t* outHandle)
183 {
184 return lookupBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
185 0, false, handle, outHandle);
186 }
187 Error updateLayerSidebandStream(buffer_handle_t handle)
188 {
189 return updateBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
190 0, false, handle);
191 }
192
193 ComposerClient& mClient;
194 ComposerBase& mHal;
195 CommandWriterBase& mWriter;
196
197 Display mDisplay;
198 Layer mLayer;
199 };
200
201 virtual std::unique_ptr<CommandReader> createCommandReader();
202
203 ComposerBase& mHal;
204
205 // 64KiB minus a small space for metadata such as read/write pointers
206 static constexpr size_t kWriterInitialSize =
207 64 * 1024 / sizeof(uint32_t) - 16;
208 std::mutex mCommandMutex;
209 std::unique_ptr<CommandReader> mReader;
210 CommandWriterBase mWriter;
211
212 sp<IComposerCallback> mCallback;
213
214 std::mutex mDisplayDataMutex;
215 std::unordered_map<Display, DisplayData> mDisplayData;
216};
217
218} // namespace implementation
219} // namespace V2_1
220} // namespace composer
221} // namespace graphics
222} // namespace hardware
223} // namespace android
224
225#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_COMPOSER_CLIENT_H
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
deleted file mode 100644
index cb393eca..00000000
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ /dev/null
@@ -1,817 +0,0 @@
1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "HwcPassthrough"
18
19#include "Hwc.h"
20
21#include <chrono>
22#include <type_traits>
23#include <log/log.h>
24
25#include "ComposerClient.h"
26#include "hardware/fb.h"
27#include "hardware/hwcomposer.h"
28#include "hwc2on1adapter/HWC2On1Adapter.h"
29#include "hwc2onfbadapter/HWC2OnFbAdapter.h"
30
31using namespace std::chrono_literals;
32
33namespace android {
34namespace hardware {
35namespace graphics {
36namespace composer {
37namespace V2_1 {
38namespace implementation {
39
40HwcHal::HwcHal(const hw_module_t* module)
41 : mDevice(nullptr), mDispatch(), mMustValidateDisplay(true), mAdapter() {
42 uint32_t majorVersion;
43 if (module->id && strcmp(module->id, GRALLOC_HARDWARE_MODULE_ID) == 0) {
44 majorVersion = initWithFb(module);
45 } else {
46 majorVersion = initWithHwc(module);
47 }
48
49 initCapabilities();
50 if (majorVersion >= 2 && hasCapability(HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE)) {
51 ALOGE("Present fence must be reliable from HWC2 on.");
52 abort();
53 }
54
55 initDispatch();
56}
57
58HwcHal::~HwcHal()
59{
60 hwc2_close(mDevice);
61}
62
63uint32_t HwcHal::initWithHwc(const hw_module_t* module)
64{
65 // Determine what kind of module is available (HWC2 vs HWC1.X).
66 hw_device_t* device = nullptr;
67 int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
68 if (error != 0) {
69 ALOGE("Failed to open HWC device (%s), aborting", strerror(-error));
70 abort();
71 }
72 uint32_t majorVersion = (device->version >> 24) & 0xF;
73
74 // If we don't have a HWC2, we need to wrap whatever we have in an adapter.
75 if (majorVersion != 2) {
76 uint32_t minorVersion = device->version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
77 minorVersion = (minorVersion >> 16) & 0xF;
78 ALOGI("Found HWC implementation v%d.%d", majorVersion, minorVersion);
79 if (minorVersion < 1) {
80 ALOGE("Cannot adapt to HWC version %d.%d. Minimum supported is 1.1",
81 majorVersion, minorVersion);
82 abort();
83 }
84 mAdapter = std::make_unique<HWC2On1Adapter>(
85 reinterpret_cast<hwc_composer_device_1*>(device));
86
87 // Place the adapter in front of the device module.
88 mDevice = mAdapter.get();
89 } else {
90 mDevice = reinterpret_cast<hwc2_device_t*>(device);
91 }
92
93 return majorVersion;
94}
95
96uint32_t HwcHal::initWithFb(const hw_module_t* module)
97{
98 framebuffer_device_t* fb_device;
99 int error = framebuffer_open(module, &fb_device);
100 if (error != 0) {
101 ALOGE("Failed to open FB device (%s), aborting", strerror(-error));
102 abort();
103 }
104
105 mFbAdapter = std::make_unique<HWC2OnFbAdapter>(fb_device);
106 mDevice = mFbAdapter.get();
107
108 return 0;
109}
110
111void HwcHal::initCapabilities()
112{
113 uint32_t count = 0;
114 mDevice->getCapabilities(mDevice, &count, nullptr);
115
116 std::vector<int32_t> caps(count);
117 mDevice->getCapabilities(mDevice, &count, caps.data());
118 caps.resize(count);
119
120 mCapabilities.reserve(count);
121 for (auto cap : caps) {
122 mCapabilities.insert(static_cast<hwc2_capability_t>(cap));
123 }
124}
125
126template<typename T>
127void HwcHal::initDispatch(hwc2_function_descriptor_t desc, T* outPfn)
128{
129 auto pfn = mDevice->getFunction(mDevice, desc);
130 if (!pfn) {
131 LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc);
132 }
133
134 *outPfn = reinterpret_cast<T>(pfn);
135}
136
137void HwcHal::initDispatch()
138{
139 initDispatch(HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
140 &mDispatch.acceptDisplayChanges);
141 initDispatch(HWC2_FUNCTION_CREATE_LAYER, &mDispatch.createLayer);
142 initDispatch(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
143 &mDispatch.createVirtualDisplay);
144 initDispatch(HWC2_FUNCTION_DESTROY_LAYER, &mDispatch.destroyLayer);
145 initDispatch(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
146 &mDispatch.destroyVirtualDisplay);
147 initDispatch(HWC2_FUNCTION_DUMP, &mDispatch.dump);
148 initDispatch(HWC2_FUNCTION_GET_ACTIVE_CONFIG, &mDispatch.getActiveConfig);
149 initDispatch(HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
150 &mDispatch.getChangedCompositionTypes);
151 initDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
152 &mDispatch.getClientTargetSupport);
153 initDispatch(HWC2_FUNCTION_GET_COLOR_MODES, &mDispatch.getColorModes);
154 initDispatch(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
155 &mDispatch.getDisplayAttribute);
156 initDispatch(HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
157 &mDispatch.getDisplayConfigs);
158 initDispatch(HWC2_FUNCTION_GET_DISPLAY_NAME, &mDispatch.getDisplayName);
159 initDispatch(HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
160 &mDispatch.getDisplayRequests);
161 initDispatch(HWC2_FUNCTION_GET_DISPLAY_TYPE, &mDispatch.getDisplayType);
162 initDispatch(HWC2_FUNCTION_GET_DOZE_SUPPORT, &mDispatch.getDozeSupport);
163 initDispatch(HWC2_FUNCTION_GET_HDR_CAPABILITIES,
164 &mDispatch.getHdrCapabilities);
165 initDispatch(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
166 &mDispatch.getMaxVirtualDisplayCount);
167 initDispatch(HWC2_FUNCTION_GET_RELEASE_FENCES,
168 &mDispatch.getReleaseFences);
169 initDispatch(HWC2_FUNCTION_PRESENT_DISPLAY, &mDispatch.presentDisplay);
170 initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK,
171 &mDispatch.registerCallback);
172 initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG, &mDispatch.setActiveConfig);
173 initDispatch(HWC2_FUNCTION_SET_CLIENT_TARGET, &mDispatch.setClientTarget);
174 initDispatch(HWC2_FUNCTION_SET_COLOR_MODE, &mDispatch.setColorMode);
175 initDispatch(HWC2_FUNCTION_SET_COLOR_TRANSFORM,
176 &mDispatch.setColorTransform);
177 initDispatch(HWC2_FUNCTION_SET_CURSOR_POSITION,
178 &mDispatch.setCursorPosition);
179 initDispatch(HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
180 &mDispatch.setLayerBlendMode);
181 initDispatch(HWC2_FUNCTION_SET_LAYER_BUFFER, &mDispatch.setLayerBuffer);
182 initDispatch(HWC2_FUNCTION_SET_LAYER_COLOR, &mDispatch.setLayerColor);
183 initDispatch(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
184 &mDispatch.setLayerCompositionType);
185 initDispatch(HWC2_FUNCTION_SET_LAYER_DATASPACE,
186 &mDispatch.setLayerDataspace);
187 initDispatch(HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
188 &mDispatch.setLayerDisplayFrame);
189 initDispatch(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
190 &mDispatch.setLayerPlaneAlpha);
191
192 if (hasCapability(HWC2_CAPABILITY_SIDEBAND_STREAM)) {
193 initDispatch(HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM,
194 &mDispatch.setLayerSidebandStream);
195 }
196
197 initDispatch(HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
198 &mDispatch.setLayerSourceCrop);
199 initDispatch(HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
200 &mDispatch.setLayerSurfaceDamage);
201 initDispatch(HWC2_FUNCTION_SET_LAYER_TRANSFORM,
202 &mDispatch.setLayerTransform);
203 initDispatch(HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
204 &mDispatch.setLayerVisibleRegion);
205 initDispatch(HWC2_FUNCTION_SET_LAYER_Z_ORDER, &mDispatch.setLayerZOrder);
206 initDispatch(HWC2_FUNCTION_SET_OUTPUT_BUFFER, &mDispatch.setOutputBuffer);
207 initDispatch(HWC2_FUNCTION_SET_POWER_MODE, &mDispatch.setPowerMode);
208 initDispatch(HWC2_FUNCTION_SET_VSYNC_ENABLED, &mDispatch.setVsyncEnabled);
209 initDispatch(HWC2_FUNCTION_VALIDATE_DISPLAY, &mDispatch.validateDisplay);
210}
211
212bool HwcHal::hasCapability(hwc2_capability_t capability) {
213 return (mCapabilities.count(capability) > 0);
214}
215
216Return<void> HwcHal::getCapabilities(getCapabilities_cb hidl_cb)
217{
218 std::vector<Capability> caps;
219 caps.reserve(mCapabilities.size());
220 for (auto cap : mCapabilities) {
221 switch (cap) {
222 case HWC2_CAPABILITY_SIDEBAND_STREAM:
223 case HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM:
224 case HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE:
225 caps.push_back(static_cast<Capability>(cap));
226 break;
227 default:
228 // not all HWC2 caps are defined in HIDL
229 break;
230 }
231 }
232
233 hidl_vec<Capability> caps_reply;
234 caps_reply.setToExternal(caps.data(), caps.size());
235 hidl_cb(caps_reply);
236
237 return Void();
238}
239
240Return<void> HwcHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
241{
242 uint32_t len = 0;
243 mDispatch.dump(mDevice, &len, nullptr);
244
245 std::vector<char> buf(len + 1);
246 mDispatch.dump(mDevice, &len, buf.data());
247 buf.resize(len + 1);
248 buf[len] = '\0';
249
250 hidl_string buf_reply;
251 buf_reply.setToExternal(buf.data(), len);
252 hidl_cb(buf_reply);
253
254 return Void();
255}
256
257Return<void> HwcHal::createClient(createClient_cb hidl_cb)
258{
259 Error err = Error::NONE;
260 sp<ComposerClient> client;
261
262 {
263 std::unique_lock<std::mutex> lock(mClientMutex);
264
265 if (mClient != nullptr) {
266 // In surface flinger we delete a composer client on one thread and
267 // then create a new client on another thread. Although surface
268 // flinger ensures the calls are made in that sequence (destroy and
269 // then create), sometimes the calls land in the composer service
270 // inverted (create and then destroy). Wait for a brief period to
271 // see if the existing client is destroyed.
272 ALOGI("HwcHal::createClient: Client already exists. Waiting for"
273 " it to be destroyed.");
274 mClientDestroyedWait.wait_for(lock, 1s,
275 [this] { return mClient == nullptr; });
276 std::string doneMsg = mClient == nullptr ?
277 "Existing client was destroyed." :
278 "Existing client was never destroyed!";
279 ALOGI("HwcHal::createClient: Done waiting. %s", doneMsg.c_str());
280 }
281
282 // only one client is allowed
283 if (mClient == nullptr) {
284 client = new ComposerClient(*this);
285 client->initialize();
286 mClient = client;
287 } else {
288 err = Error::NO_RESOURCES;
289 }
290 }
291
292 hidl_cb(err, client);
293
294 return Void();
295}
296
297sp<ComposerClient> HwcHal::getClient()
298{
299 std::lock_guard<std::mutex> lock(mClientMutex);
300 return (mClient != nullptr) ? mClient.promote() : nullptr;
301}
302
303void HwcHal::removeClient()
304{
305 std::lock_guard<std::mutex> lock(mClientMutex);
306 mClient = nullptr;
307 mClientDestroyedWait.notify_all();
308}
309
310void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
311 hwc2_display_t display, int32_t connected)
312{
313 auto hal = reinterpret_cast<HwcHal*>(callbackData);
314 auto client = hal->getClient();
315 if (client != nullptr) {
316 client->onHotplug(display,
317 static_cast<IComposerCallback::Connection>(connected));
318 }
319}
320
321void HwcHal::refreshHook(hwc2_callback_data_t callbackData,
322 hwc2_display_t display)
323{
324 auto hal = reinterpret_cast<HwcHal*>(callbackData);
325 hal->mMustValidateDisplay = true;
326
327 auto client = hal->getClient();
328 if (client != nullptr) {
329 client->onRefresh(display);
330 }
331}
332
333void HwcHal::vsyncHook(hwc2_callback_data_t callbackData,
334 hwc2_display_t display, int64_t timestamp)
335{
336 auto hal = reinterpret_cast<HwcHal*>(callbackData);
337 auto client = hal->getClient();
338 if (client != nullptr) {
339 client->onVsync(display, timestamp);
340 }
341}
342
343void HwcHal::enableCallback(bool enable)
344{
345 if (enable) {
346 mMustValidateDisplay = true;
347
348 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
349 reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
350 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
351 reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
352 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
353 reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
354 } else {
355 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
356 nullptr);
357 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
358 nullptr);
359 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
360 nullptr);
361 }
362}
363
364uint32_t HwcHal::getMaxVirtualDisplayCount()
365{
366 return mDispatch.getMaxVirtualDisplayCount(mDevice);
367}
368
369Error HwcHal::createVirtualDisplay(uint32_t width, uint32_t height,
370 PixelFormat* format, Display* outDisplay)
371{
372 int32_t hwc_format = static_cast<int32_t>(*format);
373 int32_t err = mDispatch.createVirtualDisplay(mDevice, width, height,
374 &hwc_format, outDisplay);
375 *format = static_cast<PixelFormat>(hwc_format);
376
377 return static_cast<Error>(err);
378}
379
380Error HwcHal::destroyVirtualDisplay(Display display)
381{
382 int32_t err = mDispatch.destroyVirtualDisplay(mDevice, display);
383 return static_cast<Error>(err);
384}
385
386Error HwcHal::createLayer(Display display, Layer* outLayer)
387{
388 int32_t err = mDispatch.createLayer(mDevice, display, outLayer);
389 return static_cast<Error>(err);
390}
391
392Error HwcHal::destroyLayer(Display display, Layer layer)
393{
394 int32_t err = mDispatch.destroyLayer(mDevice, display, layer);
395 return static_cast<Error>(err);
396}
397
398Error HwcHal::getActiveConfig(Display display, Config* outConfig)
399{
400 int32_t err = mDispatch.getActiveConfig(mDevice, display, outConfig);
401 return static_cast<Error>(err);
402}
403
404Error HwcHal::getClientTargetSupport(Display display,
405 uint32_t width, uint32_t height,
406 PixelFormat format, Dataspace dataspace)
407{
408 int32_t err = mDispatch.getClientTargetSupport(mDevice, display,
409 width, height, static_cast<int32_t>(format),
410 static_cast<int32_t>(dataspace));
411 return static_cast<Error>(err);
412}
413
414Error HwcHal::getColorModes(Display display, hidl_vec<ColorMode>* outModes)
415{
416 uint32_t count = 0;
417 int32_t err = mDispatch.getColorModes(mDevice, display, &count, nullptr);
418 if (err != HWC2_ERROR_NONE) {
419 return static_cast<Error>(err);
420 }
421
422 outModes->resize(count);
423 err = mDispatch.getColorModes(mDevice, display, &count,
424 reinterpret_cast<std::underlying_type<ColorMode>::type*>(
425 outModes->data()));
426 if (err != HWC2_ERROR_NONE) {
427 *outModes = hidl_vec<ColorMode>();
428 return static_cast<Error>(err);
429 }
430
431 return Error::NONE;
432}
433
434Error HwcHal::getDisplayAttribute(Display display, Config config,
435 IComposerClient::Attribute attribute, int32_t* outValue)
436{
437 int32_t err = mDispatch.getDisplayAttribute(mDevice, display, config,
438 static_cast<int32_t>(attribute), outValue);
439 return static_cast<Error>(err);
440}
441
442Error HwcHal::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs)
443{
444 uint32_t count = 0;
445 int32_t err = mDispatch.getDisplayConfigs(mDevice, display,
446 &count, nullptr);
447 if (err != HWC2_ERROR_NONE) {
448 return static_cast<Error>(err);
449 }
450
451 outConfigs->resize(count);
452 err = mDispatch.getDisplayConfigs(mDevice, display,
453 &count, outConfigs->data());
454 if (err != HWC2_ERROR_NONE) {
455 *outConfigs = hidl_vec<Config>();
456 return static_cast<Error>(err);
457 }
458
459 return Error::NONE;
460}
461
462Error HwcHal::getDisplayName(Display display, hidl_string* outName)
463{
464 uint32_t count = 0;
465 int32_t err = mDispatch.getDisplayName(mDevice, display, &count, nullptr);
466 if (err != HWC2_ERROR_NONE) {
467 return static_cast<Error>(err);
468 }
469
470 std::vector<char> buf(count + 1);
471 err = mDispatch.getDisplayName(mDevice, display, &count, buf.data());
472 if (err != HWC2_ERROR_NONE) {
473 return static_cast<Error>(err);
474 }
475 buf.resize(count + 1);
476 buf[count] = '\0';
477
478 *outName = buf.data();
479
480 return Error::NONE;
481}
482
483Error HwcHal::getDisplayType(Display display,
484 IComposerClient::DisplayType* outType)
485{
486 int32_t hwc_type = HWC2_DISPLAY_TYPE_INVALID;
487 int32_t err = mDispatch.getDisplayType(mDevice, display, &hwc_type);
488 *outType = static_cast<IComposerClient::DisplayType>(hwc_type);
489
490 return static_cast<Error>(err);
491}
492
493Error HwcHal::getDozeSupport(Display display, bool* outSupport)
494{
495 int32_t hwc_support = 0;
496 int32_t err = mDispatch.getDozeSupport(mDevice, display, &hwc_support);
497 *outSupport = hwc_support;
498
499 return static_cast<Error>(err);
500}
501
502Error HwcHal::getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
503 float* outMaxLuminance, float* outMaxAverageLuminance,
504 float* outMinLuminance)
505{
506 uint32_t count = 0;
507 int32_t err = mDispatch.getHdrCapabilities(mDevice, display, &count,
508 nullptr, outMaxLuminance, outMaxAverageLuminance,
509 outMinLuminance);
510 if (err != HWC2_ERROR_NONE) {
511 return static_cast<Error>(err);
512 }
513
514 outTypes->resize(count);
515 err = mDispatch.getHdrCapabilities(mDevice, display, &count,
516 reinterpret_cast<std::underlying_type<Hdr>::type*>(
517 outTypes->data()), outMaxLuminance,
518 outMaxAverageLuminance, outMinLuminance);
519 if (err != HWC2_ERROR_NONE) {
520 *outTypes = hidl_vec<Hdr>();
521 return static_cast<Error>(err);
522 }
523
524 return Error::NONE;
525}
526
527Error HwcHal::setActiveConfig(Display display, Config config)
528{
529 int32_t err = mDispatch.setActiveConfig(mDevice, display, config);
530 return static_cast<Error>(err);
531}
532
533Error HwcHal::setColorMode(Display display, ColorMode mode)
534{
535 int32_t err = mDispatch.setColorMode(mDevice, display,
536 static_cast<int32_t>(mode));
537 return static_cast<Error>(err);
538}
539
540Error HwcHal::setPowerMode(Display display, IComposerClient::PowerMode mode)
541{
542 int32_t err = mDispatch.setPowerMode(mDevice, display,
543 static_cast<int32_t>(mode));
544 return static_cast<Error>(err);
545}
546
547Error HwcHal::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
548{
549 int32_t err = mDispatch.setVsyncEnabled(mDevice, display,
550 static_cast<int32_t>(enabled));
551 return static_cast<Error>(err);
552}
553
554Error HwcHal::setColorTransform(Display display, const float* matrix,
555 int32_t hint)
556{
557 int32_t err = mDispatch.setColorTransform(mDevice, display, matrix, hint);
558 return static_cast<Error>(err);
559}
560
561Error HwcHal::setClientTarget(Display display, buffer_handle_t target,
562 int32_t acquireFence, int32_t dataspace,
563 const std::vector<hwc_rect_t>& damage)
564{
565 hwc_region region = { damage.size(), damage.data() };
566 int32_t err = mDispatch.setClientTarget(mDevice, display, target,
567 acquireFence, dataspace, region);
568 return static_cast<Error>(err);
569}
570
571Error HwcHal::setOutputBuffer(Display display, buffer_handle_t buffer,
572 int32_t releaseFence)
573{
574 int32_t err = mDispatch.setOutputBuffer(mDevice, display, buffer,
575 releaseFence);
576 // unlike in setClientTarget, releaseFence is owned by us
577 if (err == HWC2_ERROR_NONE && releaseFence >= 0) {
578 close(releaseFence);
579 }
580
581 return static_cast<Error>(err);
582}
583
584Error HwcHal::validateDisplay(Display display,
585 std::vector<Layer>* outChangedLayers,
586 std::vector<IComposerClient::Composition>* outCompositionTypes,
587 uint32_t* outDisplayRequestMask,
588 std::vector<Layer>* outRequestedLayers,
589 std::vector<uint32_t>* outRequestMasks)
590{
591 uint32_t types_count = 0;
592 uint32_t reqs_count = 0;
593 int32_t err = mDispatch.validateDisplay(mDevice, display,
594 &types_count, &reqs_count);
595 mMustValidateDisplay = false;
596
597 if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) {
598 return static_cast<Error>(err);
599 }
600
601 err = mDispatch.getChangedCompositionTypes(mDevice, display,
602 &types_count, nullptr, nullptr);
603 if (err != HWC2_ERROR_NONE) {
604 return static_cast<Error>(err);
605 }
606
607 outChangedLayers->resize(types_count);
608 outCompositionTypes->resize(types_count);
609 err = mDispatch.getChangedCompositionTypes(mDevice, display,
610 &types_count, outChangedLayers->data(),
611 reinterpret_cast<
612 std::underlying_type<IComposerClient::Composition>::type*>(
613 outCompositionTypes->data()));
614 if (err != HWC2_ERROR_NONE) {
615 outChangedLayers->clear();
616 outCompositionTypes->clear();
617 return static_cast<Error>(err);
618 }
619
620 int32_t display_reqs = 0;
621 err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
622 &reqs_count, nullptr, nullptr);
623 if (err != HWC2_ERROR_NONE) {
624 outChangedLayers->clear();
625 outCompositionTypes->clear();
626 return static_cast<Error>(err);
627 }
628
629 outRequestedLayers->resize(reqs_count);
630 outRequestMasks->resize(reqs_count);
631 err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
632 &reqs_count, outRequestedLayers->data(),
633 reinterpret_cast<int32_t*>(outRequestMasks->data()));
634 if (err != HWC2_ERROR_NONE) {
635 outChangedLayers->clear();
636 outCompositionTypes->clear();
637
638 outRequestedLayers->clear();
639 outRequestMasks->clear();
640 return static_cast<Error>(err);
641 }
642
643 *outDisplayRequestMask = display_reqs;
644
645 return static_cast<Error>(err);
646}
647
648Error HwcHal::acceptDisplayChanges(Display display)
649{
650 int32_t err = mDispatch.acceptDisplayChanges(mDevice, display);
651 return static_cast<Error>(err);
652}
653
654Error HwcHal::presentDisplay(Display display, int32_t* outPresentFence,
655 std::vector<Layer>* outLayers, std::vector<int32_t>* outReleaseFences)
656{
657 if (mMustValidateDisplay) {
658 return Error::NOT_VALIDATED;
659 }
660
661 *outPresentFence = -1;
662 int32_t err = mDispatch.presentDisplay(mDevice, display, outPresentFence);
663 if (err != HWC2_ERROR_NONE) {
664 return static_cast<Error>(err);
665 }
666
667 uint32_t count = 0;
668 err = mDispatch.getReleaseFences(mDevice, display, &count,
669 nullptr, nullptr);
670 if (err != HWC2_ERROR_NONE) {
671 ALOGW("failed to get release fences");
672 return Error::NONE;
673 }
674
675 outLayers->resize(count);
676 outReleaseFences->resize(count);
677 err = mDispatch.getReleaseFences(mDevice, display, &count,
678 outLayers->data(), outReleaseFences->data());
679 if (err != HWC2_ERROR_NONE) {
680 ALOGW("failed to get release fences");
681 outLayers->clear();
682 outReleaseFences->clear();
683 return Error::NONE;
684 }
685
686 return static_cast<Error>(err);
687}
688
689Error HwcHal::setLayerCursorPosition(Display display, Layer layer,
690 int32_t x, int32_t y)
691{
692 int32_t err = mDispatch.setCursorPosition(mDevice, display, layer, x, y);
693 return static_cast<Error>(err);
694}
695
696Error HwcHal::setLayerBuffer(Display display, Layer layer,
697 buffer_handle_t buffer, int32_t acquireFence)
698{
699 int32_t err = mDispatch.setLayerBuffer(mDevice, display, layer,
700 buffer, acquireFence);
701 return static_cast<Error>(err);
702}
703
704Error HwcHal::setLayerSurfaceDamage(Display display, Layer layer,
705 const std::vector<hwc_rect_t>& damage)
706{
707 hwc_region region = { damage.size(), damage.data() };
708 int32_t err = mDispatch.setLayerSurfaceDamage(mDevice, display, layer,
709 region);
710 return static_cast<Error>(err);
711}
712
713Error HwcHal::setLayerBlendMode(Display display, Layer layer, int32_t mode)
714{
715 int32_t err = mDispatch.setLayerBlendMode(mDevice, display, layer, mode);
716 return static_cast<Error>(err);
717}
718
719Error HwcHal::setLayerColor(Display display, Layer layer,
720 IComposerClient::Color color)
721{
722 hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
723 int32_t err = mDispatch.setLayerColor(mDevice, display, layer, hwc_color);
724 return static_cast<Error>(err);
725}
726
727Error HwcHal::setLayerCompositionType(Display display, Layer layer,
728 int32_t type)
729{
730 int32_t err = mDispatch.setLayerCompositionType(mDevice, display, layer,
731 type);
732 return static_cast<Error>(err);
733}
734
735Error HwcHal::setLayerDataspace(Display display, Layer layer,
736 int32_t dataspace)
737{
738 int32_t err = mDispatch.setLayerDataspace(mDevice, display, layer,
739 dataspace);
740 return static_cast<Error>(err);
741}
742
743Error HwcHal::setLayerDisplayFrame(Display display, Layer layer,
744 const hwc_rect_t& frame)
745{
746 int32_t err = mDispatch.setLayerDisplayFrame(mDevice, display, layer,
747 frame);
748 return static_cast<Error>(err);
749}
750
751Error HwcHal::setLayerPlaneAlpha(Display display, Layer layer, float alpha)
752{
753 int32_t err = mDispatch.setLayerPlaneAlpha(mDevice, display, layer,
754 alpha);
755 return static_cast<Error>(err);
756}
757
758Error HwcHal::setLayerSidebandStream(Display display, Layer layer,
759 buffer_handle_t stream)
760{
761 int32_t err = mDispatch.setLayerSidebandStream(mDevice, display, layer,
762 stream);
763 return static_cast<Error>(err);
764}
765
766Error HwcHal::setLayerSourceCrop(Display display, Layer layer,
767 const hwc_frect_t& crop)
768{
769 int32_t err = mDispatch.setLayerSourceCrop(mDevice, display, layer, crop);
770 return static_cast<Error>(err);
771}
772
773Error HwcHal::setLayerTransform(Display display, Layer layer,
774 int32_t transform)
775{
776 int32_t err = mDispatch.setLayerTransform(mDevice, display, layer,
777 transform);
778 return static_cast<Error>(err);
779}
780
781Error HwcHal::setLayerVisibleRegion(Display display, Layer layer,
782 const std::vector<hwc_rect_t>& visible)
783{
784 hwc_region_t region = { visible.size(), visible.data() };
785 int32_t err = mDispatch.setLayerVisibleRegion(mDevice, display, layer,
786 region);
787 return static_cast<Error>(err);
788}
789
790Error HwcHal::setLayerZOrder(Display display, Layer layer, uint32_t z)
791{
792 int32_t err = mDispatch.setLayerZOrder(mDevice, display, layer, z);
793 return static_cast<Error>(err);
794}
795
796IComposer* HIDL_FETCH_IComposer(const char*)
797{
798 const hw_module_t* module = nullptr;
799 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
800 if (err) {
801 ALOGI("falling back to FB HAL");
802 err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
803 }
804 if (err) {
805 ALOGE("failed to get hwcomposer or fb module");
806 return nullptr;
807 }
808
809 return new HwcHal(module);
810}
811
812} // namespace implementation
813} // namespace V2_1
814} // namespace composer
815} // namespace graphics
816} // namespace hardware
817} // namespace android
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
deleted file mode 100644
index e3f5ce68..00000000
--- a/graphics/composer/2.1/default/Hwc.h
+++ /dev/null
@@ -1,242 +0,0 @@
1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
18#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
19
20#include <atomic>
21#include <condition_variable>
22#include <memory>
23#include <mutex>
24#include <unordered_set>
25#include <vector>
26
27#include <android/hardware/graphics/composer/2.1/IComposer.h>
28#define HWC2_INCLUDE_STRINGIFICATION
29#define HWC2_USE_CPP11
30#include <hardware/hwcomposer2.h>
31#undef HWC2_INCLUDE_STRINGIFICATION
32#undef HWC2_USE_CPP11
33#include "ComposerBase.h"
34
35namespace android {
36 class HWC2On1Adapter;
37 class HWC2OnFbAdapter;
38}
39
40namespace android {
41namespace hardware {
42namespace graphics {
43namespace composer {
44namespace V2_1 {
45namespace implementation {
46
47using android::hardware::graphics::common::V1_0::PixelFormat;
48using android::hardware::graphics::common::V1_0::Transform;
49using android::hardware::graphics::common::V1_0::Dataspace;
50using android::hardware::graphics::common::V1_0::ColorMode;
51using android::hardware::graphics::common::V1_0::ColorTransform;
52using android::hardware::graphics::common::V1_0::Hdr;
53
54class ComposerClient;
55
56class HwcHal : public IComposer, public ComposerBase {
57public:
58 HwcHal(const hw_module_t* module);
59 virtual ~HwcHal();
60
61 // IComposer interface
62 Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
63 Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
64 Return<void> createClient(createClient_cb hidl_cb) override;
65
66 // ComposerBase interface
67 bool hasCapability(hwc2_capability_t capability) override;
68 void removeClient() override;
69 void enableCallback(bool enable) override;
70 uint32_t getMaxVirtualDisplayCount() override;
71 Error createVirtualDisplay(uint32_t width, uint32_t height,
72 PixelFormat* format, Display* outDisplay) override;
73 Error destroyVirtualDisplay(Display display) override;
74
75 Error createLayer(Display display, Layer* outLayer) override;
76 Error destroyLayer(Display display, Layer layer) override;
77
78 Error getActiveConfig(Display display, Config* outConfig) override;
79 Error getClientTargetSupport(Display display,
80 uint32_t width, uint32_t height,
81 PixelFormat format, Dataspace dataspace) override;
82 Error getColorModes(Display display,
83 hidl_vec<ColorMode>* outModes) override;
84 Error getDisplayAttribute(Display display, Config config,
85 IComposerClient::Attribute attribute, int32_t* outValue) override;
86 Error getDisplayConfigs(Display display,
87 hidl_vec<Config>* outConfigs) override;
88 Error getDisplayName(Display display, hidl_string* outName) override;
89 Error getDisplayType(Display display,
90 IComposerClient::DisplayType* outType) override;
91 Error getDozeSupport(Display display, bool* outSupport) override;
92 Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
93 float* outMaxLuminance, float* outMaxAverageLuminance,
94 float* outMinLuminance) override;
95
96 Error setActiveConfig(Display display, Config config) override;
97 Error setColorMode(Display display, ColorMode mode) override;
98 Error setPowerMode(Display display,
99 IComposerClient::PowerMode mode) override;
100 Error setVsyncEnabled(Display display,
101 IComposerClient::Vsync enabled) override;
102
103 Error setColorTransform(Display display, const float* matrix,
104 int32_t hint) override;
105 Error setClientTarget(Display display, buffer_handle_t target,
106 int32_t acquireFence, int32_t dataspace,
107 const std::vector<hwc_rect_t>& damage) override;
108 Error setOutputBuffer(Display display, buffer_handle_t buffer,
109 int32_t releaseFence) override;
110 Error validateDisplay(Display display,
111 std::vector<Layer>* outChangedLayers,
112 std::vector<IComposerClient::Composition>* outCompositionTypes,
113 uint32_t* outDisplayRequestMask,
114 std::vector<Layer>* outRequestedLayers,
115 std::vector<uint32_t>* outRequestMasks) override;
116 Error acceptDisplayChanges(Display display) override;
117 Error presentDisplay(Display display, int32_t* outPresentFence,
118 std::vector<Layer>* outLayers,
119 std::vector<int32_t>* outReleaseFences) override;
120
121 Error setLayerCursorPosition(Display display, Layer layer,
122 int32_t x, int32_t y) override;
123 Error setLayerBuffer(Display display, Layer layer,
124 buffer_handle_t buffer, int32_t acquireFence) override;
125 Error setLayerSurfaceDamage(Display display, Layer layer,
126 const std::vector<hwc_rect_t>& damage) override;
127 Error setLayerBlendMode(Display display, Layer layer,
128 int32_t mode) override;
129 Error setLayerColor(Display display, Layer layer,
130 IComposerClient::Color color) override;
131 Error setLayerCompositionType(Display display, Layer layer,
132 int32_t type) override;
133 Error setLayerDataspace(Display display, Layer layer,
134 int32_t dataspace) override;
135 Error setLayerDisplayFrame(Display display, Layer layer,
136 const hwc_rect_t& frame) override;
137 Error setLayerPlaneAlpha(Display display, Layer layer,
138 float alpha) override;
139 Error setLayerSidebandStream(Display display, Layer layer,
140 buffer_handle_t stream) override;
141 Error setLayerSourceCrop(Display display, Layer layer,
142 const hwc_frect_t& crop) override;
143 Error setLayerTransform(Display display, Layer layer,
144 int32_t transform) override;
145 Error setLayerVisibleRegion(Display display, Layer layer,
146 const std::vector<hwc_rect_t>& visible) override;
147 Error setLayerZOrder(Display display, Layer layer, uint32_t z) override;
148
149private:
150 uint32_t initWithHwc(const hw_module_t* module);
151 uint32_t initWithFb(const hw_module_t* module);
152
153 void initCapabilities();
154
155 template<typename T>
156 void initDispatch(hwc2_function_descriptor_t desc, T* outPfn);
157 void initDispatch();
158
159 sp<ComposerClient> getClient();
160
161 static void hotplugHook(hwc2_callback_data_t callbackData,
162 hwc2_display_t display, int32_t connected);
163 static void refreshHook(hwc2_callback_data_t callbackData,
164 hwc2_display_t display);
165 static void vsyncHook(hwc2_callback_data_t callbackData,
166 hwc2_display_t display, int64_t timestamp);
167
168 hwc2_device_t* mDevice;
169
170 std::unordered_set<hwc2_capability_t> mCapabilities;
171
172 struct {
173 HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;
174 HWC2_PFN_CREATE_LAYER createLayer;
175 HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay;
176 HWC2_PFN_DESTROY_LAYER destroyLayer;
177 HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay;
178 HWC2_PFN_DUMP dump;
179 HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig;
180 HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes;
181 HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport;
182 HWC2_PFN_GET_COLOR_MODES getColorModes;
183 HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute;
184 HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs;
185 HWC2_PFN_GET_DISPLAY_NAME getDisplayName;
186 HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests;
187 HWC2_PFN_GET_DISPLAY_TYPE getDisplayType;
188 HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport;
189 HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities;
190 HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount;
191 HWC2_PFN_GET_RELEASE_FENCES getReleaseFences;
192 HWC2_PFN_PRESENT_DISPLAY presentDisplay;
193 HWC2_PFN_REGISTER_CALLBACK registerCallback;
194 HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig;
195 HWC2_PFN_SET_CLIENT_TARGET setClientTarget;
196 HWC2_PFN_SET_COLOR_MODE setColorMode;
197 HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform;
198 HWC2_PFN_SET_CURSOR_POSITION setCursorPosition;
199 HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode;
200 HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer;
201 HWC2_PFN_SET_LAYER_COLOR setLayerColor;
202 HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType;
203 HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace;
204 HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame;
205 HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha;
206 HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream;
207 HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop;
208 HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage;
209 HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform;
210 HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion;
211 HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder;
212 HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer;
213 HWC2_PFN_SET_POWER_MODE setPowerMode;
214 HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled;
215 HWC2_PFN_VALIDATE_DISPLAY validateDisplay;
216 } mDispatch;
217
218 std::mutex mClientMutex;
219 std::condition_variable mClientDestroyedWait;
220 wp<ComposerClient> mClient;
221
222 std::atomic<bool> mMustValidateDisplay;
223
224 // If the HWC implementation version is < 2.0, use an adapter to interface
225 // between HWC 2.0 <-> HWC 1.X.
226 std::unique_ptr<HWC2On1Adapter> mAdapter;
227
228 // If there is no HWC implementation, use an adapter to interface between
229 // HWC 2.0 <-> FB HAL.
230 std::unique_ptr<HWC2OnFbAdapter> mFbAdapter;
231};
232
233extern "C" IComposer* HIDL_FETCH_IComposer(const char* name);
234
235} // namespace implementation
236} // namespace V2_1
237} // namespace composer
238} // namespace graphics
239} // namespace hardware
240} // namespace android
241
242#endif // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
diff --git a/graphics/composer/2.1/default/passthrough.cpp b/graphics/composer/2.1/default/passthrough.cpp
new file mode 100644
index 00000000..ef7ed7c8
--- /dev/null
+++ b/graphics/composer/2.1/default/passthrough.cpp
@@ -0,0 +1,25 @@
1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <android/hardware/graphics/composer/2.1/IComposer.h>
18#include <composer-passthrough/2.1/HwcLoader.h>
19
20using android::hardware::graphics::composer::V2_1::IComposer;
21using android::hardware::graphics::composer::V2_1::passthrough::HwcLoader;
22
23extern "C" IComposer* HIDL_FETCH_IComposer(const char* /* name */) {
24 return HwcLoader::load();
25}
diff --git a/graphics/composer/2.1/utils/command-buffer/Android.bp b/graphics/composer/2.1/utils/command-buffer/Android.bp
index e8d41c2b..140d9bb6 100644
--- a/graphics/composer/2.1/utils/command-buffer/Android.bp
+++ b/graphics/composer/2.1/utils/command-buffer/Android.bp
@@ -2,6 +2,15 @@ cc_library_headers {
2 name: "android.hardware.graphics.composer@2.1-command-buffer", 2 name: "android.hardware.graphics.composer@2.1-command-buffer",
3 defaults: ["hidl_defaults"], 3 defaults: ["hidl_defaults"],
4 vendor_available: true, 4 vendor_available: true,
5 shared_libs: ["android.hardware.graphics.composer@2.1"], 5 shared_libs: [
6 "android.hardware.graphics.composer@2.1",
7 "libfmq",
8 "libsync",
9 ],
10 export_shared_lib_headers: [
11 "android.hardware.graphics.composer@2.1",
12 "libfmq",
13 "libsync",
14 ],
6 export_include_dirs: ["include"], 15 export_include_dirs: ["include"],
7} 16}
diff --git a/graphics/composer/2.1/utils/hal/Android.bp b/graphics/composer/2.1/utils/hal/Android.bp
new file mode 100644
index 00000000..f24e7682
--- /dev/null
+++ b/graphics/composer/2.1/utils/hal/Android.bp
@@ -0,0 +1,37 @@
1//
2// Copyright (C) 2018 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16cc_library_headers {
17 name: "android.hardware.graphics.composer@2.1-hal",
18 defaults: ["hidl_defaults"],
19 vendor_available: true,
20 shared_libs: [
21 "android.hardware.graphics.composer@2.1",
22 "android.hardware.graphics.mapper@2.0",
23 "libhardware", // TODO remove hwcomposer2.h dependency
24 ],
25 export_shared_lib_headers: [
26 "android.hardware.graphics.composer@2.1",
27 "android.hardware.graphics.mapper@2.0",
28 "libhardware",
29 ],
30 header_libs: [
31 "android.hardware.graphics.composer@2.1-command-buffer",
32 ],
33 export_header_lib_headers: [
34 "android.hardware.graphics.composer@2.1-command-buffer",
35 ],
36 export_include_dirs: ["include"],
37}
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/Composer.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/Composer.h
new file mode 100644
index 00000000..581dc962
--- /dev/null
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/Composer.h
@@ -0,0 +1,157 @@
1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "Composer.h included without LOG_TAG"
21#endif
22
23#include <array>
24#include <chrono>
25#include <condition_variable>
26#include <memory>
27#include <mutex>
28#include <vector>
29
30#include <android/hardware/graphics/composer/2.1/IComposer.h>
31#include <android/hardware/graphics/composer/2.1/IComposerClient.h>
32#include <composer-hal/2.1/ComposerClient.h>
33#include <composer-hal/2.1/ComposerHal.h>
34
35namespace android {
36namespace hardware {
37namespace graphics {
38namespace composer {
39namespace V2_1 {
40namespace hal {
41
42namespace detail {
43
44// ComposerImpl implements V2_*::IComposer on top of V2_*::ComposerHal
45template <typename Interface, typename Hal>
46class ComposerImpl : public Interface {
47 public:
48 static std::unique_ptr<ComposerImpl> create(std::unique_ptr<Hal> hal) {
49 return std::make_unique<ComposerImpl>(std::move(hal));
50 }
51
52 ComposerImpl(std::unique_ptr<Hal> hal) : mHal(std::move(hal)) {}
53
54 // IComposer 2.1 interface
55
56 Return<void> getCapabilities(IComposer::getCapabilities_cb hidl_cb) override {
57 const std::array<IComposer::Capability, 3> all_caps = {{
58 IComposer::Capability::SIDEBAND_STREAM,
59 IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM,
60 IComposer::Capability::PRESENT_FENCE_IS_NOT_RELIABLE,
61 }};
62
63 std::vector<IComposer::Capability> caps;
64 for (auto cap : all_caps) {
65 if (mHal->hasCapability(static_cast<hwc2_capability_t>(cap))) {
66 caps.push_back(cap);
67 }
68 }
69
70 hidl_vec<IComposer::Capability> caps_reply;
71 caps_reply.setToExternal(caps.data(), caps.size());
72 hidl_cb(caps_reply);
73 return Void();
74 }
75
76 Return<void> dumpDebugInfo(IComposer::dumpDebugInfo_cb hidl_cb) override {
77 hidl_cb(mHal->dumpDebugInfo());
78 return Void();
79 }
80
81 Return<void> createClient(IComposer::createClient_cb hidl_cb) override {
82 std::unique_lock<std::mutex> lock(mClientMutex);
83 if (!waitForClientDestroyedLocked(lock)) {
84 hidl_cb(Error::NO_RESOURCES, nullptr);
85 return Void();
86 }
87
88 sp<IComposerClient> client = createClient();
89 if (!client) {
90 hidl_cb(Error::NO_RESOURCES, nullptr);
91 return Void();
92 }
93
94 mClient = client;
95 hidl_cb(Error::NONE, client);
96 return Void();
97 }
98
99 protected:
100 bool waitForClientDestroyedLocked(std::unique_lock<std::mutex>& lock) {
101 if (mClient != nullptr) {
102 using namespace std::chrono_literals;
103
104 // In surface flinger we delete a composer client on one thread and
105 // then create a new client on another thread. Although surface
106 // flinger ensures the calls are made in that sequence (destroy and
107 // then create), sometimes the calls land in the composer service
108 // inverted (create and then destroy). Wait for a brief period to
109 // see if the existing client is destroyed.
110 ALOGD("waiting for previous client to be destroyed");
111 mClientDestroyedCondition.wait_for(
112 lock, 1s, [this]() -> bool { return mClient.promote() == nullptr; });
113 if (mClient.promote() != nullptr) {
114 ALOGD("previous client was not destroyed");
115 } else {
116 mClient.clear();
117 }
118 }
119
120 return mClient == nullptr;
121 }
122
123 void onClientDestroyed() {
124 std::lock_guard<std::mutex> lock(mClientMutex);
125 mClient.clear();
126 mClientDestroyedCondition.notify_all();
127 }
128
129 virtual IComposerClient* createClient() {
130 auto client = ComposerClient::create(mHal.get());
131 if (!client) {
132 return nullptr;
133 }
134
135 auto clientDestroyed = [this]() { onClientDestroyed(); };
136 client->setOnClientDestroyed(clientDestroyed);
137
138 return client.release();
139 }
140
141 const std::unique_ptr<Hal> mHal;
142
143 std::mutex mClientMutex;
144 wp<IComposerClient> mClient;
145 std::condition_variable mClientDestroyedCondition;
146};
147
148} // namespace detail
149
150using Composer = detail::ComposerImpl<IComposer, ComposerHal>;
151
152} // namespace hal
153} // namespace V2_1
154} // namespace composer
155} // namespace graphics
156} // namespace hardware
157} // namespace android
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
new file mode 100644
index 00000000..86525b87
--- /dev/null
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
@@ -0,0 +1,396 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "ComposerClient.h included without LOG_TAG"
21#endif
22
23#include <memory>
24#include <mutex>
25#include <vector>
26
27#include <android/hardware/graphics/composer/2.1/IComposerClient.h>
28#include <composer-hal/2.1/ComposerCommandEngine.h>
29#include <composer-hal/2.1/ComposerHal.h>
30#include <composer-hal/2.1/ComposerResources.h>
31#include <log/log.h>
32
33namespace android {
34namespace hardware {
35namespace graphics {
36namespace composer {
37namespace V2_1 {
38namespace hal {
39
40namespace detail {
41
42// ComposerClientImpl implements V2_*::IComposerClient on top of V2_*::ComposerHal
43template <typename Interface, typename Hal>
44class ComposerClientImpl : public Interface {
45 public:
46 static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {
47 auto client = std::make_unique<ComposerClientImpl>(hal);
48 return client->init() ? std::move(client) : nullptr;
49 }
50
51 ComposerClientImpl(Hal* hal) : mHal(hal) {}
52
53 virtual ~ComposerClientImpl() {
54 // not initialized
55 if (!mCommandEngine) {
56 return;
57 }
58
59 ALOGD("destroying composer client");
60
61 mHal->unregisterEventCallback();
62 destroyResources();
63 if (mOnClientDestroyed) {
64 mOnClientDestroyed();
65 }
66
67 ALOGD("removed composer client");
68 }
69
70 bool init() {
71 mResources = createResources();
72 if (!mResources) {
73 ALOGE("failed to create composer resources");
74 return false;
75 }
76
77 mCommandEngine = createCommandEngine();
78
79 return true;
80 }
81
82 void setOnClientDestroyed(std::function<void()> onClientDestroyed) {
83 mOnClientDestroyed = onClientDestroyed;
84 }
85
86 // IComposerClient 2.1 interface
87
88 class HalEventCallback : public Hal::EventCallback {
89 public:
90 HalEventCallback(const sp<IComposerCallback> callback, ComposerResources* resources)
91 : mCallback(callback), mResources(resources) {}
92
93 void onHotplug(Display display, IComposerCallback::Connection connected) {
94 if (connected == IComposerCallback::Connection::CONNECTED) {
95 mResources->addPhysicalDisplay(display);
96 } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
97 mResources->removeDisplay(display);
98 }
99
100 auto ret = mCallback->onHotplug(display, connected);
101 ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s", ret.description().c_str());
102 }
103
104 void onRefresh(Display display) {
105 auto ret = mCallback->onRefresh(display);
106 ALOGE_IF(!ret.isOk(), "failed to send onRefresh: %s", ret.description().c_str());
107 }
108
109 void onVsync(Display display, int64_t timestamp) {
110 auto ret = mCallback->onVsync(display, timestamp);
111 ALOGE_IF(!ret.isOk(), "failed to send onVsync: %s", ret.description().c_str());
112 }
113
114 protected:
115 const sp<IComposerCallback> mCallback;
116 ComposerResources* const mResources;
117 };
118
119 Return<void> registerCallback(const sp<IComposerCallback>& callback) override {
120 // no locking as we require this function to be called only once
121 mHalEventCallback = std::make_unique<HalEventCallback>(callback, mResources.get());
122 mHal->registerEventCallback(mHalEventCallback.get());
123 return Void();
124 }
125
126 Return<uint32_t> getMaxVirtualDisplayCount() override {
127 return mHal->getMaxVirtualDisplayCount();
128 }
129
130 Return<void> createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat formatHint,
131 uint32_t outputBufferSlotCount,
132 IComposerClient::createVirtualDisplay_cb hidl_cb) override {
133 Display display = 0;
134 Error err = mHal->createVirtualDisplay(width, height, &formatHint, &display);
135 if (err == Error::NONE) {
136 mResources->addVirtualDisplay(display, outputBufferSlotCount);
137 }
138
139 hidl_cb(err, display, formatHint);
140 return Void();
141 }
142
143 Return<Error> destroyVirtualDisplay(Display display) override {
144 Error err = mHal->destroyVirtualDisplay(display);
145 if (err == Error::NONE) {
146 mResources->removeDisplay(display);
147 }
148
149 return err;
150 }
151
152 Return<void> createLayer(Display display, uint32_t bufferSlotCount,
153 IComposerClient::createLayer_cb hidl_cb) override {
154 Layer layer = 0;
155 Error err = mHal->createLayer(display, &layer);
156 if (err == Error::NONE) {
157 err = mResources->addLayer(display, layer, bufferSlotCount);
158 if (err != Error::NONE) {
159 // The display entry may have already been removed by onHotplug.
160 // Note: We do not destroy the layer on this error as the hotplug
161 // disconnect invalidates the display id. The implementation should
162 // ensure all layers for the display are destroyed.
163 layer = 0;
164 }
165 }
166
167 hidl_cb(err, layer);
168 return Void();
169 }
170
171 Return<Error> destroyLayer(Display display, Layer layer) override {
172 Error err = mHal->destroyLayer(display, layer);
173 if (err == Error::NONE) {
174 mResources->removeLayer(display, layer);
175 }
176
177 return err;
178 }
179
180 Return<void> getActiveConfig(Display display,
181 IComposerClient::getActiveConfig_cb hidl_cb) override {
182 Config config = 0;
183 Error err = mHal->getActiveConfig(display, &config);
184 hidl_cb(err, config);
185 return Void();
186 }
187
188 Return<Error> getClientTargetSupport(Display display, uint32_t width, uint32_t height,
189 PixelFormat format, Dataspace dataspace) override {
190 Error err = mHal->getClientTargetSupport(display, width, height, format, dataspace);
191 return err;
192 }
193
194 Return<void> getColorModes(Display display,
195 IComposerClient::getColorModes_cb hidl_cb) override {
196 hidl_vec<ColorMode> modes;
197 Error err = mHal->getColorModes(display, &modes);
198 hidl_cb(err, modes);
199 return Void();
200 }
201
202 Return<void> getDisplayAttribute(Display display, Config config,
203 IComposerClient::Attribute attribute,
204 IComposerClient::getDisplayAttribute_cb hidl_cb) override {
205 int32_t value = 0;
206 Error err = mHal->getDisplayAttribute(display, config, attribute, &value);
207 hidl_cb(err, value);
208 return Void();
209 }
210
211 Return<void> getDisplayConfigs(Display display,
212 IComposerClient::getDisplayConfigs_cb hidl_cb) override {
213 hidl_vec<Config> configs;
214 Error err = mHal->getDisplayConfigs(display, &configs);
215 hidl_cb(err, configs);
216 return Void();
217 }
218
219 Return<void> getDisplayName(Display display,
220 IComposerClient::getDisplayName_cb hidl_cb) override {
221 hidl_string name;
222 Error err = mHal->getDisplayName(display, &name);
223 hidl_cb(err, name);
224 return Void();
225 }
226
227 Return<void> getDisplayType(Display display,
228 IComposerClient::getDisplayType_cb hidl_cb) override {
229 IComposerClient::DisplayType type = IComposerClient::DisplayType::INVALID;
230 Error err = mHal->getDisplayType(display, &type);
231 hidl_cb(err, type);
232 return Void();
233 }
234
235 Return<void> getDozeSupport(Display display,
236 IComposerClient::getDozeSupport_cb hidl_cb) override {
237 bool support = false;
238 Error err = mHal->getDozeSupport(display, &support);
239 hidl_cb(err, support);
240 return Void();
241 }
242
243 Return<void> getHdrCapabilities(Display display,
244 IComposerClient::getHdrCapabilities_cb hidl_cb) override {
245 hidl_vec<Hdr> types;
246 float max_lumi = 0.0f;
247 float max_avg_lumi = 0.0f;
248 float min_lumi = 0.0f;
249 Error err = mHal->getHdrCapabilities(display, &types, &max_lumi, &max_avg_lumi, &min_lumi);
250 hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
251 return Void();
252 }
253
254 Return<Error> setActiveConfig(Display display, Config config) override {
255 Error err = mHal->setActiveConfig(display, config);
256 return err;
257 }
258
259 Return<Error> setColorMode(Display display, ColorMode mode) override {
260 Error err = mHal->setColorMode(display, mode);
261 return err;
262 }
263
264 Return<Error> setPowerMode(Display display, IComposerClient::PowerMode mode) override {
265 Error err = mHal->setPowerMode(display, mode);
266 return err;
267 }
268
269 Return<Error> setVsyncEnabled(Display display, IComposerClient::Vsync enabled) override {
270 Error err = mHal->setVsyncEnabled(display, enabled);
271 return err;
272 }
273
274 Return<Error> setClientTargetSlotCount(Display display,
275 uint32_t clientTargetSlotCount) override {
276 return mResources->setDisplayClientTargetCacheSize(display, clientTargetSlotCount);
277 }
278
279 Return<Error> setInputCommandQueue(const MQDescriptorSync<uint32_t>& descriptor) override {
280 std::lock_guard<std::mutex> lock(mCommandEngineMutex);
281 return mCommandEngine->setInputMQDescriptor(descriptor) ? Error::NONE : Error::NO_RESOURCES;
282 }
283
284 Return<void> getOutputCommandQueue(IComposerClient::getOutputCommandQueue_cb hidl_cb) override {
285 // no locking as we require this function to be called inside
286 // executeCommands_cb
287 auto outDescriptor = mCommandEngine->getOutputMQDescriptor();
288 if (outDescriptor) {
289 hidl_cb(Error::NONE, *outDescriptor);
290 } else {
291 hidl_cb(Error::NO_RESOURCES, CommandQueueType::Descriptor());
292 }
293
294 return Void();
295 }
296
297 Return<void> executeCommands(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles,
298 IComposerClient::executeCommands_cb hidl_cb) override {
299 std::lock_guard<std::mutex> lock(mCommandEngineMutex);
300 bool outChanged = false;
301 uint32_t outLength = 0;
302 hidl_vec<hidl_handle> outHandles;
303 Error error =
304 mCommandEngine->execute(inLength, inHandles, &outChanged, &outLength, &outHandles);
305
306 hidl_cb(error, outChanged, outLength, outHandles);
307
308 mCommandEngine->reset();
309
310 return Void();
311 }
312
313 protected:
314 virtual std::unique_ptr<ComposerResources> createResources() {
315 return ComposerResources::create();
316 }
317
318 virtual std::unique_ptr<ComposerCommandEngine> createCommandEngine() {
319 return std::make_unique<ComposerCommandEngine>(mHal, mResources.get());
320 }
321
322 void destroyResources() {
323 // We want to call hwc2_close here (and move hwc2_open to the
324 // constructor), with the assumption that hwc2_close would
325 //
326 // - clean up all resources owned by the client
327 // - make sure all displays are blank (since there is no layer)
328 //
329 // But since SF used to crash at this point, different hwcomposer2
330 // implementations behave differently on hwc2_close. Our only portable
331 // choice really is to abort(). But that is not an option anymore
332 // because we might also have VTS or VR as clients that can come and go.
333 //
334 // Below we manually clean all resources (layers and virtual
335 // displays), and perform a presentDisplay afterwards.
336 mResources->clear([this](Display display, bool isVirtual, const std::vector<Layer> layers) {
337 ALOGW("destroying client resources for display %" PRIu64, display);
338
339 for (auto layer : layers) {
340 mHal->destroyLayer(display, layer);
341 }
342
343 if (isVirtual) {
344 mHal->destroyVirtualDisplay(display);
345 } else {
346 ALOGW("performing a final presentDisplay");
347
348 std::vector<Layer> changedLayers;
349 std::vector<IComposerClient::Composition> compositionTypes;
350 uint32_t displayRequestMask = 0;
351 std::vector<Layer> requestedLayers;
352 std::vector<uint32_t> requestMasks;
353 mHal->validateDisplay(display, &changedLayers, &compositionTypes,
354 &displayRequestMask, &requestedLayers, &requestMasks);
355
356 mHal->acceptDisplayChanges(display);
357
358 int32_t presentFence = -1;
359 std::vector<Layer> releasedLayers;
360 std::vector<int32_t> releaseFences;
361 mHal->presentDisplay(display, &presentFence, &releasedLayers, &releaseFences);
362 if (presentFence >= 0) {
363 close(presentFence);
364 }
365 for (auto fence : releaseFences) {
366 if (fence >= 0) {
367 close(fence);
368 }
369 }
370 }
371 });
372
373 mResources.reset();
374 }
375
376 Hal* const mHal;
377
378 std::unique_ptr<ComposerResources> mResources;
379
380 std::mutex mCommandEngineMutex;
381 std::unique_ptr<ComposerCommandEngine> mCommandEngine;
382
383 std::function<void()> mOnClientDestroyed;
384 std::unique_ptr<HalEventCallback> mHalEventCallback;
385};
386
387} // namespace detail
388
389using ComposerClient = detail::ComposerClientImpl<IComposerClient, ComposerHal>;
390
391} // namespace hal
392} // namespace V2_1
393} // namespace composer
394} // namespace graphics
395} // namespace hardware
396} // namespace android
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
new file mode 100644
index 00000000..36aa64ef
--- /dev/null
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
@@ -0,0 +1,594 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "ComposerCommandEngine.h included without LOG_TAG"
21#endif
22
23#include <vector>
24
25#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
26#include <composer-hal/2.1/ComposerHal.h>
27#include <composer-hal/2.1/ComposerResources.h>
28// TODO remove hwcomposer_defs.h dependency
29#include <hardware/hwcomposer_defs.h>
30#include <log/log.h>
31
32namespace android {
33namespace hardware {
34namespace graphics {
35namespace composer {
36namespace V2_1 {
37namespace hal {
38
39// TODO own a CommandReaderBase rather than subclassing
40class ComposerCommandEngine : protected CommandReaderBase {
41 public:
42 ComposerCommandEngine(ComposerHal* hal, ComposerResources* resources)
43 : mHal(hal), mResources(resources) {}
44
45 virtual ~ComposerCommandEngine() = default;
46
47 bool setInputMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor) {
48 return setMQDescriptor(descriptor);
49 }
50
51 Error execute(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles, bool* outQueueChanged,
52 uint32_t* outCommandLength, hidl_vec<hidl_handle>* outCommandHandles) {
53 if (!readQueue(inLength, inHandles)) {
54 return Error::BAD_PARAMETER;
55 }
56
57 IComposerClient::Command command;
58 uint16_t length = 0;
59 while (!isEmpty()) {
60 if (!beginCommand(&command, &length)) {
61 break;
62 }
63
64 bool parsed = executeCommand(command, length);
65 endCommand();
66
67 if (!parsed) {
68 ALOGE("failed to parse command 0x%x, length %" PRIu16, command, length);
69 break;
70 }
71 }
72
73 if (!isEmpty()) {
74 return Error::BAD_PARAMETER;
75 }
76
77 return mWriter.writeQueue(outQueueChanged, outCommandLength, outCommandHandles)
78 ? Error::NONE
79 : Error::NO_RESOURCES;
80 }
81
82 const MQDescriptorSync<uint32_t>* getOutputMQDescriptor() { return mWriter.getMQDescriptor(); }
83
84 void reset() {
85 CommandReaderBase::reset();
86 mWriter.reset();
87 }
88
89 protected:
90 virtual bool executeCommand(IComposerClient::Command command, uint16_t length) {
91 switch (command) {
92 case IComposerClient::Command::SELECT_DISPLAY:
93 return executeSelectDisplay(length);
94 case IComposerClient::Command::SELECT_LAYER:
95 return executeSelectLayer(length);
96 case IComposerClient::Command::SET_COLOR_TRANSFORM:
97 return executeSetColorTransform(length);
98 case IComposerClient::Command::SET_CLIENT_TARGET:
99 return executeSetClientTarget(length);
100 case IComposerClient::Command::SET_OUTPUT_BUFFER:
101 return executeSetOutputBuffer(length);
102 case IComposerClient::Command::VALIDATE_DISPLAY:
103 return executeValidateDisplay(length);
104 case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
105 return executePresentOrValidateDisplay(length);
106 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
107 return executeAcceptDisplayChanges(length);
108 case IComposerClient::Command::PRESENT_DISPLAY:
109 return executePresentDisplay(length);
110 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
111 return executeSetLayerCursorPosition(length);
112 case IComposerClient::Command::SET_LAYER_BUFFER:
113 return executeSetLayerBuffer(length);
114 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
115 return executeSetLayerSurfaceDamage(length);
116 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
117 return executeSetLayerBlendMode(length);
118 case IComposerClient::Command::SET_LAYER_COLOR:
119 return executeSetLayerColor(length);
120 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
121 return executeSetLayerCompositionType(length);
122 case IComposerClient::Command::SET_LAYER_DATASPACE:
123 return executeSetLayerDataspace(length);
124 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
125 return executeSetLayerDisplayFrame(length);
126 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
127 return executeSetLayerPlaneAlpha(length);
128 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
129 return executeSetLayerSidebandStream(length);
130 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
131 return executeSetLayerSourceCrop(length);
132 case IComposerClient::Command::SET_LAYER_TRANSFORM:
133 return executeSetLayerTransform(length);
134 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
135 return executeSetLayerVisibleRegion(length);
136 case IComposerClient::Command::SET_LAYER_Z_ORDER:
137 return executeSetLayerZOrder(length);
138 default:
139 return false;
140 }
141 }
142
143 bool executeSelectDisplay(uint16_t length) {
144 if (length != CommandWriterBase::kSelectDisplayLength) {
145 return false;
146 }
147
148 mCurrentDisplay = read64();
149 mWriter.selectDisplay(mCurrentDisplay);
150
151 return true;
152 }
153
154 bool executeSelectLayer(uint16_t length) {
155 if (length != CommandWriterBase::kSelectLayerLength) {
156 return false;
157 }
158
159 mCurrentLayer = read64();
160
161 return true;
162 }
163
164 bool executeSetColorTransform(uint16_t length) {
165 if (length != CommandWriterBase::kSetColorTransformLength) {
166 return false;
167 }
168
169 float matrix[16];
170 for (int i = 0; i < 16; i++) {
171 matrix[i] = readFloat();
172 }
173 auto transform = readSigned();
174
175 auto err = mHal->setColorTransform(mCurrentDisplay, matrix, transform);
176 if (err != Error::NONE) {
177 mWriter.setError(getCommandLoc(), err);
178 }
179
180 return true;
181 }
182
183 bool executeSetClientTarget(uint16_t length) {
184 // 4 parameters followed by N rectangles
185 if ((length - 4) % 4 != 0) {
186 return false;
187 }
188
189 bool useCache = false;
190 auto slot = read();
191 auto rawHandle = readHandle(&useCache);
192 auto fence = readFence();
193 auto dataspace = readSigned();
194 auto damage = readRegion((length - 4) / 4);
195 bool closeFence = true;
196
197 const native_handle_t* clientTarget;
198 ComposerResources::ReplacedBufferHandle replacedClientTarget;
199 auto err = mResources->getDisplayClientTarget(mCurrentDisplay, slot, useCache, rawHandle,
200 &clientTarget, &replacedClientTarget);
201 if (err == Error::NONE) {
202 err = mHal->setClientTarget(mCurrentDisplay, clientTarget, fence, dataspace, damage);
203 if (err == Error::NONE) {
204 closeFence = false;
205 }
206 }
207 if (closeFence) {
208 close(fence);
209 }
210 if (err != Error::NONE) {
211 mWriter.setError(getCommandLoc(), err);
212 }
213
214 return true;
215 }
216
217 bool executeSetOutputBuffer(uint16_t length) {
218 if (length != CommandWriterBase::kSetOutputBufferLength) {
219 return false;
220 }
221
222 bool useCache = false;
223 auto slot = read();
224 auto rawhandle = readHandle(&useCache);
225 auto fence = readFence();
226 bool closeFence = true;
227
228 const native_handle_t* outputBuffer;
229 ComposerResources::ReplacedBufferHandle replacedOutputBuffer;
230 auto err = mResources->getDisplayOutputBuffer(mCurrentDisplay, slot, useCache, rawhandle,
231 &outputBuffer, &replacedOutputBuffer);
232 if (err == Error::NONE) {
233 err = mHal->setOutputBuffer(mCurrentDisplay, outputBuffer, fence);
234 if (err == Error::NONE) {
235 closeFence = false;
236 }
237 }
238 if (closeFence) {
239 close(fence);
240 }
241 if (err != Error::NONE) {
242 mWriter.setError(getCommandLoc(), err);
243 }
244
245 return true;
246 }
247
248 bool executeValidateDisplay(uint16_t length) {
249 if (length != CommandWriterBase::kValidateDisplayLength) {
250 return false;
251 }
252
253 std::vector<Layer> changedLayers;
254 std::vector<IComposerClient::Composition> compositionTypes;
255 uint32_t displayRequestMask = 0x0;
256 std::vector<Layer> requestedLayers;
257 std::vector<uint32_t> requestMasks;
258
259 auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
260 &displayRequestMask, &requestedLayers, &requestMasks);
261 if (err == Error::NONE) {
262 mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
263 mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
264 } else {
265 mWriter.setError(getCommandLoc(), err);
266 }
267
268 return true;
269 }
270
271 bool executePresentOrValidateDisplay(uint16_t length) {
272 if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
273 return false;
274 }
275
276 // First try to Present as is.
277 if (mHal->hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
278 int presentFence = -1;
279 std::vector<Layer> layers;
280 std::vector<int> fences;
281 auto err = mHal->presentDisplay(mCurrentDisplay, &presentFence, &layers, &fences);
282 if (err == Error::NONE) {
283 mWriter.setPresentOrValidateResult(1);
284 mWriter.setPresentFence(presentFence);
285 mWriter.setReleaseFences(layers, fences);
286 return true;
287 }
288 }
289
290 // Present has failed. We need to fallback to validate
291 std::vector<Layer> changedLayers;
292 std::vector<IComposerClient::Composition> compositionTypes;
293 uint32_t displayRequestMask = 0x0;
294 std::vector<Layer> requestedLayers;
295 std::vector<uint32_t> requestMasks;
296
297 auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
298 &displayRequestMask, &requestedLayers, &requestMasks);
299 if (err == Error::NONE) {
300 mWriter.setPresentOrValidateResult(0);
301 mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
302 mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
303 } else {
304 mWriter.setError(getCommandLoc(), err);
305 }
306
307 return true;
308 }
309
310 bool executeAcceptDisplayChanges(uint16_t length) {
311 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
312 return false;
313 }
314
315 auto err = mHal->acceptDisplayChanges(mCurrentDisplay);
316 if (err != Error::NONE) {
317 mWriter.setError(getCommandLoc(), err);
318 }
319
320 return true;
321 }
322
323 bool executePresentDisplay(uint16_t length) {
324 if (length != CommandWriterBase::kPresentDisplayLength) {
325 return false;
326 }
327
328 int presentFence = -1;
329 std::vector<Layer> layers;
330 std::vector<int> fences;
331 auto err = mHal->presentDisplay(mCurrentDisplay, &presentFence, &layers, &fences);
332 if (err == Error::NONE) {
333 mWriter.setPresentFence(presentFence);
334 mWriter.setReleaseFences(layers, fences);
335 } else {
336 mWriter.setError(getCommandLoc(), err);
337 }
338
339 return true;
340 }
341
342 bool executeSetLayerCursorPosition(uint16_t length) {
343 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
344 return false;
345 }
346
347 auto err = mHal->setLayerCursorPosition(mCurrentDisplay, mCurrentLayer, readSigned(),
348 readSigned());
349 if (err != Error::NONE) {
350 mWriter.setError(getCommandLoc(), err);
351 }
352
353 return true;
354 }
355
356 bool executeSetLayerBuffer(uint16_t length) {
357 if (length != CommandWriterBase::kSetLayerBufferLength) {
358 return false;
359 }
360
361 bool useCache = false;
362 auto slot = read();
363 auto rawHandle = readHandle(&useCache);
364 auto fence = readFence();
365 bool closeFence = true;
366
367 const native_handle_t* buffer;
368 ComposerResources::ReplacedBufferHandle replacedBuffer;
369 auto err = mResources->getLayerBuffer(mCurrentDisplay, mCurrentLayer, slot, useCache,
370 rawHandle, &buffer, &replacedBuffer);
371 if (err == Error::NONE) {
372 err = mHal->setLayerBuffer(mCurrentDisplay, mCurrentLayer, buffer, fence);
373 if (err == Error::NONE) {
374 closeFence = false;
375 }
376 }
377 if (closeFence) {
378 close(fence);
379 }
380 if (err != Error::NONE) {
381 mWriter.setError(getCommandLoc(), err);
382 }
383
384 return true;
385 }
386
387 bool executeSetLayerSurfaceDamage(uint16_t length) {
388 // N rectangles
389 if (length % 4 != 0) {
390 return false;
391 }
392
393 auto damage = readRegion(length / 4);
394 auto err = mHal->setLayerSurfaceDamage(mCurrentDisplay, mCurrentLayer, damage);
395 if (err != Error::NONE) {
396 mWriter.setError(getCommandLoc(), err);
397 }
398
399 return true;
400 }
401
402 bool executeSetLayerBlendMode(uint16_t length) {
403 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
404 return false;
405 }
406
407 auto err = mHal->setLayerBlendMode(mCurrentDisplay, mCurrentLayer, readSigned());
408 if (err != Error::NONE) {
409 mWriter.setError(getCommandLoc(), err);
410 }
411
412 return true;
413 }
414
415 bool executeSetLayerColor(uint16_t length) {
416 if (length != CommandWriterBase::kSetLayerColorLength) {
417 return false;
418 }
419
420 auto err = mHal->setLayerColor(mCurrentDisplay, mCurrentLayer, readColor());
421 if (err != Error::NONE) {
422 mWriter.setError(getCommandLoc(), err);
423 }
424
425 return true;
426 }
427
428 bool executeSetLayerCompositionType(uint16_t length) {
429 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
430 return false;
431 }
432
433 auto err = mHal->setLayerCompositionType(mCurrentDisplay, mCurrentLayer, readSigned());
434 if (err != Error::NONE) {
435 mWriter.setError(getCommandLoc(), err);
436 }
437
438 return true;
439 }
440
441 bool executeSetLayerDataspace(uint16_t length) {
442 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
443 return false;
444 }
445
446 auto err = mHal->setLayerDataspace(mCurrentDisplay, mCurrentLayer, readSigned());
447 if (err != Error::NONE) {
448 mWriter.setError(getCommandLoc(), err);
449 }
450
451 return true;
452 }
453
454 bool executeSetLayerDisplayFrame(uint16_t length) {
455 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
456 return false;
457 }
458
459 auto err = mHal->setLayerDisplayFrame(mCurrentDisplay, mCurrentLayer, readRect());
460 if (err != Error::NONE) {
461 mWriter.setError(getCommandLoc(), err);
462 }
463
464 return true;
465 }
466
467 bool executeSetLayerPlaneAlpha(uint16_t length) {
468 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
469 return false;
470 }
471
472 auto err = mHal->setLayerPlaneAlpha(mCurrentDisplay, mCurrentLayer, readFloat());
473 if (err != Error::NONE) {
474 mWriter.setError(getCommandLoc(), err);
475 }
476
477 return true;
478 }
479
480 bool executeSetLayerSidebandStream(uint16_t length) {
481 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
482 return false;
483 }
484
485 auto rawHandle = readHandle();
486
487 const native_handle_t* stream;
488 ComposerResources::ReplacedStreamHandle replacedStream;
489 auto err = mResources->getLayerSidebandStream(mCurrentDisplay, mCurrentLayer, rawHandle,
490 &stream, &replacedStream);
491 if (err == Error::NONE) {
492 err = mHal->setLayerSidebandStream(mCurrentDisplay, mCurrentLayer, stream);
493 }
494 if (err != Error::NONE) {
495 mWriter.setError(getCommandLoc(), err);
496 }
497
498 return true;
499 }
500
501 bool executeSetLayerSourceCrop(uint16_t length) {
502 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
503 return false;
504 }
505
506 auto err = mHal->setLayerSourceCrop(mCurrentDisplay, mCurrentLayer, readFRect());
507 if (err != Error::NONE) {
508 mWriter.setError(getCommandLoc(), err);
509 }
510
511 return true;
512 }
513
514 bool executeSetLayerTransform(uint16_t length) {
515 if (length != CommandWriterBase::kSetLayerTransformLength) {
516 return false;
517 }
518
519 auto err = mHal->setLayerTransform(mCurrentDisplay, mCurrentLayer, readSigned());
520 if (err != Error::NONE) {
521 mWriter.setError(getCommandLoc(), err);
522 }
523
524 return true;
525 }
526
527 bool executeSetLayerVisibleRegion(uint16_t length) {
528 // N rectangles
529 if (length % 4 != 0) {
530 return false;
531 }
532
533 auto region = readRegion(length / 4);
534 auto err = mHal->setLayerVisibleRegion(mCurrentDisplay, mCurrentLayer, region);
535 if (err != Error::NONE) {
536 mWriter.setError(getCommandLoc(), err);
537 }
538
539 return true;
540 }
541
542 bool executeSetLayerZOrder(uint16_t length) {
543 if (length != CommandWriterBase::kSetLayerZOrderLength) {
544 return false;
545 }
546
547 auto err = mHal->setLayerZOrder(mCurrentDisplay, mCurrentLayer, read());
548 if (err != Error::NONE) {
549 mWriter.setError(getCommandLoc(), err);
550 }
551
552 return true;
553 }
554
555 hwc_rect_t readRect() {
556 return hwc_rect_t{
557 readSigned(), readSigned(), readSigned(), readSigned(),
558 };
559 }
560
561 std::vector<hwc_rect_t> readRegion(size_t count) {
562 std::vector<hwc_rect_t> region;
563 region.reserve(count);
564 while (count > 0) {
565 region.emplace_back(readRect());
566 count--;
567 }
568
569 return region;
570 }
571
572 hwc_frect_t readFRect() {
573 return hwc_frect_t{
574 readFloat(), readFloat(), readFloat(), readFloat(),
575 };
576 }
577
578 ComposerHal* mHal;
579 ComposerResources* mResources;
580
581 // 64KiB minus a small space for metadata such as read/write pointers
582 static constexpr size_t kWriterInitialSize = 64 * 1024 / sizeof(uint32_t) - 16;
583 CommandWriterBase mWriter{kWriterInitialSize};
584
585 Display mCurrentDisplay = 0;
586 Layer mCurrentLayer = 0;
587};
588
589} // namespace hal
590} // namespace V2_1
591} // namespace composer
592} // namespace graphics
593} // namespace hardware
594} // namespace android
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerHal.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerHal.h
new file mode 100644
index 00000000..c9793fd9
--- /dev/null
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerHal.h
@@ -0,0 +1,137 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <string>
20#include <vector>
21
22#include <android/hardware/graphics/composer/2.1/IComposer.h>
23#include <android/hardware/graphics/composer/2.1/IComposerClient.h>
24
25// TODO remove hwcomposer2.h dependency
26#define HWC2_INCLUDE_STRINGIFICATION
27#define HWC2_USE_CPP11
28#include <hardware/hwcomposer2.h>
29#undef HWC2_INCLUDE_STRINGIFICATION
30#undef HWC2_USE_CPP11
31
32namespace android {
33namespace hardware {
34namespace graphics {
35namespace composer {
36namespace V2_1 {
37namespace hal {
38
39using common::V1_0::ColorMode;
40using common::V1_0::ColorTransform;
41using common::V1_0::Dataspace;
42using common::V1_0::Hdr;
43using common::V1_0::PixelFormat;
44using common::V1_0::Transform;
45
46class ComposerHal {
47 public:
48 virtual ~ComposerHal() = default;
49
50 virtual bool hasCapability(hwc2_capability_t capability) = 0;
51
52 // dump the debug information
53 virtual std::string dumpDebugInfo() = 0;
54
55 class EventCallback {
56 public:
57 virtual ~EventCallback() = default;
58 virtual void onHotplug(Display display, IComposerCallback::Connection connected) = 0;
59 virtual void onRefresh(Display display) = 0;
60 virtual void onVsync(Display display, int64_t timestamp) = 0;
61 };
62
63 // Register the event callback object. The event callback object is valid
64 // until it is unregistered. A hotplug event must be generated for each
65 // connected physical display, before or after this function returns.
66 virtual void registerEventCallback(EventCallback* callback) = 0;
67
68 // Unregister the event callback object. It must block if there is any
69 // callback in-flight.
70 virtual void unregisterEventCallback() = 0;
71
72 virtual uint32_t getMaxVirtualDisplayCount() = 0;
73 virtual Error createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format,
74 Display* outDisplay) = 0;
75 virtual Error destroyVirtualDisplay(Display display) = 0;
76 virtual Error createLayer(Display display, Layer* outLayer) = 0;
77 virtual Error destroyLayer(Display display, Layer layer) = 0;
78
79 virtual Error getActiveConfig(Display display, Config* outConfig) = 0;
80 virtual Error getClientTargetSupport(Display display, uint32_t width, uint32_t height,
81 PixelFormat format, Dataspace dataspace) = 0;
82 virtual Error getColorModes(Display display, hidl_vec<ColorMode>* outModes) = 0;
83 virtual Error getDisplayAttribute(Display display, Config config,
84 IComposerClient::Attribute attribute, int32_t* outValue) = 0;
85 virtual Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) = 0;
86 virtual Error getDisplayName(Display display, hidl_string* outName) = 0;
87 virtual Error getDisplayType(Display display, IComposerClient::DisplayType* outType) = 0;
88 virtual Error getDozeSupport(Display display, bool* outSupport) = 0;
89 virtual Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
90 float* outMaxLuminance, float* outMaxAverageLuminance,
91 float* outMinLuminance) = 0;
92
93 virtual Error setActiveConfig(Display display, Config config) = 0;
94 virtual Error setColorMode(Display display, ColorMode mode) = 0;
95 virtual Error setPowerMode(Display display, IComposerClient::PowerMode mode) = 0;
96 virtual Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled) = 0;
97
98 virtual Error setColorTransform(Display display, const float* matrix, int32_t hint) = 0;
99 virtual Error setClientTarget(Display display, buffer_handle_t target, int32_t acquireFence,
100 int32_t dataspace, const std::vector<hwc_rect_t>& damage) = 0;
101 virtual Error setOutputBuffer(Display display, buffer_handle_t buffer,
102 int32_t releaseFence) = 0;
103 virtual Error validateDisplay(Display display, std::vector<Layer>* outChangedLayers,
104 std::vector<IComposerClient::Composition>* outCompositionTypes,
105 uint32_t* outDisplayRequestMask,
106 std::vector<Layer>* outRequestedLayers,
107 std::vector<uint32_t>* outRequestMasks) = 0;
108 virtual Error acceptDisplayChanges(Display display) = 0;
109 virtual Error presentDisplay(Display display, int32_t* outPresentFence,
110 std::vector<Layer>* outLayers,
111 std::vector<int32_t>* outReleaseFences) = 0;
112
113 virtual Error setLayerCursorPosition(Display display, Layer layer, int32_t x, int32_t y) = 0;
114 virtual Error setLayerBuffer(Display display, Layer layer, buffer_handle_t buffer,
115 int32_t acquireFence) = 0;
116 virtual Error setLayerSurfaceDamage(Display display, Layer layer,
117 const std::vector<hwc_rect_t>& damage) = 0;
118 virtual Error setLayerBlendMode(Display display, Layer layer, int32_t mode) = 0;
119 virtual Error setLayerColor(Display display, Layer layer, IComposerClient::Color color) = 0;
120 virtual Error setLayerCompositionType(Display display, Layer layer, int32_t type) = 0;
121 virtual Error setLayerDataspace(Display display, Layer layer, int32_t dataspace) = 0;
122 virtual Error setLayerDisplayFrame(Display display, Layer layer, const hwc_rect_t& frame) = 0;
123 virtual Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) = 0;
124 virtual Error setLayerSidebandStream(Display display, Layer layer, buffer_handle_t stream) = 0;
125 virtual Error setLayerSourceCrop(Display display, Layer layer, const hwc_frect_t& crop) = 0;
126 virtual Error setLayerTransform(Display display, Layer layer, int32_t transform) = 0;
127 virtual Error setLayerVisibleRegion(Display display, Layer layer,
128 const std::vector<hwc_rect_t>& visible) = 0;
129 virtual Error setLayerZOrder(Display display, Layer layer, uint32_t z) = 0;
130};
131
132} // namespace hal
133} // namespace V2_1
134} // namespace composer
135} // namespace graphics
136} // namespace hardware
137} // namespace android
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h
new file mode 100644
index 00000000..7bb36929
--- /dev/null
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h
@@ -0,0 +1,536 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "ComposerResources.h included without LOG_TAG"
21#endif
22
23#include <memory>
24#include <mutex>
25#include <unordered_map>
26#include <vector>
27
28#include <android/hardware/graphics/mapper/2.0/IMapper.h>
29#include <log/log.h>
30
31namespace android {
32namespace hardware {
33namespace graphics {
34namespace composer {
35namespace V2_1 {
36namespace hal {
37
38// wrapper for IMapper to import buffers and sideband streams
39class ComposerHandleImporter {
40 public:
41 bool init() {
42 mMapper = mapper::V2_0::IMapper::getService();
43 ALOGE_IF(!mMapper, "failed to get mapper service");
44 return mMapper != nullptr;
45 }
46
47 Error importBuffer(const native_handle_t* rawHandle, const native_handle_t** outBufferHandle) {
48 if (!rawHandle || (!rawHandle->numFds && !rawHandle->numInts)) {
49 *outBufferHandle = nullptr;
50 return Error::NONE;
51 }
52
53 mapper::V2_0::Error error;
54 const native_handle_t* bufferHandle;
55 mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBufferHandle) {
56 error = tmpError;
57 bufferHandle = static_cast<const native_handle_t*>(tmpBufferHandle);
58 });
59 if (error != mapper::V2_0::Error::NONE) {
60 return Error::NO_RESOURCES;
61 }
62
63 *outBufferHandle = bufferHandle;
64 return Error::NONE;
65 }
66
67 void freeBuffer(const native_handle_t* bufferHandle) {
68 if (bufferHandle) {
69 mMapper->freeBuffer(static_cast<void*>(const_cast<native_handle_t*>(bufferHandle)));
70 }
71 }
72
73 Error importStream(const native_handle_t* rawHandle, const native_handle_t** outStreamHandle) {
74 const native_handle_t* streamHandle = nullptr;
75 if (rawHandle) {
76 streamHandle = native_handle_clone(rawHandle);
77 if (!streamHandle) {
78 return Error::NO_RESOURCES;
79 }
80 }
81
82 *outStreamHandle = streamHandle;
83 return Error::NONE;
84 }
85
86 void freeStream(const native_handle_t* streamHandle) {
87 if (streamHandle) {
88 native_handle_close(streamHandle);
89 native_handle_delete(const_cast<native_handle_t*>(streamHandle));
90 }
91 }
92
93 private:
94 sp<mapper::V2_0::IMapper> mMapper;
95};
96
97class ComposerHandleCache {
98 public:
99 enum class HandleType {
100 INVALID,
101 BUFFER,
102 STREAM,
103 };
104
105 ComposerHandleCache(ComposerHandleImporter& importer, HandleType type, uint32_t cacheSize)
106 : mImporter(importer), mHandleType(type), mHandles(cacheSize, nullptr) {}
107
108 // must be initialized later with initCache
109 ComposerHandleCache(ComposerHandleImporter& importer) : mImporter(importer) {}
110
111 ~ComposerHandleCache() {
112 switch (mHandleType) {
113 case HandleType::BUFFER:
114 for (auto handle : mHandles) {
115 mImporter.freeBuffer(handle);
116 }
117 break;
118 case HandleType::STREAM:
119 for (auto handle : mHandles) {
120 mImporter.freeStream(handle);
121 }
122 break;
123 default:
124 break;
125 }
126 }
127
128 ComposerHandleCache(const ComposerHandleCache&) = delete;
129 ComposerHandleCache& operator=(const ComposerHandleCache&) = delete;
130
131 bool initCache(HandleType type, uint32_t cacheSize) {
132 // already initialized
133 if (mHandleType != HandleType::INVALID) {
134 return false;
135 }
136
137 mHandleType = type;
138 mHandles.resize(cacheSize, nullptr);
139
140 return true;
141 }
142
143 Error lookupCache(uint32_t slot, const native_handle_t** outHandle) {
144 if (slot < mHandles.size()) {
145 *outHandle = mHandles[slot];
146 return Error::NONE;
147 } else {
148 return Error::BAD_PARAMETER;
149 }
150 }
151
152 Error updateCache(uint32_t slot, const native_handle_t* handle,
153 const native_handle** outReplacedHandle) {
154 if (slot < mHandles.size()) {
155 auto& cachedHandle = mHandles[slot];
156 *outReplacedHandle = cachedHandle;
157 cachedHandle = handle;
158 return Error::NONE;
159 } else {
160 return Error::BAD_PARAMETER;
161 }
162 }
163
164 // when fromCache is true, look up in the cache; otherwise, update the cache
165 Error getHandle(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
166 const native_handle_t** outHandle, const native_handle** outReplacedHandle) {
167 if (fromCache) {
168 *outReplacedHandle = nullptr;
169 return lookupCache(slot, outHandle);
170 } else {
171 *outHandle = inHandle;
172 return updateCache(slot, inHandle, outReplacedHandle);
173 }
174 }
175
176 private:
177 ComposerHandleImporter& mImporter;
178 HandleType mHandleType = HandleType::INVALID;
179 std::vector<const native_handle_t*> mHandles;
180};
181
182// layer resource
183class ComposerLayerResource {
184 public:
185 ComposerLayerResource(ComposerHandleImporter& importer, uint32_t bufferCacheSize)
186 : mBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, bufferCacheSize),
187 mSidebandStreamCache(importer, ComposerHandleCache::HandleType::STREAM, 1) {}
188
189 Error getBuffer(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
190 const native_handle_t** outHandle, const native_handle** outReplacedHandle) {
191 return mBufferCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
192 }
193
194 Error getSidebandStream(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
195 const native_handle_t** outHandle,
196 const native_handle** outReplacedHandle) {
197 return mSidebandStreamCache.getHandle(slot, fromCache, inHandle, outHandle,
198 outReplacedHandle);
199 }
200
201 protected:
202 ComposerHandleCache mBufferCache;
203 ComposerHandleCache mSidebandStreamCache;
204};
205
206// display resource
207class ComposerDisplayResource {
208 public:
209 enum class DisplayType {
210 PHYSICAL,
211 VIRTUAL,
212 };
213
214 ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
215 uint32_t outputBufferCacheSize)
216 : mType(type),
217 mClientTargetCache(importer),
218 mOutputBufferCache(importer, ComposerHandleCache::HandleType::BUFFER,
219 outputBufferCacheSize) {}
220
221 bool initClientTargetCache(uint32_t cacheSize) {
222 return mClientTargetCache.initCache(ComposerHandleCache::HandleType::BUFFER, cacheSize);
223 }
224
225 bool isVirtual() const { return mType == DisplayType::VIRTUAL; }
226
227 Error getClientTarget(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
228 const native_handle_t** outHandle,
229 const native_handle** outReplacedHandle) {
230 return mClientTargetCache.getHandle(slot, fromCache, inHandle, outHandle,
231 outReplacedHandle);
232 }
233
234 Error getOutputBuffer(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
235 const native_handle_t** outHandle,
236 const native_handle** outReplacedHandle) {
237 return mOutputBufferCache.getHandle(slot, fromCache, inHandle, outHandle,
238 outReplacedHandle);
239 }
240
241 bool addLayer(Layer layer, std::unique_ptr<ComposerLayerResource> layerResource) {
242 auto result = mLayerResources.emplace(layer, std::move(layerResource));
243 return result.second;
244 }
245
246 bool removeLayer(Layer layer) { return mLayerResources.erase(layer) > 0; }
247
248 ComposerLayerResource* findLayerResource(Layer layer) {
249 auto layerIter = mLayerResources.find(layer);
250 if (layerIter == mLayerResources.end()) {
251 return nullptr;
252 }
253
254 return layerIter->second.get();
255 }
256
257 std::vector<Layer> getLayers() const {
258 std::vector<Layer> layers;
259 layers.reserve(mLayerResources.size());
260 for (const auto& layerKey : mLayerResources) {
261 layers.push_back(layerKey.first);
262 }
263 return layers;
264 }
265
266 protected:
267 const DisplayType mType;
268 ComposerHandleCache mClientTargetCache;
269 ComposerHandleCache mOutputBufferCache;
270
271 std::unordered_map<Layer, std::unique_ptr<ComposerLayerResource>> mLayerResources;
272};
273
274class ComposerResources {
275 private:
276 template <bool isBuffer>
277 class ReplacedHandle;
278
279 public:
280 static std::unique_ptr<ComposerResources> create() {
281 auto resources = std::make_unique<ComposerResources>();
282 return resources->init() ? std::move(resources) : nullptr;
283 }
284
285 ComposerResources() = default;
286 virtual ~ComposerResources() = default;
287
288 bool init() { return mImporter.init(); }
289
290 using RemoveDisplay =
291 std::function<void(Display display, bool isVirtual, const std::vector<Layer>& layers)>;
292 void clear(RemoveDisplay removeDisplay) {
293 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
294 for (const auto& displayKey : mDisplayResources) {
295 Display display = displayKey.first;
296 const ComposerDisplayResource& displayResource = *displayKey.second;
297 removeDisplay(display, displayResource.isVirtual(), displayResource.getLayers());
298 }
299 mDisplayResources.clear();
300 }
301
302 Error addPhysicalDisplay(Display display) {
303 auto displayResource =
304 createDisplayResource(ComposerDisplayResource::DisplayType::PHYSICAL, 0);
305
306 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
307 auto result = mDisplayResources.emplace(display, std::move(displayResource));
308 return result.second ? Error::NONE : Error::BAD_DISPLAY;
309 }
310
311 Error addVirtualDisplay(Display display, uint32_t outputBufferCacheSize) {
312 auto displayResource = createDisplayResource(ComposerDisplayResource::DisplayType::VIRTUAL,
313 outputBufferCacheSize);
314
315 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
316 auto result = mDisplayResources.emplace(display, std::move(displayResource));
317 return result.second ? Error::NONE : Error::BAD_DISPLAY;
318 }
319
320 Error removeDisplay(Display display) {
321 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
322 return mDisplayResources.erase(display) > 0 ? Error::NONE : Error::BAD_DISPLAY;
323 }
324
325 Error setDisplayClientTargetCacheSize(Display display, uint32_t clientTargetCacheSize) {
326 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
327 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
328 if (!displayResource) {
329 return Error::BAD_DISPLAY;
330 }
331
332 return displayResource->initClientTargetCache(clientTargetCacheSize) ? Error::NONE
333 : Error::BAD_PARAMETER;
334 }
335
336 Error addLayer(Display display, Layer layer, uint32_t bufferCacheSize) {
337 auto layerResource = createLayerResource(bufferCacheSize);
338
339 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
340 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
341 if (!displayResource) {
342 return Error::BAD_DISPLAY;
343 }
344
345 return displayResource->addLayer(layer, std::move(layerResource)) ? Error::NONE
346 : Error::BAD_LAYER;
347 }
348
349 Error removeLayer(Display display, Layer layer) {
350 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
351 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
352 if (!displayResource) {
353 return Error::BAD_DISPLAY;
354 }
355
356 return displayResource->removeLayer(layer) ? Error::NONE : Error::BAD_LAYER;
357 }
358
359 using ReplacedBufferHandle = ReplacedHandle<true>;
360 using ReplacedStreamHandle = ReplacedHandle<false>;
361
362 Error getDisplayClientTarget(Display display, uint32_t slot, bool fromCache,
363 const native_handle_t* rawHandle,
364 const native_handle_t** outBufferHandle,
365 ReplacedBufferHandle* outReplacedBuffer) {
366 return getHandle<Cache::CLIENT_TARGET>(display, 0, slot, fromCache, rawHandle,
367 outBufferHandle, outReplacedBuffer);
368 }
369
370 Error getDisplayOutputBuffer(Display display, uint32_t slot, bool fromCache,
371 const native_handle_t* rawHandle,
372 const native_handle_t** outBufferHandle,
373 ReplacedBufferHandle* outReplacedBuffer) {
374 return getHandle<Cache::OUTPUT_BUFFER>(display, 0, slot, fromCache, rawHandle,
375 outBufferHandle, outReplacedBuffer);
376 }
377
378 Error getLayerBuffer(Display display, Layer layer, uint32_t slot, bool fromCache,
379 const native_handle_t* rawHandle, const native_handle_t** outBufferHandle,
380 ReplacedBufferHandle* outReplacedBuffer) {
381 return getHandle<Cache::LAYER_BUFFER>(display, layer, slot, fromCache, rawHandle,
382 outBufferHandle, outReplacedBuffer);
383 }
384
385 Error getLayerSidebandStream(Display display, Layer layer, const native_handle_t* rawHandle,
386 const native_handle_t** outStreamHandle,
387 ReplacedStreamHandle* outReplacedStream) {
388 return getHandle<Cache::LAYER_SIDEBAND_STREAM>(display, layer, 0, false, rawHandle,
389 outStreamHandle, outReplacedStream);
390 }
391
392 protected:
393 virtual std::unique_ptr<ComposerDisplayResource> createDisplayResource(
394 ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) {
395 return std::make_unique<ComposerDisplayResource>(type, mImporter, outputBufferCacheSize);
396 }
397
398 virtual std::unique_ptr<ComposerLayerResource> createLayerResource(uint32_t bufferCacheSize) {
399 return std::make_unique<ComposerLayerResource>(mImporter, bufferCacheSize);
400 }
401
402 ComposerDisplayResource* findDisplayResourceLocked(Display display) {
403 auto iter = mDisplayResources.find(display);
404 if (iter == mDisplayResources.end()) {
405 return nullptr;
406 }
407 return iter->second.get();
408 }
409
410 ComposerHandleImporter mImporter;
411
412 std::mutex mDisplayResourcesMutex;
413 std::unordered_map<Display, std::unique_ptr<ComposerDisplayResource>> mDisplayResources;
414
415 private:
416 enum class Cache {
417 CLIENT_TARGET,
418 OUTPUT_BUFFER,
419 LAYER_BUFFER,
420 LAYER_SIDEBAND_STREAM,
421 };
422
423 // When a buffer in the cache is replaced by a new one, we must keep it
424 // alive until it has been replaced in ComposerHal.
425 template <bool isBuffer>
426 class ReplacedHandle {
427 public:
428 ReplacedHandle() = default;
429 ReplacedHandle(const ReplacedHandle&) = delete;
430 ReplacedHandle& operator=(const ReplacedHandle&) = delete;
431
432 ~ReplacedHandle() { reset(); }
433
434 void reset(ComposerHandleImporter* importer = nullptr,
435 const native_handle_t* handle = nullptr) {
436 if (mHandle) {
437 if (isBuffer) {
438 mImporter->freeBuffer(mHandle);
439 } else {
440 mImporter->freeStream(mHandle);
441 }
442 }
443
444 mImporter = importer;
445 mHandle = handle;
446 }
447
448 private:
449 ComposerHandleImporter* mImporter = nullptr;
450 const native_handle_t* mHandle = nullptr;
451 };
452
453 template <Cache cache, bool isBuffer>
454 Error getHandle(Display display, Layer layer, uint32_t slot, bool fromCache,
455 const native_handle_t* rawHandle, const native_handle_t** outHandle,
456 ReplacedHandle<isBuffer>* outReplacedHandle) {
457 Error error;
458
459 // import the raw handle (or ignore raw handle when fromCache is true)
460 const native_handle_t* importedHandle = nullptr;
461 if (!fromCache) {
462 error = (isBuffer) ? mImporter.importBuffer(rawHandle, &importedHandle)
463 : mImporter.importStream(rawHandle, &importedHandle);
464 if (error != Error::NONE) {
465 return error;
466 }
467 }
468
469 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
470
471 // find display/layer resource
472 const bool needLayerResource =
473 (cache == Cache::LAYER_BUFFER || cache == Cache::LAYER_SIDEBAND_STREAM);
474 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
475 ComposerLayerResource* layerResource = (displayResource && needLayerResource)
476 ? displayResource->findLayerResource(layer)
477 : nullptr;
478
479 // lookup or update cache
480 const native_handle_t* replacedHandle = nullptr;
481 if (displayResource && (!needLayerResource || layerResource)) {
482 switch (cache) {
483 case Cache::CLIENT_TARGET:
484 error = displayResource->getClientTarget(slot, fromCache, importedHandle,
485 outHandle, &replacedHandle);
486 break;
487 case Cache::OUTPUT_BUFFER:
488 error = displayResource->getOutputBuffer(slot, fromCache, importedHandle,
489 outHandle, &replacedHandle);
490 break;
491 case Cache::LAYER_BUFFER:
492 error = layerResource->getBuffer(slot, fromCache, importedHandle, outHandle,
493 &replacedHandle);
494 break;
495 case Cache::LAYER_SIDEBAND_STREAM:
496 error = layerResource->getSidebandStream(slot, fromCache, importedHandle,
497 outHandle, &replacedHandle);
498 break;
499 default:
500 error = Error::BAD_PARAMETER;
501 break;
502 }
503
504 if (error != Error::NONE) {
505 ALOGW("invalid cache %d slot %d", int(cache), int(slot));
506 }
507 } else if (!displayResource) {
508 error = Error::BAD_DISPLAY;
509 } else {
510 error = Error::BAD_LAYER;
511 }
512
513 // clean up on errors
514 if (error != Error::NONE) {
515 if (!fromCache) {
516 if (isBuffer) {
517 mImporter.freeBuffer(importedHandle);
518 } else {
519 mImporter.freeStream(importedHandle);
520 }
521 }
522 return error;
523 }
524
525 outReplacedHandle->reset(&mImporter, replacedHandle);
526
527 return Error::NONE;
528 }
529};
530
531} // namespace hal
532} // namespace V2_1
533} // namespace composer
534} // namespace graphics
535} // namespace hardware
536} // namespace android
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
new file mode 100644
index 00000000..420a1f60
--- /dev/null
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
@@ -0,0 +1,76 @@
1// Copyright 2010 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15cc_library_shared {
16 name: "libhwc2on1adapter",
17 vendor: true,
18
19 clang: true,
20 cflags: [
21 "-Wall",
22 "-Werror",
23 "-Wno-user-defined-warnings",
24 ],
25 cppflags: [
26 "-Weverything",
27 "-Wunused",
28 "-Wunreachable-code",
29
30 // The static constructors and destructors in this library have not been noted to
31 // introduce significant overheads
32 "-Wno-exit-time-destructors",
33 "-Wno-global-constructors",
34
35 // We only care about compiling as C++14
36 "-Wno-c++98-compat-pedantic",
37
38 // android/sensors.h uses nested anonymous unions and anonymous structs
39 "-Wno-nested-anon-types",
40 "-Wno-gnu-anonymous-struct",
41
42 // Don't warn about struct padding
43 "-Wno-padded",
44
45 // hwcomposer2.h features switch covering all cases.
46 "-Wno-covered-switch-default",
47
48 // hwcomposer.h features zero size array.
49 "-Wno-zero-length-array",
50
51 // Disabling warning specific to hwc2on1adapter code
52 "-Wno-double-promotion",
53 "-Wno-sign-conversion",
54 "-Wno-switch-enum",
55 "-Wno-float-equal",
56 "-Wno-shorten-64-to-32",
57 "-Wno-sign-compare",
58 "-Wno-missing-prototypes",
59 ],
60
61 srcs: [
62 "HWC2On1Adapter.cpp",
63 "MiniFence.cpp",
64 ],
65
66 shared_libs: [
67 "libutils",
68 "libcutils",
69 "liblog",
70 "libhardware",
71 ],
72
73 export_include_dirs: ["include"],
74
75 export_shared_lib_headers: ["libutils"],
76}
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/CleanSpec.mk b/graphics/composer/2.1/utils/hwc2on1adapter/CleanSpec.mk
new file mode 100644
index 00000000..7fc22161
--- /dev/null
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/CleanSpec.mk
@@ -0,0 +1,52 @@
1# Copyright (C) 2017 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#
15
16# If you don't need to do a full clean build but would like to touch
17# a file or delete some intermediate files, add a clean step to the end
18# of the list. These steps will only be run once, if they haven't been
19# run before.
20#
21# E.g.:
22# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
23# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
24#
25# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
26# files that are missing or have been moved.
27#
28# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
29# Use $(OUT_DIR) to refer to the "out" directory.
30#
31# If you need to re-do something that's already mentioned, just copy
32# the command and add it to the bottom of the list. E.g., if a change
33# that you made last week required touching a file and a change you
34# made today requires touching the same file, just copy the old
35# touch step and add it to the end of the list.
36#
37# ************************************************
38# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
39# ************************************************
40
41# For example:
42#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
43#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
44#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
45#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
46
47# ************************************************
48# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
49# ************************************************
50$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libhwc2on1adapter_intermediates)
51$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libhwc2on1adapter.so)
52$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/libhwc2on1adapter.so)
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp b/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp
new file mode 100644
index 00000000..77f06bbb
--- /dev/null
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp
@@ -0,0 +1,2637 @@
1/*
2 * Copyright 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "hwc2on1adapter/HWC2On1Adapter.h"
18
19//#define LOG_NDEBUG 0
20
21#undef LOG_TAG
22#define LOG_TAG "HWC2On1Adapter"
23#define ATRACE_TAG ATRACE_TAG_GRAPHICS
24
25
26#include <inttypes.h>
27
28#include <chrono>
29#include <cstdlib>
30#include <sstream>
31
32#include <hardware/hwcomposer.h>
33#include <log/log.h>
34#include <utils/Trace.h>
35
36using namespace std::chrono_literals;
37
38static uint8_t getMinorVersion(struct hwc_composer_device_1* device)
39{
40 auto version = device->common.version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
41 return (version >> 16) & 0xF;
42}
43
44template <typename PFN, typename T>
45static hwc2_function_pointer_t asFP(T function)
46{
47 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
48 return reinterpret_cast<hwc2_function_pointer_t>(function);
49}
50
51using namespace HWC2;
52
53static constexpr Attribute ColorMode = static_cast<Attribute>(6);
54
55namespace android {
56
57class HWC2On1Adapter::Callbacks : public hwc_procs_t {
58 public:
59 explicit Callbacks(HWC2On1Adapter& adapter) : mAdapter(adapter) {
60 invalidate = &invalidateHook;
61 vsync = &vsyncHook;
62 hotplug = &hotplugHook;
63 }
64
65 static void invalidateHook(const hwc_procs_t* procs) {
66 auto callbacks = static_cast<const Callbacks*>(procs);
67 callbacks->mAdapter.hwc1Invalidate();
68 }
69
70 static void vsyncHook(const hwc_procs_t* procs, int display,
71 int64_t timestamp) {
72 auto callbacks = static_cast<const Callbacks*>(procs);
73 callbacks->mAdapter.hwc1Vsync(display, timestamp);
74 }
75
76 static void hotplugHook(const hwc_procs_t* procs, int display,
77 int connected) {
78 auto callbacks = static_cast<const Callbacks*>(procs);
79 callbacks->mAdapter.hwc1Hotplug(display, connected);
80 }
81
82 private:
83 HWC2On1Adapter& mAdapter;
84};
85
86static int closeHook(hw_device_t* /*device*/)
87{
88 // Do nothing, since the real work is done in the class destructor, but we
89 // need to provide a valid function pointer for hwc2_close to call
90 return 0;
91}
92
93HWC2On1Adapter::HWC2On1Adapter(hwc_composer_device_1_t* hwc1Device)
94 : mDumpString(),
95 mHwc1Device(hwc1Device),
96 mHwc1MinorVersion(getMinorVersion(hwc1Device)),
97 mHwc1SupportsVirtualDisplays(false),
98 mHwc1SupportsBackgroundColor(false),
99 mHwc1Callbacks(std::make_unique<Callbacks>(*this)),
100 mCapabilities(),
101 mLayers(),
102 mHwc1VirtualDisplay(),
103 mStateMutex(),
104 mCallbacks(),
105 mHasPendingInvalidate(false),
106 mPendingVsyncs(),
107 mPendingHotplugs(),
108 mDisplays(),
109 mHwc1DisplayMap()
110{
111 common.close = closeHook;
112 getCapabilities = getCapabilitiesHook;
113 getFunction = getFunctionHook;
114 populateCapabilities();
115 populatePrimary();
116 mHwc1Device->registerProcs(mHwc1Device,
117 static_cast<const hwc_procs_t*>(mHwc1Callbacks.get()));
118}
119
120HWC2On1Adapter::~HWC2On1Adapter() {
121 hwc_close_1(mHwc1Device);
122}
123
124void HWC2On1Adapter::doGetCapabilities(uint32_t* outCount,
125 int32_t* outCapabilities) {
126 if (outCapabilities == nullptr) {
127 *outCount = mCapabilities.size();
128 return;
129 }
130
131 auto capabilityIter = mCapabilities.cbegin();
132 for (size_t written = 0; written < *outCount; ++written) {
133 if (capabilityIter == mCapabilities.cend()) {
134 return;
135 }
136 outCapabilities[written] = static_cast<int32_t>(*capabilityIter);
137 ++capabilityIter;
138 }
139}
140
141hwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
142 FunctionDescriptor descriptor) {
143 switch (descriptor) {
144 // Device functions
145 case FunctionDescriptor::CreateVirtualDisplay:
146 return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
147 createVirtualDisplayHook);
148 case FunctionDescriptor::DestroyVirtualDisplay:
149 return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
150 destroyVirtualDisplayHook);
151 case FunctionDescriptor::Dump:
152 return asFP<HWC2_PFN_DUMP>(dumpHook);
153 case FunctionDescriptor::GetMaxVirtualDisplayCount:
154 return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
155 getMaxVirtualDisplayCountHook);
156 case FunctionDescriptor::RegisterCallback:
157 return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
158
159 // Display functions
160 case FunctionDescriptor::AcceptDisplayChanges:
161 return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
162 displayHook<decltype(&Display::acceptChanges),
163 &Display::acceptChanges>);
164 case FunctionDescriptor::CreateLayer:
165 return asFP<HWC2_PFN_CREATE_LAYER>(
166 displayHook<decltype(&Display::createLayer),
167 &Display::createLayer, hwc2_layer_t*>);
168 case FunctionDescriptor::DestroyLayer:
169 return asFP<HWC2_PFN_DESTROY_LAYER>(
170 displayHook<decltype(&Display::destroyLayer),
171 &Display::destroyLayer, hwc2_layer_t>);
172 case FunctionDescriptor::GetActiveConfig:
173 return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
174 displayHook<decltype(&Display::getActiveConfig),
175 &Display::getActiveConfig, hwc2_config_t*>);
176 case FunctionDescriptor::GetChangedCompositionTypes:
177 return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
178 displayHook<decltype(&Display::getChangedCompositionTypes),
179 &Display::getChangedCompositionTypes, uint32_t*,
180 hwc2_layer_t*, int32_t*>);
181 case FunctionDescriptor::GetColorModes:
182 return asFP<HWC2_PFN_GET_COLOR_MODES>(
183 displayHook<decltype(&Display::getColorModes),
184 &Display::getColorModes, uint32_t*, int32_t*>);
185 case FunctionDescriptor::GetDisplayAttribute:
186 return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
187 getDisplayAttributeHook);
188 case FunctionDescriptor::GetDisplayConfigs:
189 return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
190 displayHook<decltype(&Display::getConfigs),
191 &Display::getConfigs, uint32_t*, hwc2_config_t*>);
192 case FunctionDescriptor::GetDisplayName:
193 return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
194 displayHook<decltype(&Display::getName),
195 &Display::getName, uint32_t*, char*>);
196 case FunctionDescriptor::GetDisplayRequests:
197 return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
198 displayHook<decltype(&Display::getRequests),
199 &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*,
200 int32_t*>);
201 case FunctionDescriptor::GetDisplayType:
202 return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
203 displayHook<decltype(&Display::getType),
204 &Display::getType, int32_t*>);
205 case FunctionDescriptor::GetDozeSupport:
206 return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
207 displayHook<decltype(&Display::getDozeSupport),
208 &Display::getDozeSupport, int32_t*>);
209 case FunctionDescriptor::GetHdrCapabilities:
210 return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
211 displayHook<decltype(&Display::getHdrCapabilities),
212 &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
213 float*, float*>);
214 case FunctionDescriptor::GetReleaseFences:
215 return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
216 displayHook<decltype(&Display::getReleaseFences),
217 &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
218 int32_t*>);
219 case FunctionDescriptor::PresentDisplay:
220 return asFP<HWC2_PFN_PRESENT_DISPLAY>(
221 displayHook<decltype(&Display::present),
222 &Display::present, int32_t*>);
223 case FunctionDescriptor::SetActiveConfig:
224 return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
225 displayHook<decltype(&Display::setActiveConfig),
226 &Display::setActiveConfig, hwc2_config_t>);
227 case FunctionDescriptor::SetClientTarget:
228 return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
229 displayHook<decltype(&Display::setClientTarget),
230 &Display::setClientTarget, buffer_handle_t, int32_t,
231 int32_t, hwc_region_t>);
232 case FunctionDescriptor::SetColorMode:
233 return asFP<HWC2_PFN_SET_COLOR_MODE>(setColorModeHook);
234 case FunctionDescriptor::SetColorTransform:
235 return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
236 case FunctionDescriptor::SetOutputBuffer:
237 return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
238 displayHook<decltype(&Display::setOutputBuffer),
239 &Display::setOutputBuffer, buffer_handle_t, int32_t>);
240 case FunctionDescriptor::SetPowerMode:
241 return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
242 case FunctionDescriptor::SetVsyncEnabled:
243 return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook);
244 case FunctionDescriptor::ValidateDisplay:
245 return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
246 displayHook<decltype(&Display::validate),
247 &Display::validate, uint32_t*, uint32_t*>);
248 case FunctionDescriptor::GetClientTargetSupport:
249 return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
250 displayHook<decltype(&Display::getClientTargetSupport),
251 &Display::getClientTargetSupport, uint32_t, uint32_t,
252 int32_t, int32_t>);
253
254 // Layer functions
255 case FunctionDescriptor::SetCursorPosition:
256 return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
257 layerHook<decltype(&Layer::setCursorPosition),
258 &Layer::setCursorPosition, int32_t, int32_t>);
259 case FunctionDescriptor::SetLayerBuffer:
260 return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
261 layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
262 buffer_handle_t, int32_t>);
263 case FunctionDescriptor::SetLayerSurfaceDamage:
264 return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
265 layerHook<decltype(&Layer::setSurfaceDamage),
266 &Layer::setSurfaceDamage, hwc_region_t>);
267
268 // Layer state functions
269 case FunctionDescriptor::SetLayerBlendMode:
270 return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
271 setLayerBlendModeHook);
272 case FunctionDescriptor::SetLayerColor:
273 return asFP<HWC2_PFN_SET_LAYER_COLOR>(
274 layerHook<decltype(&Layer::setColor), &Layer::setColor,
275 hwc_color_t>);
276 case FunctionDescriptor::SetLayerCompositionType:
277 return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
278 setLayerCompositionTypeHook);
279 case FunctionDescriptor::SetLayerDataspace:
280 return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerDataspaceHook);
281 case FunctionDescriptor::SetLayerDisplayFrame:
282 return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
283 layerHook<decltype(&Layer::setDisplayFrame),
284 &Layer::setDisplayFrame, hwc_rect_t>);
285 case FunctionDescriptor::SetLayerPlaneAlpha:
286 return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
287 layerHook<decltype(&Layer::setPlaneAlpha),
288 &Layer::setPlaneAlpha, float>);
289 case FunctionDescriptor::SetLayerSidebandStream:
290 return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
291 layerHook<decltype(&Layer::setSidebandStream),
292 &Layer::setSidebandStream, const native_handle_t*>);
293 case FunctionDescriptor::SetLayerSourceCrop:
294 return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
295 layerHook<decltype(&Layer::setSourceCrop),
296 &Layer::setSourceCrop, hwc_frect_t>);
297 case FunctionDescriptor::SetLayerTransform:
298 return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerTransformHook);
299 case FunctionDescriptor::SetLayerVisibleRegion:
300 return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
301 layerHook<decltype(&Layer::setVisibleRegion),
302 &Layer::setVisibleRegion, hwc_region_t>);
303 case FunctionDescriptor::SetLayerZOrder:
304 return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerZOrderHook);
305
306 default:
307 ALOGE("doGetFunction: Unknown function descriptor: %d (%s)",
308 static_cast<int32_t>(descriptor),
309 to_string(descriptor).c_str());
310 return nullptr;
311 }
312}
313
314// Device functions
315
316Error HWC2On1Adapter::createVirtualDisplay(uint32_t width,
317 uint32_t height, hwc2_display_t* outDisplay) {
318 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
319
320 if (mHwc1VirtualDisplay) {
321 // We have already allocated our only HWC1 virtual display
322 ALOGE("createVirtualDisplay: HWC1 virtual display already allocated");
323 return Error::NoResources;
324 }
325
326 mHwc1VirtualDisplay = std::make_shared<HWC2On1Adapter::Display>(*this,
327 HWC2::DisplayType::Virtual);
328 mHwc1VirtualDisplay->populateConfigs(width, height);
329 const auto displayId = mHwc1VirtualDisplay->getId();
330 mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL] = displayId;
331 mHwc1VirtualDisplay->setHwc1Id(HWC_DISPLAY_VIRTUAL);
332 mDisplays.emplace(displayId, mHwc1VirtualDisplay);
333 *outDisplay = displayId;
334
335 return Error::None;
336}
337
338Error HWC2On1Adapter::destroyVirtualDisplay(hwc2_display_t displayId) {
339 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
340
341 if (!mHwc1VirtualDisplay || (mHwc1VirtualDisplay->getId() != displayId)) {
342 return Error::BadDisplay;
343 }
344
345 mHwc1VirtualDisplay.reset();
346 mHwc1DisplayMap.erase(HWC_DISPLAY_VIRTUAL);
347 mDisplays.erase(displayId);
348
349 return Error::None;
350}
351
352void HWC2On1Adapter::dump(uint32_t* outSize, char* outBuffer) {
353 if (outBuffer != nullptr) {
354 auto copiedBytes = mDumpString.copy(outBuffer, *outSize);
355 *outSize = static_cast<uint32_t>(copiedBytes);
356 return;
357 }
358
359 std::stringstream output;
360
361 output << "-- HWC2On1Adapter --\n";
362
363 output << "Adapting to a HWC 1." << static_cast<int>(mHwc1MinorVersion) <<
364 " device\n";
365
366 // Attempt to acquire the lock for 1 second, but proceed without the lock
367 // after that, so we can still get some information if we're deadlocked
368 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex,
369 std::defer_lock);
370 lock.try_lock_for(1s);
371
372 if (mCapabilities.empty()) {
373 output << "Capabilities: None\n";
374 } else {
375 output << "Capabilities:\n";
376 for (auto capability : mCapabilities) {
377 output << " " << to_string(capability) << '\n';
378 }
379 }
380
381 output << "Displays:\n";
382 for (const auto& element : mDisplays) {
383 const auto& display = element.second;
384 output << display->dump();
385 }
386 output << '\n';
387
388 // Release the lock before calling into HWC1, and since we no longer require
389 // mutual exclusion to access mCapabilities or mDisplays
390 lock.unlock();
391
392 if (mHwc1Device->dump) {
393 output << "HWC1 dump:\n";
394 std::vector<char> hwc1Dump(4096);
395 // Call with size - 1 to preserve a null character at the end
396 mHwc1Device->dump(mHwc1Device, hwc1Dump.data(),
397 static_cast<int>(hwc1Dump.size() - 1));
398 output << hwc1Dump.data();
399 }
400
401 mDumpString = output.str();
402 *outSize = static_cast<uint32_t>(mDumpString.size());
403}
404
405uint32_t HWC2On1Adapter::getMaxVirtualDisplayCount() {
406 return mHwc1SupportsVirtualDisplays ? 1 : 0;
407}
408
409static bool isValid(Callback descriptor) {
410 switch (descriptor) {
411 case Callback::Hotplug: // Fall-through
412 case Callback::Refresh: // Fall-through
413 case Callback::Vsync: return true;
414 default: return false;
415 }
416}
417
418Error HWC2On1Adapter::registerCallback(Callback descriptor,
419 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
420 if (!isValid(descriptor)) {
421 return Error::BadParameter;
422 }
423
424 ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(),
425 callbackData, pointer);
426
427 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
428
429 if (pointer != nullptr) {
430 mCallbacks[descriptor] = {callbackData, pointer};
431 } else {
432 ALOGI("unregisterCallback(%s)", to_string(descriptor).c_str());
433 mCallbacks.erase(descriptor);
434 return Error::None;
435 }
436
437 bool hasPendingInvalidate = false;
438 std::vector<hwc2_display_t> displayIds;
439 std::vector<std::pair<hwc2_display_t, int64_t>> pendingVsyncs;
440 std::vector<std::pair<hwc2_display_t, int>> pendingHotplugs;
441
442 if (descriptor == Callback::Refresh) {
443 hasPendingInvalidate = mHasPendingInvalidate;
444 if (hasPendingInvalidate) {
445 for (auto& displayPair : mDisplays) {
446 displayIds.emplace_back(displayPair.first);
447 }
448 }
449 mHasPendingInvalidate = false;
450 } else if (descriptor == Callback::Vsync) {
451 for (auto pending : mPendingVsyncs) {
452 auto hwc1DisplayId = pending.first;
453 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
454 ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d",
455 hwc1DisplayId);
456 continue;
457 }
458 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
459 auto timestamp = pending.second;
460 pendingVsyncs.emplace_back(displayId, timestamp);
461 }
462 mPendingVsyncs.clear();
463 } else if (descriptor == Callback::Hotplug) {
464 // Hotplug the primary display
465 pendingHotplugs.emplace_back(mHwc1DisplayMap[HWC_DISPLAY_PRIMARY],
466 static_cast<int32_t>(Connection::Connected));
467
468 for (auto pending : mPendingHotplugs) {
469 auto hwc1DisplayId = pending.first;
470 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
471 ALOGE("hwc1Hotplug: Couldn't find display for HWC1 id %d",
472 hwc1DisplayId);
473 continue;
474 }
475 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
476 auto connected = pending.second;
477 pendingHotplugs.emplace_back(displayId, connected);
478 }
479 }
480
481 // Call pending callbacks without the state lock held
482 lock.unlock();
483
484 if (hasPendingInvalidate) {
485 auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
486 for (auto displayId : displayIds) {
487 refresh(callbackData, displayId);
488 }
489 }
490 if (!pendingVsyncs.empty()) {
491 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
492 for (auto& pendingVsync : pendingVsyncs) {
493 vsync(callbackData, pendingVsync.first, pendingVsync.second);
494 }
495 }
496 if (!pendingHotplugs.empty()) {
497 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
498 for (auto& pendingHotplug : pendingHotplugs) {
499 hotplug(callbackData, pendingHotplug.first, pendingHotplug.second);
500 }
501 }
502 return Error::None;
503}
504
505// Display functions
506
507std::atomic<hwc2_display_t> HWC2On1Adapter::Display::sNextId(1);
508
509HWC2On1Adapter::Display::Display(HWC2On1Adapter& device, HWC2::DisplayType type)
510 : mId(sNextId++),
511 mDevice(device),
512 mStateMutex(),
513 mHwc1RequestedContents(nullptr),
514 mRetireFence(),
515 mChanges(),
516 mHwc1Id(-1),
517 mConfigs(),
518 mActiveConfig(nullptr),
519 mActiveColorMode(static_cast<android_color_mode_t>(-1)),
520 mName(),
521 mType(type),
522 mPowerMode(PowerMode::Off),
523 mVsyncEnabled(Vsync::Invalid),
524 mClientTarget(),
525 mOutputBuffer(),
526 mHasColorTransform(false),
527 mLayers(),
528 mHwc1LayerMap(),
529 mNumAvailableRects(0),
530 mNextAvailableRect(nullptr),
531 mGeometryChanged(false)
532 {}
533
534Error HWC2On1Adapter::Display::acceptChanges() {
535 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
536
537 if (!mChanges) {
538 ALOGV("[%" PRIu64 "] acceptChanges failed, not validated", mId);
539 return Error::NotValidated;
540 }
541
542 ALOGV("[%" PRIu64 "] acceptChanges", mId);
543
544 for (auto& change : mChanges->getTypeChanges()) {
545 auto layerId = change.first;
546 auto type = change.second;
547 if (mDevice.mLayers.count(layerId) == 0) {
548 // This should never happen but somehow does.
549 ALOGW("Cannot accept change for unknown layer (%" PRIu64 ")",
550 layerId);
551 continue;
552 }
553 auto layer = mDevice.mLayers[layerId];
554 layer->setCompositionType(type);
555 }
556
557 mChanges->clearTypeChanges();
558
559 return Error::None;
560}
561
562Error HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId) {
563 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
564
565 auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
566 mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
567 *outLayerId = layer->getId();
568 ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId);
569 markGeometryChanged();
570 return Error::None;
571}
572
573Error HWC2On1Adapter::Display::destroyLayer(hwc2_layer_t layerId) {
574 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
575
576 const auto mapLayer = mDevice.mLayers.find(layerId);
577 if (mapLayer == mDevice.mLayers.end()) {
578 ALOGV("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer",
579 mId, layerId);
580 return Error::BadLayer;
581 }
582 const auto layer = mapLayer->second;
583 mDevice.mLayers.erase(mapLayer);
584 const auto zRange = mLayers.equal_range(layer);
585 for (auto current = zRange.first; current != zRange.second; ++current) {
586 if (**current == *layer) {
587 current = mLayers.erase(current);
588 break;
589 }
590 }
591 ALOGV("[%" PRIu64 "] destroyed layer %" PRIu64, mId, layerId);
592 markGeometryChanged();
593 return Error::None;
594}
595
596Error HWC2On1Adapter::Display::getActiveConfig(hwc2_config_t* outConfig) {
597 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
598
599 if (!mActiveConfig) {
600 ALOGV("[%" PRIu64 "] getActiveConfig --> %s", mId,
601 to_string(Error::BadConfig).c_str());
602 return Error::BadConfig;
603 }
604 auto configId = mActiveConfig->getId();
605 ALOGV("[%" PRIu64 "] getActiveConfig --> %u", mId, configId);
606 *outConfig = configId;
607 return Error::None;
608}
609
610Error HWC2On1Adapter::Display::getAttribute(hwc2_config_t configId,
611 Attribute attribute, int32_t* outValue) {
612 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
613
614 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
615 ALOGV("[%" PRIu64 "] getAttribute failed: bad config (%u)", mId,
616 configId);
617 return Error::BadConfig;
618 }
619 *outValue = mConfigs[configId]->getAttribute(attribute);
620 ALOGV("[%" PRIu64 "] getAttribute(%u, %s) --> %d", mId, configId,
621 to_string(attribute).c_str(), *outValue);
622 return Error::None;
623}
624
625Error HWC2On1Adapter::Display::getChangedCompositionTypes(
626 uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) {
627 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
628
629 if (!mChanges) {
630 ALOGE("[%" PRIu64 "] getChangedCompositionTypes failed: not validated",
631 mId);
632 return Error::NotValidated;
633 }
634
635 if ((outLayers == nullptr) || (outTypes == nullptr)) {
636 *outNumElements = mChanges->getTypeChanges().size();
637 return Error::None;
638 }
639
640 uint32_t numWritten = 0;
641 for (const auto& element : mChanges->getTypeChanges()) {
642 if (numWritten == *outNumElements) {
643 break;
644 }
645 auto layerId = element.first;
646 auto intType = static_cast<int32_t>(element.second);
647 ALOGV("Adding %" PRIu64 " %s", layerId,
648 to_string(element.second).c_str());
649 outLayers[numWritten] = layerId;
650 outTypes[numWritten] = intType;
651 ++numWritten;
652 }
653 *outNumElements = numWritten;
654
655 return Error::None;
656}
657
658Error HWC2On1Adapter::Display::getColorModes(uint32_t* outNumModes,
659 int32_t* outModes) {
660 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
661
662 if (!outModes) {
663 *outNumModes = mColorModes.size();
664 return Error::None;
665 }
666 uint32_t numModes = std::min(*outNumModes,
667 static_cast<uint32_t>(mColorModes.size()));
668 std::copy_n(mColorModes.cbegin(), numModes, outModes);
669 *outNumModes = numModes;
670 return Error::None;
671}
672
673Error HWC2On1Adapter::Display::getConfigs(uint32_t* outNumConfigs,
674 hwc2_config_t* outConfigs) {
675 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
676
677 if (!outConfigs) {
678 *outNumConfigs = mConfigs.size();
679 return Error::None;
680 }
681 uint32_t numWritten = 0;
682 for (const auto& config : mConfigs) {
683 if (numWritten == *outNumConfigs) {
684 break;
685 }
686 outConfigs[numWritten] = config->getId();
687 ++numWritten;
688 }
689 *outNumConfigs = numWritten;
690 return Error::None;
691}
692
693Error HWC2On1Adapter::Display::getDozeSupport(int32_t* outSupport) {
694 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
695
696 if (mDevice.mHwc1MinorVersion < 4 || mHwc1Id != 0) {
697 *outSupport = 0;
698 } else {
699 *outSupport = 1;
700 }
701 return Error::None;
702}
703
704Error HWC2On1Adapter::Display::getHdrCapabilities(uint32_t* outNumTypes,
705 int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
706 float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
707 // This isn't supported on HWC1, so per the HWC2 header, return numTypes = 0
708 *outNumTypes = 0;
709 return Error::None;
710}
711
712Error HWC2On1Adapter::Display::getName(uint32_t* outSize, char* outName) {
713 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
714
715 if (!outName) {
716 *outSize = mName.size();
717 return Error::None;
718 }
719 auto numCopied = mName.copy(outName, *outSize);
720 *outSize = numCopied;
721 return Error::None;
722}
723
724Error HWC2On1Adapter::Display::getReleaseFences(uint32_t* outNumElements,
725 hwc2_layer_t* outLayers, int32_t* outFences) {
726 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
727
728 uint32_t numWritten = 0;
729 bool outputsNonNull = (outLayers != nullptr) && (outFences != nullptr);
730 for (const auto& layer : mLayers) {
731 if (outputsNonNull && (numWritten == *outNumElements)) {
732 break;
733 }
734
735 auto releaseFence = layer->getReleaseFence();
736 if (releaseFence != MiniFence::NO_FENCE) {
737 if (outputsNonNull) {
738 outLayers[numWritten] = layer->getId();
739 outFences[numWritten] = releaseFence->dup();
740 }
741 ++numWritten;
742 }
743 }
744 *outNumElements = numWritten;
745
746 return Error::None;
747}
748
749Error HWC2On1Adapter::Display::getRequests(int32_t* outDisplayRequests,
750 uint32_t* outNumElements, hwc2_layer_t* outLayers,
751 int32_t* outLayerRequests) {
752 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
753
754 if (!mChanges) {
755 return Error::NotValidated;
756 }
757
758 if (outLayers == nullptr || outLayerRequests == nullptr) {
759 *outNumElements = mChanges->getNumLayerRequests();
760 return Error::None;
761 }
762
763 // Display requests (HWC2::DisplayRequest) are not supported by hwc1:
764 // A hwc1 has always zero requests for the client.
765 *outDisplayRequests = 0;
766
767 uint32_t numWritten = 0;
768 for (const auto& request : mChanges->getLayerRequests()) {
769 if (numWritten == *outNumElements) {
770 break;
771 }
772 outLayers[numWritten] = request.first;
773 outLayerRequests[numWritten] = static_cast<int32_t>(request.second);
774 ++numWritten;
775 }
776
777 return Error::None;
778}
779
780Error HWC2On1Adapter::Display::getType(int32_t* outType) {
781 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
782
783 *outType = static_cast<int32_t>(mType);
784 return Error::None;
785}
786
787Error HWC2On1Adapter::Display::present(int32_t* outRetireFence) {
788 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
789
790 if (mChanges) {
791 Error error = mDevice.setAllDisplays();
792 if (error != Error::None) {
793 ALOGE("[%" PRIu64 "] present: setAllDisplaysFailed (%s)", mId,
794 to_string(error).c_str());
795 return error;
796 }
797 }
798
799 *outRetireFence = mRetireFence.get()->dup();
800 ALOGV("[%" PRIu64 "] present returning retire fence %d", mId,
801 *outRetireFence);
802
803 return Error::None;
804}
805
806Error HWC2On1Adapter::Display::setActiveConfig(hwc2_config_t configId) {
807 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
808
809 auto config = getConfig(configId);
810 if (!config) {
811 return Error::BadConfig;
812 }
813 if (config == mActiveConfig) {
814 return Error::None;
815 }
816
817 if (mDevice.mHwc1MinorVersion >= 4) {
818 uint32_t hwc1Id = 0;
819 auto error = config->getHwc1IdForColorMode(mActiveColorMode, &hwc1Id);
820 if (error != Error::None) {
821 return error;
822 }
823
824 int intError = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
825 mHwc1Id, static_cast<int>(hwc1Id));
826 if (intError != 0) {
827 ALOGE("setActiveConfig: Failed to set active config on HWC1 (%d)",
828 intError);
829 return Error::BadConfig;
830 }
831 mActiveConfig = config;
832 }
833
834 return Error::None;
835}
836
837Error HWC2On1Adapter::Display::setClientTarget(buffer_handle_t target,
838 int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
839 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
840
841 ALOGV("[%" PRIu64 "] setClientTarget(%p, %d)", mId, target, acquireFence);
842 mClientTarget.setBuffer(target);
843 mClientTarget.setFence(acquireFence);
844 // dataspace and damage can't be used by HWC1, so ignore them
845 return Error::None;
846}
847
848Error HWC2On1Adapter::Display::setColorMode(android_color_mode_t mode) {
849 std::unique_lock<std::recursive_mutex> lock (mStateMutex);
850
851 ALOGV("[%" PRIu64 "] setColorMode(%d)", mId, mode);
852
853 if (mode == mActiveColorMode) {
854 return Error::None;
855 }
856 if (mColorModes.count(mode) == 0) {
857 ALOGE("[%" PRIu64 "] Mode %d not found in mColorModes", mId, mode);
858 return Error::Unsupported;
859 }
860
861 uint32_t hwc1Config = 0;
862 auto error = mActiveConfig->getHwc1IdForColorMode(mode, &hwc1Config);
863 if (error != Error::None) {
864 return error;
865 }
866
867 ALOGV("[%" PRIu64 "] Setting HWC1 config %u", mId, hwc1Config);
868 int intError = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
869 mHwc1Id, hwc1Config);
870 if (intError != 0) {
871 ALOGE("[%" PRIu64 "] Failed to set HWC1 config (%d)", mId, intError);
872 return Error::Unsupported;
873 }
874
875 mActiveColorMode = mode;
876 return Error::None;
877}
878
879Error HWC2On1Adapter::Display::setColorTransform(android_color_transform_t hint) {
880 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
881
882 ALOGV("%" PRIu64 "] setColorTransform(%d)", mId,
883 static_cast<int32_t>(hint));
884 mHasColorTransform = (hint != HAL_COLOR_TRANSFORM_IDENTITY);
885 return Error::None;
886}
887
888Error HWC2On1Adapter::Display::setOutputBuffer(buffer_handle_t buffer,
889 int32_t releaseFence) {
890 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
891
892 ALOGV("[%" PRIu64 "] setOutputBuffer(%p, %d)", mId, buffer, releaseFence);
893 mOutputBuffer.setBuffer(buffer);
894 mOutputBuffer.setFence(releaseFence);
895 return Error::None;
896}
897
898static bool isValid(PowerMode mode) {
899 switch (mode) {
900 case PowerMode::Off: // Fall-through
901 case PowerMode::DozeSuspend: // Fall-through
902 case PowerMode::Doze: // Fall-through
903 case PowerMode::On: return true;
904 }
905}
906
907static int getHwc1PowerMode(PowerMode mode) {
908 switch (mode) {
909 case PowerMode::Off: return HWC_POWER_MODE_OFF;
910 case PowerMode::DozeSuspend: return HWC_POWER_MODE_DOZE_SUSPEND;
911 case PowerMode::Doze: return HWC_POWER_MODE_DOZE;
912 case PowerMode::On: return HWC_POWER_MODE_NORMAL;
913 }
914}
915
916Error HWC2On1Adapter::Display::setPowerMode(PowerMode mode) {
917 if (!isValid(mode)) {
918 return Error::BadParameter;
919 }
920 if (mode == mPowerMode) {
921 return Error::None;
922 }
923
924 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
925
926 int error = 0;
927 if (mDevice.mHwc1MinorVersion < 4) {
928 error = mDevice.mHwc1Device->blank(mDevice.mHwc1Device, mHwc1Id,
929 mode == PowerMode::Off);
930 } else {
931 error = mDevice.mHwc1Device->setPowerMode(mDevice.mHwc1Device,
932 mHwc1Id, getHwc1PowerMode(mode));
933 }
934 ALOGE_IF(error != 0, "setPowerMode: Failed to set power mode on HWC1 (%d)",
935 error);
936
937 ALOGV("[%" PRIu64 "] setPowerMode(%s)", mId, to_string(mode).c_str());
938 mPowerMode = mode;
939 return Error::None;
940}
941
942static bool isValid(Vsync enable) {
943 switch (enable) {
944 case Vsync::Enable: // Fall-through
945 case Vsync::Disable: return true;
946 case Vsync::Invalid: return false;
947 }
948}
949
950Error HWC2On1Adapter::Display::setVsyncEnabled(Vsync enable) {
951 if (!isValid(enable)) {
952 return Error::BadParameter;
953 }
954 if (enable == mVsyncEnabled) {
955 return Error::None;
956 }
957
958 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
959
960 int error = mDevice.mHwc1Device->eventControl(mDevice.mHwc1Device,
961 mHwc1Id, HWC_EVENT_VSYNC, enable == Vsync::Enable);
962 ALOGE_IF(error != 0, "setVsyncEnabled: Failed to set vsync on HWC1 (%d)",
963 error);
964
965 mVsyncEnabled = enable;
966 return Error::None;
967}
968
969Error HWC2On1Adapter::Display::validate(uint32_t* outNumTypes,
970 uint32_t* outNumRequests) {
971 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
972
973 if (!mChanges) {
974 if (!mDevice.prepareAllDisplays()) {
975 return Error::BadDisplay;
976 }
977 } else {
978 ALOGE("Validate was called more than once!");
979 }
980
981 *outNumTypes = mChanges->getNumTypes();
982 *outNumRequests = mChanges->getNumLayerRequests();
983 ALOGV("[%" PRIu64 "] validate --> %u types, %u requests", mId, *outNumTypes,
984 *outNumRequests);
985 for (auto request : mChanges->getTypeChanges()) {
986 ALOGV("Layer %" PRIu64 " --> %s", request.first,
987 to_string(request.second).c_str());
988 }
989 return *outNumTypes > 0 ? Error::HasChanges : Error::None;
990}
991
992Error HWC2On1Adapter::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
993 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
994
995 const auto mapLayer = mDevice.mLayers.find(layerId);
996 if (mapLayer == mDevice.mLayers.end()) {
997 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer", mId);
998 return Error::BadLayer;
999 }
1000
1001 const auto layer = mapLayer->second;
1002 const auto zRange = mLayers.equal_range(layer);
1003 bool layerOnDisplay = false;
1004 for (auto current = zRange.first; current != zRange.second; ++current) {
1005 if (**current == *layer) {
1006 if ((*current)->getZ() == z) {
1007 // Don't change anything if the Z hasn't changed
1008 return Error::None;
1009 }
1010 current = mLayers.erase(current);
1011 layerOnDisplay = true;
1012 break;
1013 }
1014 }
1015
1016 if (!layerOnDisplay) {
1017 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display",
1018 mId);
1019 return Error::BadLayer;
1020 }
1021
1022 layer->setZ(z);
1023 mLayers.emplace(std::move(layer));
1024 markGeometryChanged();
1025
1026 return Error::None;
1027}
1028
1029Error HWC2On1Adapter::Display::getClientTargetSupport(uint32_t width, uint32_t height,
1030 int32_t format, int32_t dataspace){
1031 if (mActiveConfig == nullptr) {
1032 return Error::Unsupported;
1033 }
1034
1035 if (width == mActiveConfig->getAttribute(Attribute::Width) &&
1036 height == mActiveConfig->getAttribute(Attribute::Height) &&
1037 format == HAL_PIXEL_FORMAT_RGBA_8888 &&
1038 dataspace == HAL_DATASPACE_UNKNOWN) {
1039 return Error::None;
1040 }
1041
1042 return Error::Unsupported;
1043}
1044
1045static constexpr uint32_t ATTRIBUTES_WITH_COLOR[] = {
1046 HWC_DISPLAY_VSYNC_PERIOD,
1047 HWC_DISPLAY_WIDTH,
1048 HWC_DISPLAY_HEIGHT,
1049 HWC_DISPLAY_DPI_X,
1050 HWC_DISPLAY_DPI_Y,
1051 HWC_DISPLAY_COLOR_TRANSFORM,
1052 HWC_DISPLAY_NO_ATTRIBUTE,
1053};
1054
1055static constexpr uint32_t ATTRIBUTES_WITHOUT_COLOR[] = {
1056 HWC_DISPLAY_VSYNC_PERIOD,
1057 HWC_DISPLAY_WIDTH,
1058 HWC_DISPLAY_HEIGHT,
1059 HWC_DISPLAY_DPI_X,
1060 HWC_DISPLAY_DPI_Y,
1061 HWC_DISPLAY_NO_ATTRIBUTE,
1062};
1063
1064static constexpr size_t NUM_ATTRIBUTES_WITH_COLOR =
1065 sizeof(ATTRIBUTES_WITH_COLOR) / sizeof(uint32_t);
1066static_assert(sizeof(ATTRIBUTES_WITH_COLOR) > sizeof(ATTRIBUTES_WITHOUT_COLOR),
1067 "Attribute tables have unexpected sizes");
1068
1069static constexpr uint32_t ATTRIBUTE_MAP_WITH_COLOR[] = {
1070 6, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1071 0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1072 1, // HWC_DISPLAY_WIDTH = 2,
1073 2, // HWC_DISPLAY_HEIGHT = 3,
1074 3, // HWC_DISPLAY_DPI_X = 4,
1075 4, // HWC_DISPLAY_DPI_Y = 5,
1076 5, // HWC_DISPLAY_COLOR_TRANSFORM = 6,
1077};
1078
1079static constexpr uint32_t ATTRIBUTE_MAP_WITHOUT_COLOR[] = {
1080 5, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1081 0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1082 1, // HWC_DISPLAY_WIDTH = 2,
1083 2, // HWC_DISPLAY_HEIGHT = 3,
1084 3, // HWC_DISPLAY_DPI_X = 4,
1085 4, // HWC_DISPLAY_DPI_Y = 5,
1086};
1087
1088template <uint32_t attribute>
1089static constexpr bool attributesMatch()
1090{
1091 bool match = (attribute ==
1092 ATTRIBUTES_WITH_COLOR[ATTRIBUTE_MAP_WITH_COLOR[attribute]]);
1093 if (attribute == HWC_DISPLAY_COLOR_TRANSFORM) {
1094 return match;
1095 }
1096
1097 return match && (attribute ==
1098 ATTRIBUTES_WITHOUT_COLOR[ATTRIBUTE_MAP_WITHOUT_COLOR[attribute]]);
1099}
1100static_assert(attributesMatch<HWC_DISPLAY_VSYNC_PERIOD>(),
1101 "Tables out of sync");
1102static_assert(attributesMatch<HWC_DISPLAY_WIDTH>(), "Tables out of sync");
1103static_assert(attributesMatch<HWC_DISPLAY_HEIGHT>(), "Tables out of sync");
1104static_assert(attributesMatch<HWC_DISPLAY_DPI_X>(), "Tables out of sync");
1105static_assert(attributesMatch<HWC_DISPLAY_DPI_Y>(), "Tables out of sync");
1106static_assert(attributesMatch<HWC_DISPLAY_COLOR_TRANSFORM>(),
1107 "Tables out of sync");
1108
1109void HWC2On1Adapter::Display::populateConfigs() {
1110 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1111
1112 ALOGV("[%" PRIu64 "] populateConfigs", mId);
1113
1114 if (mHwc1Id == -1) {
1115 ALOGE("populateConfigs: HWC1 ID not set");
1116 return;
1117 }
1118
1119 const size_t MAX_NUM_CONFIGS = 128;
1120 uint32_t configs[MAX_NUM_CONFIGS] = {};
1121 size_t numConfigs = MAX_NUM_CONFIGS;
1122 mDevice.mHwc1Device->getDisplayConfigs(mDevice.mHwc1Device, mHwc1Id,
1123 configs, &numConfigs);
1124
1125 for (size_t c = 0; c < numConfigs; ++c) {
1126 uint32_t hwc1ConfigId = configs[c];
1127 auto newConfig = std::make_shared<Config>(*this);
1128
1129 int32_t values[NUM_ATTRIBUTES_WITH_COLOR] = {};
1130 bool hasColor = true;
1131 auto result = mDevice.mHwc1Device->getDisplayAttributes(
1132 mDevice.mHwc1Device, mHwc1Id, hwc1ConfigId,
1133 ATTRIBUTES_WITH_COLOR, values);
1134 if (result != 0) {
1135 mDevice.mHwc1Device->getDisplayAttributes(mDevice.mHwc1Device,
1136 mHwc1Id, hwc1ConfigId, ATTRIBUTES_WITHOUT_COLOR, values);
1137 hasColor = false;
1138 }
1139
1140 auto attributeMap = hasColor ?
1141 ATTRIBUTE_MAP_WITH_COLOR : ATTRIBUTE_MAP_WITHOUT_COLOR;
1142
1143 newConfig->setAttribute(Attribute::VsyncPeriod,
1144 values[attributeMap[HWC_DISPLAY_VSYNC_PERIOD]]);
1145 newConfig->setAttribute(Attribute::Width,
1146 values[attributeMap[HWC_DISPLAY_WIDTH]]);
1147 newConfig->setAttribute(Attribute::Height,
1148 values[attributeMap[HWC_DISPLAY_HEIGHT]]);
1149 newConfig->setAttribute(Attribute::DpiX,
1150 values[attributeMap[HWC_DISPLAY_DPI_X]]);
1151 newConfig->setAttribute(Attribute::DpiY,
1152 values[attributeMap[HWC_DISPLAY_DPI_Y]]);
1153 if (hasColor) {
1154 // In HWC1, color modes are referred to as color transforms. To avoid confusion with
1155 // the HWC2 concept of color transforms, we internally refer to them as color modes for
1156 // both HWC1 and 2.
1157 newConfig->setAttribute(ColorMode,
1158 values[attributeMap[HWC_DISPLAY_COLOR_TRANSFORM]]);
1159 }
1160
1161 // We can only do this after attempting to read the color mode
1162 newConfig->setHwc1Id(hwc1ConfigId);
1163
1164 for (auto& existingConfig : mConfigs) {
1165 if (existingConfig->merge(*newConfig)) {
1166 ALOGV("Merged config %d with existing config %u: %s",
1167 hwc1ConfigId, existingConfig->getId(),
1168 existingConfig->toString().c_str());
1169 newConfig.reset();
1170 break;
1171 }
1172 }
1173
1174 // If it wasn't merged with any existing config, add it to the end
1175 if (newConfig) {
1176 newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
1177 ALOGV("Found new config %u: %s", newConfig->getId(),
1178 newConfig->toString().c_str());
1179 mConfigs.emplace_back(std::move(newConfig));
1180 }
1181 }
1182
1183 initializeActiveConfig();
1184 populateColorModes();
1185}
1186
1187void HWC2On1Adapter::Display::populateConfigs(uint32_t width, uint32_t height) {
1188 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1189
1190 mConfigs.emplace_back(std::make_shared<Config>(*this));
1191 auto& config = mConfigs[0];
1192
1193 config->setAttribute(Attribute::Width, static_cast<int32_t>(width));
1194 config->setAttribute(Attribute::Height, static_cast<int32_t>(height));
1195 config->setHwc1Id(0);
1196 config->setId(0);
1197 mActiveConfig = config;
1198}
1199
1200bool HWC2On1Adapter::Display::prepare() {
1201 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1202
1203 // Only prepare display contents for displays HWC1 knows about
1204 if (mHwc1Id == -1) {
1205 return true;
1206 }
1207
1208 // It doesn't make sense to prepare a display for which there is no active
1209 // config, so return early
1210 if (!mActiveConfig) {
1211 ALOGE("[%" PRIu64 "] Attempted to prepare, but no config active", mId);
1212 return false;
1213 }
1214
1215 allocateRequestedContents();
1216 assignHwc1LayerIds();
1217
1218 mHwc1RequestedContents->retireFenceFd = -1;
1219 mHwc1RequestedContents->flags = 0;
1220 if (mGeometryChanged) {
1221 mHwc1RequestedContents->flags |= HWC_GEOMETRY_CHANGED;
1222 }
1223 mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer();
1224 mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence();
1225
1226 // +1 is for framebuffer target layer.
1227 mHwc1RequestedContents->numHwLayers = mLayers.size() + 1;
1228 for (auto& layer : mLayers) {
1229 auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
1230 hwc1Layer.releaseFenceFd = -1;
1231 hwc1Layer.acquireFenceFd = -1;
1232 ALOGV("Applying states for layer %" PRIu64 " ", layer->getId());
1233 layer->applyState(hwc1Layer);
1234 }
1235
1236 prepareFramebufferTarget();
1237
1238 resetGeometryMarker();
1239
1240 return true;
1241}
1242
1243void HWC2On1Adapter::Display::generateChanges() {
1244 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1245
1246 mChanges.reset(new Changes);
1247
1248 size_t numLayers = mHwc1RequestedContents->numHwLayers;
1249 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1250 const auto& receivedLayer = mHwc1RequestedContents->hwLayers[hwc1Id];
1251 if (mHwc1LayerMap.count(hwc1Id) == 0) {
1252 ALOGE_IF(receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET,
1253 "generateChanges: HWC1 layer %zd doesn't have a"
1254 " matching HWC2 layer, and isn't the framebuffer target",
1255 hwc1Id);
1256 continue;
1257 }
1258
1259 Layer& layer = *mHwc1LayerMap[hwc1Id];
1260 updateTypeChanges(receivedLayer, layer);
1261 updateLayerRequests(receivedLayer, layer);
1262 }
1263}
1264
1265bool HWC2On1Adapter::Display::hasChanges() const {
1266 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1267 return mChanges != nullptr;
1268}
1269
1270Error HWC2On1Adapter::Display::set(hwc_display_contents_1& hwcContents) {
1271 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1272
1273 if (!mChanges || (mChanges->getNumTypes() > 0)) {
1274 ALOGE("[%" PRIu64 "] set failed: not validated", mId);
1275 return Error::NotValidated;
1276 }
1277
1278 // Set up the client/framebuffer target
1279 auto numLayers = hwcContents.numHwLayers;
1280
1281 // Close acquire fences on FRAMEBUFFER layers, since they will not be used
1282 // by HWC
1283 for (size_t l = 0; l < numLayers - 1; ++l) {
1284 auto& layer = hwcContents.hwLayers[l];
1285 if (layer.compositionType == HWC_FRAMEBUFFER) {
1286 ALOGV("Closing fence %d for layer %zd", layer.acquireFenceFd, l);
1287 close(layer.acquireFenceFd);
1288 layer.acquireFenceFd = -1;
1289 }
1290 }
1291
1292 auto& clientTargetLayer = hwcContents.hwLayers[numLayers - 1];
1293 if (clientTargetLayer.compositionType == HWC_FRAMEBUFFER_TARGET) {
1294 clientTargetLayer.handle = mClientTarget.getBuffer();
1295 clientTargetLayer.acquireFenceFd = mClientTarget.getFence();
1296 } else {
1297 ALOGE("[%" PRIu64 "] set: last HWC layer wasn't FRAMEBUFFER_TARGET",
1298 mId);
1299 }
1300
1301 mChanges.reset();
1302
1303 return Error::None;
1304}
1305
1306void HWC2On1Adapter::Display::addRetireFence(int fenceFd) {
1307 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1308 mRetireFence.add(fenceFd);
1309}
1310
1311void HWC2On1Adapter::Display::addReleaseFences(
1312 const hwc_display_contents_1_t& hwcContents) {
1313 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1314
1315 size_t numLayers = hwcContents.numHwLayers;
1316 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1317 const auto& receivedLayer = hwcContents.hwLayers[hwc1Id];
1318 if (mHwc1LayerMap.count(hwc1Id) == 0) {
1319 if (receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET) {
1320 ALOGE("addReleaseFences: HWC1 layer %zd doesn't have a"
1321 " matching HWC2 layer, and isn't the framebuffer"
1322 " target", hwc1Id);
1323 }
1324 // Close the framebuffer target release fence since we will use the
1325 // display retire fence instead
1326 if (receivedLayer.releaseFenceFd != -1) {
1327 close(receivedLayer.releaseFenceFd);
1328 }
1329 continue;
1330 }
1331
1332 Layer& layer = *mHwc1LayerMap[hwc1Id];
1333 ALOGV("Adding release fence %d to layer %" PRIu64,
1334 receivedLayer.releaseFenceFd, layer.getId());
1335 layer.addReleaseFence(receivedLayer.releaseFenceFd);
1336 }
1337}
1338
1339bool HWC2On1Adapter::Display::hasColorTransform() const {
1340 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1341 return mHasColorTransform;
1342}
1343
1344static std::string hwc1CompositionString(int32_t type) {
1345 switch (type) {
1346 case HWC_FRAMEBUFFER: return "Framebuffer";
1347 case HWC_OVERLAY: return "Overlay";
1348 case HWC_BACKGROUND: return "Background";
1349 case HWC_FRAMEBUFFER_TARGET: return "FramebufferTarget";
1350 case HWC_SIDEBAND: return "Sideband";
1351 case HWC_CURSOR_OVERLAY: return "CursorOverlay";
1352 default:
1353 return std::string("Unknown (") + std::to_string(type) + ")";
1354 }
1355}
1356
1357static std::string hwc1TransformString(int32_t transform) {
1358 switch (transform) {
1359 case 0: return "None";
1360 case HWC_TRANSFORM_FLIP_H: return "FlipH";
1361 case HWC_TRANSFORM_FLIP_V: return "FlipV";
1362 case HWC_TRANSFORM_ROT_90: return "Rotate90";
1363 case HWC_TRANSFORM_ROT_180: return "Rotate180";
1364 case HWC_TRANSFORM_ROT_270: return "Rotate270";
1365 case HWC_TRANSFORM_FLIP_H_ROT_90: return "FlipHRotate90";
1366 case HWC_TRANSFORM_FLIP_V_ROT_90: return "FlipVRotate90";
1367 default:
1368 return std::string("Unknown (") + std::to_string(transform) + ")";
1369 }
1370}
1371
1372static std::string hwc1BlendModeString(int32_t mode) {
1373 switch (mode) {
1374 case HWC_BLENDING_NONE: return "None";
1375 case HWC_BLENDING_PREMULT: return "Premultiplied";
1376 case HWC_BLENDING_COVERAGE: return "Coverage";
1377 default:
1378 return std::string("Unknown (") + std::to_string(mode) + ")";
1379 }
1380}
1381
1382static std::string rectString(hwc_rect_t rect) {
1383 std::stringstream output;
1384 output << "[" << rect.left << ", " << rect.top << ", ";
1385 output << rect.right << ", " << rect.bottom << "]";
1386 return output.str();
1387}
1388
1389static std::string approximateFloatString(float f) {
1390 if (static_cast<int32_t>(f) == f) {
1391 return std::to_string(static_cast<int32_t>(f));
1392 }
1393 int32_t truncated = static_cast<int32_t>(f * 10);
1394 bool approximate = (static_cast<float>(truncated) != f * 10);
1395 const size_t BUFFER_SIZE = 32;
1396 char buffer[BUFFER_SIZE] = {};
1397 auto bytesWritten = snprintf(buffer, BUFFER_SIZE,
1398 "%s%.1f", approximate ? "~" : "", f);
1399 return std::string(buffer, bytesWritten);
1400}
1401
1402static std::string frectString(hwc_frect_t frect) {
1403 std::stringstream output;
1404 output << "[" << approximateFloatString(frect.left) << ", ";
1405 output << approximateFloatString(frect.top) << ", ";
1406 output << approximateFloatString(frect.right) << ", ";
1407 output << approximateFloatString(frect.bottom) << "]";
1408 return output.str();
1409}
1410
1411static std::string colorString(hwc_color_t color) {
1412 std::stringstream output;
1413 output << "RGBA [";
1414 output << static_cast<int32_t>(color.r) << ", ";
1415 output << static_cast<int32_t>(color.g) << ", ";
1416 output << static_cast<int32_t>(color.b) << ", ";
1417 output << static_cast<int32_t>(color.a) << "]";
1418 return output.str();
1419}
1420
1421static std::string alphaString(float f) {
1422 const size_t BUFFER_SIZE = 8;
1423 char buffer[BUFFER_SIZE] = {};
1424 auto bytesWritten = snprintf(buffer, BUFFER_SIZE, "%.3f", f);
1425 return std::string(buffer, bytesWritten);
1426}
1427
1428static std::string to_string(const hwc_layer_1_t& hwcLayer,
1429 int32_t hwc1MinorVersion) {
1430 const char* fill = " ";
1431
1432 std::stringstream output;
1433
1434 output << " Composition: " <<
1435 hwc1CompositionString(hwcLayer.compositionType);
1436
1437 if (hwcLayer.compositionType == HWC_BACKGROUND) {
1438 output << " Color: " << colorString(hwcLayer.backgroundColor) << '\n';
1439 } else if (hwcLayer.compositionType == HWC_SIDEBAND) {
1440 output << " Stream: " << hwcLayer.sidebandStream << '\n';
1441 } else {
1442 output << " Buffer: " << hwcLayer.handle << "/" <<
1443 hwcLayer.acquireFenceFd << '\n';
1444 }
1445
1446 output << fill << "Display frame: " << rectString(hwcLayer.displayFrame) <<
1447 '\n';
1448
1449 output << fill << "Source crop: ";
1450 if (hwc1MinorVersion >= 3) {
1451 output << frectString(hwcLayer.sourceCropf) << '\n';
1452 } else {
1453 output << rectString(hwcLayer.sourceCropi) << '\n';
1454 }
1455
1456 output << fill << "Transform: " << hwc1TransformString(hwcLayer.transform);
1457 output << " Blend mode: " << hwc1BlendModeString(hwcLayer.blending);
1458 if (hwcLayer.planeAlpha != 0xFF) {
1459 output << " Alpha: " << alphaString(hwcLayer.planeAlpha / 255.0f);
1460 }
1461 output << '\n';
1462
1463 if (hwcLayer.hints != 0) {
1464 output << fill << "Hints:";
1465 if ((hwcLayer.hints & HWC_HINT_TRIPLE_BUFFER) != 0) {
1466 output << " TripleBuffer";
1467 }
1468 if ((hwcLayer.hints & HWC_HINT_CLEAR_FB) != 0) {
1469 output << " ClearFB";
1470 }
1471 output << '\n';
1472 }
1473
1474 if (hwcLayer.flags != 0) {
1475 output << fill << "Flags:";
1476 if ((hwcLayer.flags & HWC_SKIP_LAYER) != 0) {
1477 output << " SkipLayer";
1478 }
1479 if ((hwcLayer.flags & HWC_IS_CURSOR_LAYER) != 0) {
1480 output << " IsCursorLayer";
1481 }
1482 output << '\n';
1483 }
1484
1485 return output.str();
1486}
1487
1488static std::string to_string(const hwc_display_contents_1_t& hwcContents,
1489 int32_t hwc1MinorVersion) {
1490 const char* fill = " ";
1491
1492 std::stringstream output;
1493 output << fill << "Geometry changed: " <<
1494 ((hwcContents.flags & HWC_GEOMETRY_CHANGED) != 0 ? "Y\n" : "N\n");
1495
1496 output << fill << hwcContents.numHwLayers << " Layer" <<
1497 ((hwcContents.numHwLayers == 1) ? "\n" : "s\n");
1498 for (size_t layer = 0; layer < hwcContents.numHwLayers; ++layer) {
1499 output << fill << " Layer " << layer;
1500 output << to_string(hwcContents.hwLayers[layer], hwc1MinorVersion);
1501 }
1502
1503 if (hwcContents.outbuf != nullptr) {
1504 output << fill << "Output buffer: " << hwcContents.outbuf << "/" <<
1505 hwcContents.outbufAcquireFenceFd << '\n';
1506 }
1507
1508 return output.str();
1509}
1510
1511std::string HWC2On1Adapter::Display::dump() const {
1512 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1513
1514 std::stringstream output;
1515
1516 output << " Display " << mId << ": ";
1517 output << to_string(mType) << " ";
1518 output << "HWC1 ID: " << mHwc1Id << " ";
1519 output << "Power mode: " << to_string(mPowerMode) << " ";
1520 output << "Vsync: " << to_string(mVsyncEnabled) << '\n';
1521
1522 output << " Color modes [active]:";
1523 for (const auto& mode : mColorModes) {
1524 if (mode == mActiveColorMode) {
1525 output << " [" << mode << ']';
1526 } else {
1527 output << " " << mode;
1528 }
1529 }
1530 output << '\n';
1531
1532 output << " " << mConfigs.size() << " Config" <<
1533 (mConfigs.size() == 1 ? "" : "s") << " (* active)\n";
1534 for (const auto& config : mConfigs) {
1535 output << (config == mActiveConfig ? " * " : " ");
1536 output << config->toString(true) << '\n';
1537 }
1538
1539 output << " " << mLayers.size() << " Layer" <<
1540 (mLayers.size() == 1 ? "" : "s") << '\n';
1541 for (const auto& layer : mLayers) {
1542 output << layer->dump();
1543 }
1544
1545 output << " Client target: " << mClientTarget.getBuffer() << '\n';
1546
1547 if (mOutputBuffer.getBuffer() != nullptr) {
1548 output << " Output buffer: " << mOutputBuffer.getBuffer() << '\n';
1549 }
1550
1551 if (mHwc1RequestedContents) {
1552 output << " Last requested HWC1 state\n";
1553 output << to_string(*mHwc1RequestedContents, mDevice.mHwc1MinorVersion);
1554 }
1555
1556 return output.str();
1557}
1558
1559hwc_rect_t* HWC2On1Adapter::Display::GetRects(size_t numRects) {
1560 if (numRects == 0) {
1561 return nullptr;
1562 }
1563
1564 if (numRects > mNumAvailableRects) {
1565 // This should NEVER happen since we calculated how many rects the
1566 // display would need.
1567 ALOGE("Rect allocation failure! SF is likely to crash soon!");
1568 return nullptr;
1569
1570 }
1571 hwc_rect_t* rects = mNextAvailableRect;
1572 mNextAvailableRect += numRects;
1573 mNumAvailableRects -= numRects;
1574 return rects;
1575}
1576
1577hwc_display_contents_1* HWC2On1Adapter::Display::getDisplayContents() {
1578 return mHwc1RequestedContents.get();
1579}
1580
1581void HWC2On1Adapter::Display::Config::setAttribute(HWC2::Attribute attribute,
1582 int32_t value) {
1583 mAttributes[attribute] = value;
1584}
1585
1586int32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const {
1587 if (mAttributes.count(attribute) == 0) {
1588 return -1;
1589 }
1590 return mAttributes.at(attribute);
1591}
1592
1593void HWC2On1Adapter::Display::Config::setHwc1Id(uint32_t id) {
1594 android_color_mode_t colorMode = static_cast<android_color_mode_t>(getAttribute(ColorMode));
1595 mHwc1Ids.emplace(colorMode, id);
1596}
1597
1598bool HWC2On1Adapter::Display::Config::hasHwc1Id(uint32_t id) const {
1599 for (const auto& idPair : mHwc1Ids) {
1600 if (id == idPair.second) {
1601 return true;
1602 }
1603 }
1604 return false;
1605}
1606
1607Error HWC2On1Adapter::Display::Config::getColorModeForHwc1Id(
1608 uint32_t id, android_color_mode_t* outMode) const {
1609 for (const auto& idPair : mHwc1Ids) {
1610 if (id == idPair.second) {
1611 *outMode = idPair.first;
1612 return Error::None;
1613 }
1614 }
1615 ALOGE("Unable to find color mode for HWC ID %" PRIu32 " on config %u", id, mId);
1616 return Error::BadParameter;
1617}
1618
1619Error HWC2On1Adapter::Display::Config::getHwc1IdForColorMode(android_color_mode_t mode,
1620 uint32_t* outId) const {
1621 for (const auto& idPair : mHwc1Ids) {
1622 if (mode == idPair.first) {
1623 *outId = idPair.second;
1624 return Error::None;
1625 }
1626 }
1627 ALOGE("Unable to find HWC1 ID for color mode %d on config %u", mode, mId);
1628 return Error::BadParameter;
1629}
1630
1631bool HWC2On1Adapter::Display::Config::merge(const Config& other) {
1632 auto attributes = {HWC2::Attribute::Width, HWC2::Attribute::Height,
1633 HWC2::Attribute::VsyncPeriod, HWC2::Attribute::DpiX,
1634 HWC2::Attribute::DpiY};
1635 for (auto attribute : attributes) {
1636 if (getAttribute(attribute) != other.getAttribute(attribute)) {
1637 return false;
1638 }
1639 }
1640 android_color_mode_t otherColorMode =
1641 static_cast<android_color_mode_t>(other.getAttribute(ColorMode));
1642 if (mHwc1Ids.count(otherColorMode) != 0) {
1643 ALOGE("Attempted to merge two configs (%u and %u) which appear to be "
1644 "identical", mHwc1Ids.at(otherColorMode),
1645 other.mHwc1Ids.at(otherColorMode));
1646 return false;
1647 }
1648 mHwc1Ids.emplace(otherColorMode,
1649 other.mHwc1Ids.at(otherColorMode));
1650 return true;
1651}
1652
1653std::set<android_color_mode_t> HWC2On1Adapter::Display::Config::getColorModes() const {
1654 std::set<android_color_mode_t> colorModes;
1655 for (const auto& idPair : mHwc1Ids) {
1656 colorModes.emplace(idPair.first);
1657 }
1658 return colorModes;
1659}
1660
1661std::string HWC2On1Adapter::Display::Config::toString(bool splitLine) const {
1662 std::string output;
1663
1664 const size_t BUFFER_SIZE = 100;
1665 char buffer[BUFFER_SIZE] = {};
1666 auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
1667 "%u x %u", mAttributes.at(HWC2::Attribute::Width),
1668 mAttributes.at(HWC2::Attribute::Height));
1669 output.append(buffer, writtenBytes);
1670
1671 if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
1672 std::memset(buffer, 0, BUFFER_SIZE);
1673 writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
1674 1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
1675 output.append(buffer, writtenBytes);
1676 }
1677
1678 if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
1679 mAttributes.at(HWC2::Attribute::DpiX) != -1) {
1680 std::memset(buffer, 0, BUFFER_SIZE);
1681 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1682 ", DPI: %.1f x %.1f",
1683 mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
1684 mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
1685 output.append(buffer, writtenBytes);
1686 }
1687
1688 std::memset(buffer, 0, BUFFER_SIZE);
1689 if (splitLine) {
1690 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1691 "\n HWC1 ID/Color transform:");
1692 } else {
1693 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1694 ", HWC1 ID/Color transform:");
1695 }
1696 output.append(buffer, writtenBytes);
1697
1698
1699 for (const auto& id : mHwc1Ids) {
1700 android_color_mode_t colorMode = id.first;
1701 uint32_t hwc1Id = id.second;
1702 std::memset(buffer, 0, BUFFER_SIZE);
1703 if (colorMode == mDisplay.mActiveColorMode) {
1704 writtenBytes = snprintf(buffer, BUFFER_SIZE, " [%u/%d]", hwc1Id,
1705 colorMode);
1706 } else {
1707 writtenBytes = snprintf(buffer, BUFFER_SIZE, " %u/%d", hwc1Id,
1708 colorMode);
1709 }
1710 output.append(buffer, writtenBytes);
1711 }
1712
1713 return output;
1714}
1715
1716std::shared_ptr<const HWC2On1Adapter::Display::Config>
1717 HWC2On1Adapter::Display::getConfig(hwc2_config_t configId) const {
1718 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
1719 return nullptr;
1720 }
1721 return mConfigs[configId];
1722}
1723
1724void HWC2On1Adapter::Display::populateColorModes() {
1725 mColorModes = mConfigs[0]->getColorModes();
1726 for (const auto& config : mConfigs) {
1727 std::set<android_color_mode_t> intersection;
1728 auto configModes = config->getColorModes();
1729 std::set_intersection(mColorModes.cbegin(), mColorModes.cend(),
1730 configModes.cbegin(), configModes.cend(),
1731 std::inserter(intersection, intersection.begin()));
1732 std::swap(intersection, mColorModes);
1733 }
1734}
1735
1736void HWC2On1Adapter::Display::initializeActiveConfig() {
1737 if (mDevice.mHwc1Device->getActiveConfig == nullptr) {
1738 ALOGV("getActiveConfig is null, choosing config 0");
1739 mActiveConfig = mConfigs[0];
1740 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1741 return;
1742 }
1743
1744 auto activeConfig = mDevice.mHwc1Device->getActiveConfig(
1745 mDevice.mHwc1Device, mHwc1Id);
1746
1747 // Some devices startup without an activeConfig:
1748 // We need to set one ourselves.
1749 if (activeConfig == HWC_ERROR) {
1750 ALOGV("There is no active configuration: Picking the first one: 0.");
1751 const int defaultIndex = 0;
1752 mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device, mHwc1Id, defaultIndex);
1753 activeConfig = defaultIndex;
1754 }
1755
1756 for (const auto& config : mConfigs) {
1757 if (config->hasHwc1Id(activeConfig)) {
1758 ALOGE("Setting active config to %d for HWC1 config %u", config->getId(), activeConfig);
1759 mActiveConfig = config;
1760 if (config->getColorModeForHwc1Id(activeConfig, &mActiveColorMode) != Error::None) {
1761 // This should never happen since we checked for the config's presence before
1762 // setting it as active.
1763 ALOGE("Unable to find color mode for active HWC1 config %d", config->getId());
1764 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1765 }
1766 break;
1767 }
1768 }
1769 if (!mActiveConfig) {
1770 ALOGV("Unable to find active HWC1 config %u, defaulting to "
1771 "config 0", activeConfig);
1772 mActiveConfig = mConfigs[0];
1773 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1774 }
1775
1776
1777
1778
1779}
1780
1781void HWC2On1Adapter::Display::allocateRequestedContents() {
1782 // What needs to be allocated:
1783 // 1 hwc_display_contents_1_t
1784 // 1 hwc_layer_1_t for each layer
1785 // 1 hwc_rect_t for each layer's surfaceDamage
1786 // 1 hwc_rect_t for each layer's visibleRegion
1787 // 1 hwc_layer_1_t for the framebuffer
1788 // 1 hwc_rect_t for the framebuffer's visibleRegion
1789
1790 // Count # of surfaceDamage
1791 size_t numSurfaceDamages = 0;
1792 for (const auto& layer : mLayers) {
1793 numSurfaceDamages += layer->getNumSurfaceDamages();
1794 }
1795
1796 // Count # of visibleRegions (start at 1 for mandatory framebuffer target
1797 // region)
1798 size_t numVisibleRegion = 1;
1799 for (const auto& layer : mLayers) {
1800 numVisibleRegion += layer->getNumVisibleRegions();
1801 }
1802
1803 size_t numRects = numVisibleRegion + numSurfaceDamages;
1804 auto numLayers = mLayers.size() + 1;
1805 size_t size = sizeof(hwc_display_contents_1_t) +
1806 sizeof(hwc_layer_1_t) * numLayers +
1807 sizeof(hwc_rect_t) * numRects;
1808 auto contents = static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1));
1809 mHwc1RequestedContents.reset(contents);
1810 mNextAvailableRect = reinterpret_cast<hwc_rect_t*>(&contents->hwLayers[numLayers]);
1811 mNumAvailableRects = numRects;
1812}
1813
1814void HWC2On1Adapter::Display::assignHwc1LayerIds() {
1815 mHwc1LayerMap.clear();
1816 size_t nextHwc1Id = 0;
1817 for (auto& layer : mLayers) {
1818 mHwc1LayerMap[nextHwc1Id] = layer;
1819 layer->setHwc1Id(nextHwc1Id++);
1820 }
1821}
1822
1823void HWC2On1Adapter::Display::updateTypeChanges(const hwc_layer_1_t& hwc1Layer,
1824 const Layer& layer) {
1825 auto layerId = layer.getId();
1826 switch (hwc1Layer.compositionType) {
1827 case HWC_FRAMEBUFFER:
1828 if (layer.getCompositionType() != Composition::Client) {
1829 mChanges->addTypeChange(layerId, Composition::Client);
1830 }
1831 break;
1832 case HWC_OVERLAY:
1833 if (layer.getCompositionType() != Composition::Device) {
1834 mChanges->addTypeChange(layerId, Composition::Device);
1835 }
1836 break;
1837 case HWC_BACKGROUND:
1838 ALOGE_IF(layer.getCompositionType() != Composition::SolidColor,
1839 "updateTypeChanges: HWC1 requested BACKGROUND, but HWC2"
1840 " wasn't expecting SolidColor");
1841 break;
1842 case HWC_FRAMEBUFFER_TARGET:
1843 // Do nothing, since it shouldn't be modified by HWC1
1844 break;
1845 case HWC_SIDEBAND:
1846 ALOGE_IF(layer.getCompositionType() != Composition::Sideband,
1847 "updateTypeChanges: HWC1 requested SIDEBAND, but HWC2"
1848 " wasn't expecting Sideband");
1849 break;
1850 case HWC_CURSOR_OVERLAY:
1851 ALOGE_IF(layer.getCompositionType() != Composition::Cursor,
1852 "updateTypeChanges: HWC1 requested CURSOR_OVERLAY, but"
1853 " HWC2 wasn't expecting Cursor");
1854 break;
1855 }
1856}
1857
1858void HWC2On1Adapter::Display::updateLayerRequests(
1859 const hwc_layer_1_t& hwc1Layer, const Layer& layer) {
1860 if ((hwc1Layer.hints & HWC_HINT_CLEAR_FB) != 0) {
1861 mChanges->addLayerRequest(layer.getId(),
1862 LayerRequest::ClearClientTarget);
1863 }
1864}
1865
1866void HWC2On1Adapter::Display::prepareFramebufferTarget() {
1867 // We check that mActiveConfig is valid in Display::prepare
1868 int32_t width = mActiveConfig->getAttribute(Attribute::Width);
1869 int32_t height = mActiveConfig->getAttribute(Attribute::Height);
1870
1871 auto& hwc1Target = mHwc1RequestedContents->hwLayers[mLayers.size()];
1872 hwc1Target.compositionType = HWC_FRAMEBUFFER_TARGET;
1873 hwc1Target.releaseFenceFd = -1;
1874 hwc1Target.hints = 0;
1875 hwc1Target.flags = 0;
1876 hwc1Target.transform = 0;
1877 hwc1Target.blending = HWC_BLENDING_PREMULT;
1878 if (mDevice.getHwc1MinorVersion() < 3) {
1879 hwc1Target.sourceCropi = {0, 0, width, height};
1880 } else {
1881 hwc1Target.sourceCropf = {0.0f, 0.0f, static_cast<float>(width),
1882 static_cast<float>(height)};
1883 }
1884 hwc1Target.displayFrame = {0, 0, width, height};
1885 hwc1Target.planeAlpha = 255;
1886
1887 hwc1Target.visibleRegionScreen.numRects = 1;
1888 hwc_rect_t* rects = GetRects(1);
1889 rects[0].left = 0;
1890 rects[0].top = 0;
1891 rects[0].right = width;
1892 rects[0].bottom = height;
1893 hwc1Target.visibleRegionScreen.rects = rects;
1894
1895 // We will set this to the correct value in set
1896 hwc1Target.acquireFenceFd = -1;
1897}
1898
1899// Layer functions
1900
1901std::atomic<hwc2_layer_t> HWC2On1Adapter::Layer::sNextId(1);
1902
1903HWC2On1Adapter::Layer::Layer(Display& display)
1904 : mId(sNextId++),
1905 mDisplay(display),
1906 mBuffer(),
1907 mSurfaceDamage(),
1908 mBlendMode(BlendMode::None),
1909 mColor({0, 0, 0, 0}),
1910 mCompositionType(Composition::Invalid),
1911 mDisplayFrame({0, 0, -1, -1}),
1912 mPlaneAlpha(0.0f),
1913 mSidebandStream(nullptr),
1914 mSourceCrop({0.0f, 0.0f, -1.0f, -1.0f}),
1915 mTransform(Transform::None),
1916 mVisibleRegion(),
1917 mZ(0),
1918 mReleaseFence(),
1919 mHwc1Id(0),
1920 mHasUnsupportedPlaneAlpha(false) {}
1921
1922bool HWC2On1Adapter::SortLayersByZ::operator()(
1923 const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs) {
1924 return lhs->getZ() < rhs->getZ();
1925}
1926
1927Error HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer,
1928 int32_t acquireFence) {
1929 ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
1930 mBuffer.setBuffer(buffer);
1931 mBuffer.setFence(acquireFence);
1932 return Error::None;
1933}
1934
1935Error HWC2On1Adapter::Layer::setCursorPosition(int32_t x, int32_t y) {
1936 if (mCompositionType != Composition::Cursor) {
1937 return Error::BadLayer;
1938 }
1939
1940 if (mDisplay.hasChanges()) {
1941 return Error::NotValidated;
1942 }
1943
1944 auto displayId = mDisplay.getHwc1Id();
1945 auto hwc1Device = mDisplay.getDevice().getHwc1Device();
1946 hwc1Device->setCursorPositionAsync(hwc1Device, displayId, x, y);
1947 return Error::None;
1948}
1949
1950Error HWC2On1Adapter::Layer::setSurfaceDamage(hwc_region_t damage) {
1951 // HWC1 supports surface damage starting only with version 1.5.
1952 if (mDisplay.getDevice().mHwc1MinorVersion < 5) {
1953 return Error::None;
1954 }
1955 mSurfaceDamage.resize(damage.numRects);
1956 std::copy_n(damage.rects, damage.numRects, mSurfaceDamage.begin());
1957 return Error::None;
1958}
1959
1960// Layer state functions
1961
1962Error HWC2On1Adapter::Layer::setBlendMode(BlendMode mode) {
1963 mBlendMode = mode;
1964 mDisplay.markGeometryChanged();
1965 return Error::None;
1966}
1967
1968Error HWC2On1Adapter::Layer::setColor(hwc_color_t color) {
1969 mColor = color;
1970 mDisplay.markGeometryChanged();
1971 return Error::None;
1972}
1973
1974Error HWC2On1Adapter::Layer::setCompositionType(Composition type) {
1975 mCompositionType = type;
1976 mDisplay.markGeometryChanged();
1977 return Error::None;
1978}
1979
1980Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t) {
1981 return Error::None;
1982}
1983
1984Error HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame) {
1985 mDisplayFrame = frame;
1986 mDisplay.markGeometryChanged();
1987 return Error::None;
1988}
1989
1990Error HWC2On1Adapter::Layer::setPlaneAlpha(float alpha) {
1991 mPlaneAlpha = alpha;
1992 mDisplay.markGeometryChanged();
1993 return Error::None;
1994}
1995
1996Error HWC2On1Adapter::Layer::setSidebandStream(const native_handle_t* stream) {
1997 mSidebandStream = stream;
1998 mDisplay.markGeometryChanged();
1999 return Error::None;
2000}
2001
2002Error HWC2On1Adapter::Layer::setSourceCrop(hwc_frect_t crop) {
2003 mSourceCrop = crop;
2004 mDisplay.markGeometryChanged();
2005 return Error::None;
2006}
2007
2008Error HWC2On1Adapter::Layer::setTransform(Transform transform) {
2009 mTransform = transform;
2010 mDisplay.markGeometryChanged();
2011 return Error::None;
2012}
2013
2014static bool compareRects(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
2015 return rect1.left == rect2.left &&
2016 rect1.right == rect2.right &&
2017 rect1.top == rect2.top &&
2018 rect1.bottom == rect2.bottom;
2019}
2020
2021Error HWC2On1Adapter::Layer::setVisibleRegion(hwc_region_t visible) {
2022 if ((getNumVisibleRegions() != visible.numRects) ||
2023 !std::equal(mVisibleRegion.begin(), mVisibleRegion.end(), visible.rects,
2024 compareRects)) {
2025 mVisibleRegion.resize(visible.numRects);
2026 std::copy_n(visible.rects, visible.numRects, mVisibleRegion.begin());
2027 mDisplay.markGeometryChanged();
2028 }
2029 return Error::None;
2030}
2031
2032Error HWC2On1Adapter::Layer::setZ(uint32_t z) {
2033 mZ = z;
2034 return Error::None;
2035}
2036
2037void HWC2On1Adapter::Layer::addReleaseFence(int fenceFd) {
2038 ALOGV("addReleaseFence %d to layer %" PRIu64, fenceFd, mId);
2039 mReleaseFence.add(fenceFd);
2040}
2041
2042const sp<MiniFence>& HWC2On1Adapter::Layer::getReleaseFence() const {
2043 return mReleaseFence.get();
2044}
2045
2046void HWC2On1Adapter::Layer::applyState(hwc_layer_1_t& hwc1Layer) {
2047 applyCommonState(hwc1Layer);
2048 applyCompositionType(hwc1Layer);
2049 switch (mCompositionType) {
2050 case Composition::SolidColor : applySolidColorState(hwc1Layer); break;
2051 case Composition::Sideband : applySidebandState(hwc1Layer); break;
2052 default: applyBufferState(hwc1Layer); break;
2053 }
2054}
2055
2056static std::string regionStrings(const std::vector<hwc_rect_t>& visibleRegion,
2057 const std::vector<hwc_rect_t>& surfaceDamage) {
2058 std::string regions;
2059 regions += " Visible Region";
2060 regions.resize(40, ' ');
2061 regions += "Surface Damage\n";
2062
2063 size_t numPrinted = 0;
2064 size_t maxSize = std::max(visibleRegion.size(), surfaceDamage.size());
2065 while (numPrinted < maxSize) {
2066 std::string line(" ");
2067 if (visibleRegion.empty() && numPrinted == 0) {
2068 line += "None";
2069 } else if (numPrinted < visibleRegion.size()) {
2070 line += rectString(visibleRegion[numPrinted]);
2071 }
2072 line.resize(40, ' ');
2073 if (surfaceDamage.empty() && numPrinted == 0) {
2074 line += "None";
2075 } else if (numPrinted < surfaceDamage.size()) {
2076 line += rectString(surfaceDamage[numPrinted]);
2077 }
2078 line += '\n';
2079 regions += line;
2080 ++numPrinted;
2081 }
2082 return regions;
2083}
2084
2085std::string HWC2On1Adapter::Layer::dump() const {
2086 std::stringstream output;
2087 const char* fill = " ";
2088
2089 output << fill << to_string(mCompositionType);
2090 output << " Layer HWC2/1: " << mId << "/" << mHwc1Id << " ";
2091 output << "Z: " << mZ;
2092 if (mCompositionType == HWC2::Composition::SolidColor) {
2093 output << " " << colorString(mColor);
2094 } else if (mCompositionType == HWC2::Composition::Sideband) {
2095 output << " Handle: " << mSidebandStream << '\n';
2096 } else {
2097 output << " Buffer: " << mBuffer.getBuffer() << "/" <<
2098 mBuffer.getFence() << '\n';
2099 output << fill << " Display frame [LTRB]: " <<
2100 rectString(mDisplayFrame) << '\n';
2101 output << fill << " Source crop: " <<
2102 frectString(mSourceCrop) << '\n';
2103 output << fill << " Transform: " << to_string(mTransform);
2104 output << " Blend mode: " << to_string(mBlendMode);
2105 if (mPlaneAlpha != 1.0f) {
2106 output << " Alpha: " <<
2107 alphaString(mPlaneAlpha) << '\n';
2108 } else {
2109 output << '\n';
2110 }
2111 output << regionStrings(mVisibleRegion, mSurfaceDamage);
2112 }
2113 return output.str();
2114}
2115
2116static int getHwc1Blending(HWC2::BlendMode blendMode) {
2117 switch (blendMode) {
2118 case BlendMode::Coverage: return HWC_BLENDING_COVERAGE;
2119 case BlendMode::Premultiplied: return HWC_BLENDING_PREMULT;
2120 default: return HWC_BLENDING_NONE;
2121 }
2122}
2123
2124void HWC2On1Adapter::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer) {
2125 auto minorVersion = mDisplay.getDevice().getHwc1MinorVersion();
2126 hwc1Layer.blending = getHwc1Blending(mBlendMode);
2127 hwc1Layer.displayFrame = mDisplayFrame;
2128
2129 auto pendingAlpha = mPlaneAlpha;
2130 if (minorVersion < 2) {
2131 mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f;
2132 } else {
2133 hwc1Layer.planeAlpha =
2134 static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f);
2135 }
2136
2137 if (minorVersion < 3) {
2138 auto pending = mSourceCrop;
2139 hwc1Layer.sourceCropi.left =
2140 static_cast<int32_t>(std::ceil(pending.left));
2141 hwc1Layer.sourceCropi.top =
2142 static_cast<int32_t>(std::ceil(pending.top));
2143 hwc1Layer.sourceCropi.right =
2144 static_cast<int32_t>(std::floor(pending.right));
2145 hwc1Layer.sourceCropi.bottom =
2146 static_cast<int32_t>(std::floor(pending.bottom));
2147 } else {
2148 hwc1Layer.sourceCropf = mSourceCrop;
2149 }
2150
2151 hwc1Layer.transform = static_cast<uint32_t>(mTransform);
2152
2153 auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen;
2154 hwc1VisibleRegion.numRects = mVisibleRegion.size();
2155 hwc_rect_t* rects = mDisplay.GetRects(hwc1VisibleRegion.numRects);
2156 hwc1VisibleRegion.rects = rects;
2157 for (size_t i = 0; i < mVisibleRegion.size(); i++) {
2158 rects[i] = mVisibleRegion[i];
2159 }
2160}
2161
2162void HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer) {
2163 // If the device does not support background color it is likely to make
2164 // assumption regarding backgroundColor and handle (both fields occupy
2165 // the same location in hwc_layer_1_t union).
2166 // To not confuse these devices we don't set background color and we
2167 // make sure handle is a null pointer.
2168 if (hasUnsupportedBackgroundColor()) {
2169 hwc1Layer.handle = nullptr;
2170 } else {
2171 hwc1Layer.backgroundColor = mColor;
2172 }
2173}
2174
2175void HWC2On1Adapter::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer) {
2176 hwc1Layer.sidebandStream = mSidebandStream;
2177}
2178
2179void HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer) {
2180 hwc1Layer.handle = mBuffer.getBuffer();
2181 hwc1Layer.acquireFenceFd = mBuffer.getFence();
2182}
2183
2184void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer) {
2185 // HWC1 never supports color transforms or dataspaces and only sometimes
2186 // supports plane alpha (depending on the version). These require us to drop
2187 // some or all layers to client composition.
2188 if (mHasUnsupportedPlaneAlpha || mDisplay.hasColorTransform() ||
2189 hasUnsupportedBackgroundColor()) {
2190 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2191 hwc1Layer.flags = HWC_SKIP_LAYER;
2192 return;
2193 }
2194
2195 hwc1Layer.flags = 0;
2196 switch (mCompositionType) {
2197 case Composition::Client:
2198 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2199 hwc1Layer.flags |= HWC_SKIP_LAYER;
2200 break;
2201 case Composition::Device:
2202 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2203 break;
2204 case Composition::SolidColor:
2205 // In theory the following line should work, but since the HWC1
2206 // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
2207 // devices may not work correctly. To be on the safe side, we
2208 // fall back to client composition.
2209 //
2210 // hwc1Layer.compositionType = HWC_BACKGROUND;
2211 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2212 hwc1Layer.flags |= HWC_SKIP_LAYER;
2213 break;
2214 case Composition::Cursor:
2215 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2216 if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
2217 hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
2218 }
2219 break;
2220 case Composition::Sideband:
2221 if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
2222 hwc1Layer.compositionType = HWC_SIDEBAND;
2223 } else {
2224 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2225 hwc1Layer.flags |= HWC_SKIP_LAYER;
2226 }
2227 break;
2228 default:
2229 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2230 hwc1Layer.flags |= HWC_SKIP_LAYER;
2231 break;
2232 }
2233 ALOGV("Layer %" PRIu64 " %s set to %d", mId,
2234 to_string(mCompositionType).c_str(),
2235 hwc1Layer.compositionType);
2236 ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, " and skipping");
2237}
2238
2239// Adapter helpers
2240
2241void HWC2On1Adapter::populateCapabilities() {
2242 if (mHwc1MinorVersion >= 3U) {
2243 int supportedTypes = 0;
2244 auto result = mHwc1Device->query(mHwc1Device,
2245 HWC_DISPLAY_TYPES_SUPPORTED, &supportedTypes);
2246 if ((result == 0) && ((supportedTypes & HWC_DISPLAY_VIRTUAL_BIT) != 0)) {
2247 ALOGI("Found support for HWC virtual displays");
2248 mHwc1SupportsVirtualDisplays = true;
2249 }
2250 }
2251 if (mHwc1MinorVersion >= 4U) {
2252 mCapabilities.insert(Capability::SidebandStream);
2253 }
2254
2255 // Check for HWC background color layer support.
2256 if (mHwc1MinorVersion >= 1U) {
2257 int backgroundColorSupported = 0;
2258 auto result = mHwc1Device->query(mHwc1Device,
2259 HWC_BACKGROUND_LAYER_SUPPORTED,
2260 &backgroundColorSupported);
2261 if ((result == 0) && (backgroundColorSupported == 1)) {
2262 ALOGV("Found support for HWC background color");
2263 mHwc1SupportsBackgroundColor = true;
2264 }
2265 }
2266
2267 // Some devices might have HWC1 retire fences that accurately emulate
2268 // HWC2 present fences when they are deferred, but it's not very reliable.
2269 // To be safe, we indicate PresentFenceIsNotReliable for all HWC1 devices.
2270 mCapabilities.insert(Capability::PresentFenceIsNotReliable);
2271}
2272
2273HWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id) {
2274 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2275
2276 auto display = mDisplays.find(id);
2277 if (display == mDisplays.end()) {
2278 return nullptr;
2279 }
2280
2281 return display->second.get();
2282}
2283
2284std::tuple<HWC2On1Adapter::Layer*, Error> HWC2On1Adapter::getLayer(
2285 hwc2_display_t displayId, hwc2_layer_t layerId) {
2286 auto display = getDisplay(displayId);
2287 if (!display) {
2288 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
2289 }
2290
2291 auto layerEntry = mLayers.find(layerId);
2292 if (layerEntry == mLayers.end()) {
2293 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2294 }
2295
2296 auto layer = layerEntry->second;
2297 if (layer->getDisplay().getId() != displayId) {
2298 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2299 }
2300 return std::make_tuple(layer.get(), Error::None);
2301}
2302
2303void HWC2On1Adapter::populatePrimary() {
2304 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2305
2306 auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
2307 mHwc1DisplayMap[HWC_DISPLAY_PRIMARY] = display->getId();
2308 display->setHwc1Id(HWC_DISPLAY_PRIMARY);
2309 display->populateConfigs();
2310 mDisplays.emplace(display->getId(), std::move(display));
2311}
2312
2313bool HWC2On1Adapter::prepareAllDisplays() {
2314 ATRACE_CALL();
2315
2316 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2317
2318 for (const auto& displayPair : mDisplays) {
2319 auto& display = displayPair.second;
2320 if (!display->prepare()) {
2321 return false;
2322 }
2323 }
2324
2325 if (mHwc1DisplayMap.count(HWC_DISPLAY_PRIMARY) == 0) {
2326 ALOGE("prepareAllDisplays: Unable to find primary HWC1 display");
2327 return false;
2328 }
2329
2330 // Build an array of hwc_display_contents_1 to call prepare() on HWC1.
2331 mHwc1Contents.clear();
2332
2333 // Always push the primary display
2334 auto primaryDisplayId = mHwc1DisplayMap[HWC_DISPLAY_PRIMARY];
2335 auto& primaryDisplay = mDisplays[primaryDisplayId];
2336 mHwc1Contents.push_back(primaryDisplay->getDisplayContents());
2337
2338 // Push the external display, if present
2339 if (mHwc1DisplayMap.count(HWC_DISPLAY_EXTERNAL) != 0) {
2340 auto externalDisplayId = mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL];
2341 auto& externalDisplay = mDisplays[externalDisplayId];
2342 mHwc1Contents.push_back(externalDisplay->getDisplayContents());
2343 } else {
2344 // Even if an external display isn't present, we still need to send
2345 // at least two displays down to HWC1
2346 mHwc1Contents.push_back(nullptr);
2347 }
2348
2349 // Push the hardware virtual display, if supported and present
2350 if (mHwc1MinorVersion >= 3) {
2351 if (mHwc1DisplayMap.count(HWC_DISPLAY_VIRTUAL) != 0) {
2352 auto virtualDisplayId = mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL];
2353 auto& virtualDisplay = mDisplays[virtualDisplayId];
2354 mHwc1Contents.push_back(virtualDisplay->getDisplayContents());
2355 } else {
2356 mHwc1Contents.push_back(nullptr);
2357 }
2358 }
2359
2360 for (auto& displayContents : mHwc1Contents) {
2361 if (!displayContents) {
2362 continue;
2363 }
2364
2365 ALOGV("Display %zd layers:", mHwc1Contents.size() - 1);
2366 for (size_t l = 0; l < displayContents->numHwLayers; ++l) {
2367 auto& layer = displayContents->hwLayers[l];
2368 ALOGV(" %zd: %d", l, layer.compositionType);
2369 }
2370 }
2371
2372 ALOGV("Calling HWC1 prepare");
2373 {
2374 ATRACE_NAME("HWC1 prepare");
2375 mHwc1Device->prepare(mHwc1Device, mHwc1Contents.size(),
2376 mHwc1Contents.data());
2377 }
2378
2379 for (size_t c = 0; c < mHwc1Contents.size(); ++c) {
2380 auto& contents = mHwc1Contents[c];
2381 if (!contents) {
2382 continue;
2383 }
2384 ALOGV("Display %zd layers:", c);
2385 for (size_t l = 0; l < contents->numHwLayers; ++l) {
2386 ALOGV(" %zd: %d", l, contents->hwLayers[l].compositionType);
2387 }
2388 }
2389
2390 // Return the received contents to their respective displays
2391 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2392 if (mHwc1Contents[hwc1Id] == nullptr) {
2393 continue;
2394 }
2395
2396 auto displayId = mHwc1DisplayMap[hwc1Id];
2397 auto& display = mDisplays[displayId];
2398 display->generateChanges();
2399 }
2400
2401 return true;
2402}
2403
2404void dumpHWC1Message(hwc_composer_device_1* device, size_t numDisplays,
2405 hwc_display_contents_1_t** displays) {
2406 ALOGV("*****************************");
2407 size_t displayId = 0;
2408 while (displayId < numDisplays) {
2409 hwc_display_contents_1_t* display = displays[displayId];
2410
2411 ALOGV("hwc_display_contents_1_t[%zu] @0x%p", displayId, display);
2412 if (display == nullptr) {
2413 displayId++;
2414 continue;
2415 }
2416 ALOGV(" retirefd:0x%08x", display->retireFenceFd);
2417 ALOGV(" outbuf :0x%p", display->outbuf);
2418 ALOGV(" outbuffd:0x%08x", display->outbufAcquireFenceFd);
2419 ALOGV(" flags :0x%08x", display->flags);
2420 for(size_t layerId=0 ; layerId < display->numHwLayers ; layerId++) {
2421 hwc_layer_1_t& layer = display->hwLayers[layerId];
2422 ALOGV(" Layer[%zu]:", layerId);
2423 ALOGV(" composition : 0x%08x", layer.compositionType);
2424 ALOGV(" hints : 0x%08x", layer.hints);
2425 ALOGV(" flags : 0x%08x", layer.flags);
2426 ALOGV(" handle : 0x%p", layer.handle);
2427 ALOGV(" transform : 0x%08x", layer.transform);
2428 ALOGV(" blending : 0x%08x", layer.blending);
2429 ALOGV(" sourceCropf : %f, %f, %f, %f",
2430 layer.sourceCropf.left,
2431 layer.sourceCropf.top,
2432 layer.sourceCropf.right,
2433 layer.sourceCropf.bottom);
2434 ALOGV(" displayFrame : %d, %d, %d, %d",
2435 layer.displayFrame.left,
2436 layer.displayFrame.left,
2437 layer.displayFrame.left,
2438 layer.displayFrame.left);
2439 hwc_region_t& visReg = layer.visibleRegionScreen;
2440 ALOGV(" visibleRegionScreen: #0x%08zx[@0x%p]",
2441 visReg.numRects,
2442 visReg.rects);
2443 for (size_t visRegId=0; visRegId < visReg.numRects ; visRegId++) {
2444 if (layer.visibleRegionScreen.rects == nullptr) {
2445 ALOGV(" null");
2446 } else {
2447 ALOGV(" visibleRegionScreen[%zu] %d, %d, %d, %d",
2448 visRegId,
2449 visReg.rects[visRegId].left,
2450 visReg.rects[visRegId].top,
2451 visReg.rects[visRegId].right,
2452 visReg.rects[visRegId].bottom);
2453 }
2454 }
2455 ALOGV(" acquireFenceFd : 0x%08x", layer.acquireFenceFd);
2456 ALOGV(" releaseFenceFd : 0x%08x", layer.releaseFenceFd);
2457 ALOGV(" planeAlpha : 0x%08x", layer.planeAlpha);
2458 if (getMinorVersion(device) < 5)
2459 continue;
2460 ALOGV(" surfaceDamage : #0x%08zx[@0x%p]",
2461 layer.surfaceDamage.numRects,
2462 layer.surfaceDamage.rects);
2463 for (size_t sdId=0; sdId < layer.surfaceDamage.numRects ; sdId++) {
2464 if (layer.surfaceDamage.rects == nullptr) {
2465 ALOGV(" null");
2466 } else {
2467 ALOGV(" surfaceDamage[%zu] %d, %d, %d, %d",
2468 sdId,
2469 layer.surfaceDamage.rects[sdId].left,
2470 layer.surfaceDamage.rects[sdId].top,
2471 layer.surfaceDamage.rects[sdId].right,
2472 layer.surfaceDamage.rects[sdId].bottom);
2473 }
2474 }
2475 }
2476 displayId++;
2477 }
2478 ALOGV("-----------------------------");
2479}
2480
2481Error HWC2On1Adapter::setAllDisplays() {
2482 ATRACE_CALL();
2483
2484 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2485
2486 // Make sure we're ready to validate
2487 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2488 if (mHwc1Contents[hwc1Id] == nullptr) {
2489 continue;
2490 }
2491
2492 auto displayId = mHwc1DisplayMap[hwc1Id];
2493 auto& display = mDisplays[displayId];
2494 Error error = display->set(*mHwc1Contents[hwc1Id]);
2495 if (error != Error::None) {
2496 ALOGE("setAllDisplays: Failed to set display %zd: %s", hwc1Id,
2497 to_string(error).c_str());
2498 return error;
2499 }
2500 }
2501
2502 ALOGV("Calling HWC1 set");
2503 {
2504 ATRACE_NAME("HWC1 set");
2505 //dumpHWC1Message(mHwc1Device, mHwc1Contents.size(), mHwc1Contents.data());
2506 mHwc1Device->set(mHwc1Device, mHwc1Contents.size(),
2507 mHwc1Contents.data());
2508 }
2509
2510 // Add retire and release fences
2511 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2512 if (mHwc1Contents[hwc1Id] == nullptr) {
2513 continue;
2514 }
2515
2516 auto displayId = mHwc1DisplayMap[hwc1Id];
2517 auto& display = mDisplays[displayId];
2518 auto retireFenceFd = mHwc1Contents[hwc1Id]->retireFenceFd;
2519 ALOGV("setAllDisplays: Adding retire fence %d to display %zd",
2520 retireFenceFd, hwc1Id);
2521 display->addRetireFence(mHwc1Contents[hwc1Id]->retireFenceFd);
2522 display->addReleaseFences(*mHwc1Contents[hwc1Id]);
2523 }
2524
2525 return Error::None;
2526}
2527
2528void HWC2On1Adapter::hwc1Invalidate() {
2529 ALOGV("Received hwc1Invalidate");
2530
2531 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2532
2533 // If the HWC2-side callback hasn't been registered yet, buffer this until
2534 // it is registered.
2535 if (mCallbacks.count(Callback::Refresh) == 0) {
2536 mHasPendingInvalidate = true;
2537 return;
2538 }
2539
2540 const auto& callbackInfo = mCallbacks[Callback::Refresh];
2541 std::vector<hwc2_display_t> displays;
2542 for (const auto& displayPair : mDisplays) {
2543 displays.emplace_back(displayPair.first);
2544 }
2545
2546 // Call back without the state lock held.
2547 lock.unlock();
2548
2549 auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(callbackInfo.pointer);
2550 for (auto display : displays) {
2551 refresh(callbackInfo.data, display);
2552 }
2553}
2554
2555void HWC2On1Adapter::hwc1Vsync(int hwc1DisplayId, int64_t timestamp) {
2556 ALOGV("Received hwc1Vsync(%d, %" PRId64 ")", hwc1DisplayId, timestamp);
2557
2558 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2559
2560 // If the HWC2-side callback hasn't been registered yet, buffer this until
2561 // it is registered.
2562 if (mCallbacks.count(Callback::Vsync) == 0) {
2563 mPendingVsyncs.emplace_back(hwc1DisplayId, timestamp);
2564 return;
2565 }
2566
2567 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2568 ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", hwc1DisplayId);
2569 return;
2570 }
2571
2572 const auto& callbackInfo = mCallbacks[Callback::Vsync];
2573 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
2574
2575 // Call back without the state lock held.
2576 lock.unlock();
2577
2578 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
2579 vsync(callbackInfo.data, displayId, timestamp);
2580}
2581
2582void HWC2On1Adapter::hwc1Hotplug(int hwc1DisplayId, int connected) {
2583 ALOGV("Received hwc1Hotplug(%d, %d)", hwc1DisplayId, connected);
2584
2585 if (hwc1DisplayId != HWC_DISPLAY_EXTERNAL) {
2586 ALOGE("hwc1Hotplug: Received hotplug for non-external display");
2587 return;
2588 }
2589
2590 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2591
2592 // If the HWC2-side callback hasn't been registered yet, buffer this until
2593 // it is registered
2594 if (mCallbacks.count(Callback::Hotplug) == 0) {
2595 mPendingHotplugs.emplace_back(hwc1DisplayId, connected);
2596 return;
2597 }
2598
2599 hwc2_display_t displayId = UINT64_MAX;
2600 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2601 if (connected == 0) {
2602 ALOGW("hwc1Hotplug: Received disconnect for unconnected display");
2603 return;
2604 }
2605
2606 // Create a new display on connect
2607 auto display = std::make_shared<HWC2On1Adapter::Display>(*this,
2608 HWC2::DisplayType::Physical);
2609 display->setHwc1Id(HWC_DISPLAY_EXTERNAL);
2610 display->populateConfigs();
2611 displayId = display->getId();
2612 mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL] = displayId;
2613 mDisplays.emplace(displayId, std::move(display));
2614 } else {
2615 if (connected != 0) {
2616 ALOGW("hwc1Hotplug: Received connect for previously connected "
2617 "display");
2618 return;
2619 }
2620
2621 // Disconnect an existing display
2622 displayId = mHwc1DisplayMap[hwc1DisplayId];
2623 mHwc1DisplayMap.erase(HWC_DISPLAY_EXTERNAL);
2624 mDisplays.erase(displayId);
2625 }
2626
2627 const auto& callbackInfo = mCallbacks[Callback::Hotplug];
2628
2629 // Call back without the state lock held
2630 lock.unlock();
2631
2632 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(callbackInfo.pointer);
2633 auto hwc2Connected = (connected == 0) ?
2634 HWC2::Connection::Disconnected : HWC2::Connection::Connected;
2635 hotplug(callbackInfo.data, displayId, static_cast<int32_t>(hwc2Connected));
2636}
2637} // namespace android
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/MiniFence.cpp b/graphics/composer/2.1/utils/hwc2on1adapter/MiniFence.cpp
new file mode 100644
index 00000000..dfbe4d63
--- /dev/null
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/MiniFence.cpp
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "hwc2on1adapter/MiniFence.h"
18
19#include <unistd.h>
20
21namespace android {
22
23const sp<MiniFence> MiniFence::NO_FENCE = sp<MiniFence>(new MiniFence);
24
25MiniFence::MiniFence() :
26 mFenceFd(-1) {
27}
28
29MiniFence::MiniFence(int fenceFd) :
30 mFenceFd(fenceFd) {
31}
32
33MiniFence::~MiniFence() {
34 if (mFenceFd != -1) {
35 close(mFenceFd);
36 }
37}
38
39int MiniFence::dup() const {
40 return ::dup(mFenceFd);
41}
42}
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/include/hwc2on1adapter/HWC2On1Adapter.h b/graphics/composer/2.1/utils/hwc2on1adapter/include/hwc2on1adapter/HWC2On1Adapter.h
new file mode 100644
index 00000000..3badfce0
--- /dev/null
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/include/hwc2on1adapter/HWC2On1Adapter.h
@@ -0,0 +1,738 @@
1/*
2 * Copyright 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_SF_HWC2_ON_1_ADAPTER_H
18#define ANDROID_SF_HWC2_ON_1_ADAPTER_H
19
20#define HWC2_INCLUDE_STRINGIFICATION
21#define HWC2_USE_CPP11
22#include <hardware/hwcomposer2.h>
23#undef HWC2_INCLUDE_STRINGIFICATION
24#undef HWC2_USE_CPP11
25
26#include "MiniFence.h"
27
28#include <atomic>
29#include <map>
30#include <mutex>
31#include <queue>
32#include <set>
33#include <unordered_map>
34#include <unordered_set>
35#include <vector>
36
37struct hwc_composer_device_1;
38struct hwc_display_contents_1;
39struct hwc_layer_1;
40
41namespace android {
42
43// For devices unable to provide an implementation of HWC2 (see hwcomposer2.h),
44// we provide an adapter able to talk to HWC1 (see hwcomposer.h). It translates
45// streamed function calls ala HWC2 model to batched array of structs calls ala
46// HWC1 model.
47class HWC2On1Adapter : public hwc2_device_t
48{
49public:
50 explicit HWC2On1Adapter(struct hwc_composer_device_1* hwc1Device);
51 ~HWC2On1Adapter();
52
53 struct hwc_composer_device_1* getHwc1Device() const { return mHwc1Device; }
54 uint8_t getHwc1MinorVersion() const { return mHwc1MinorVersion; }
55
56private:
57 static inline HWC2On1Adapter* getAdapter(hwc2_device_t* device) {
58 return static_cast<HWC2On1Adapter*>(device);
59 }
60
61 // getCapabilities
62
63 void doGetCapabilities(uint32_t* outCount,
64 int32_t* /*hwc2_capability_t*/ outCapabilities);
65 static void getCapabilitiesHook(hwc2_device_t* device, uint32_t* outCount,
66 int32_t* /*hwc2_capability_t*/ outCapabilities) {
67 getAdapter(device)->doGetCapabilities(outCount, outCapabilities);
68 }
69
70 bool supportsBackgroundColor() {
71 return mHwc1SupportsBackgroundColor;
72 }
73
74 // getFunction
75
76 hwc2_function_pointer_t doGetFunction(HWC2::FunctionDescriptor descriptor);
77 static hwc2_function_pointer_t getFunctionHook(hwc2_device_t* device,
78 int32_t intDesc) {
79 auto descriptor = static_cast<HWC2::FunctionDescriptor>(intDesc);
80 return getAdapter(device)->doGetFunction(descriptor);
81 }
82
83 // Device functions
84
85 HWC2::Error createVirtualDisplay(uint32_t width, uint32_t height,
86 hwc2_display_t* outDisplay);
87 static int32_t createVirtualDisplayHook(hwc2_device_t* device,
88 uint32_t width, uint32_t height, int32_t* /*format*/,
89 hwc2_display_t* outDisplay) {
90 // HWC1 implementations cannot override the buffer format requested by
91 // the consumer
92 auto error = getAdapter(device)->createVirtualDisplay(width, height,
93 outDisplay);
94 return static_cast<int32_t>(error);
95 }
96
97 HWC2::Error destroyVirtualDisplay(hwc2_display_t display);
98 static int32_t destroyVirtualDisplayHook(hwc2_device_t* device,
99 hwc2_display_t display) {
100 auto error = getAdapter(device)->destroyVirtualDisplay(display);
101 return static_cast<int32_t>(error);
102 }
103
104 std::string mDumpString;
105 void dump(uint32_t* outSize, char* outBuffer);
106 static void dumpHook(hwc2_device_t* device, uint32_t* outSize,
107 char* outBuffer) {
108 getAdapter(device)->dump(outSize, outBuffer);
109 }
110
111 uint32_t getMaxVirtualDisplayCount();
112 static uint32_t getMaxVirtualDisplayCountHook(hwc2_device_t* device) {
113 return getAdapter(device)->getMaxVirtualDisplayCount();
114 }
115
116 HWC2::Error registerCallback(HWC2::Callback descriptor,
117 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer);
118 static int32_t registerCallbackHook(hwc2_device_t* device,
119 int32_t intDesc, hwc2_callback_data_t callbackData,
120 hwc2_function_pointer_t pointer) {
121 auto descriptor = static_cast<HWC2::Callback>(intDesc);
122 auto error = getAdapter(device)->registerCallback(descriptor,
123 callbackData, pointer);
124 return static_cast<int32_t>(error);
125 }
126
127 // Display functions
128
129 class Layer;
130
131 class SortLayersByZ {
132 public:
133 bool operator()(const std::shared_ptr<Layer>& lhs,
134 const std::shared_ptr<Layer>& rhs);
135 };
136
137 // The semantics of the fences returned by the device differ between
138 // hwc1.set() and hwc2.present(). Read hwcomposer.h and hwcomposer2.h
139 // for more information.
140 //
141 // Release fences in hwc1 are obtained on set() for a frame n and signaled
142 // when the layer buffer is not needed for read operations anymore
143 // (typically on frame n+1). In HWC2, release fences are obtained with a
144 // special call after present() for frame n. These fences signal
145 // on frame n: More specifically, the fence for a given buffer provided in
146 // frame n will signal when the prior buffer is no longer required.
147 //
148 // A retire fence (HWC1) is signaled when a composition is replaced
149 // on the panel whereas a present fence (HWC2) is signaled when a
150 // composition starts to be displayed on a panel.
151 //
152 // The HWC2to1Adapter emulates the new fence semantics for a frame
153 // n by returning the fence from frame n-1. For frame 0, the adapter
154 // returns NO_FENCE.
155 class DeferredFence {
156 public:
157 DeferredFence()
158 : mFences({MiniFence::NO_FENCE, MiniFence::NO_FENCE}) {}
159
160 void add(int32_t fenceFd) {
161 mFences.emplace(new MiniFence(fenceFd));
162 mFences.pop();
163 }
164
165 const sp<MiniFence>& get() const {
166 return mFences.front();
167 }
168
169 private:
170 // There are always two fences in this queue.
171 std::queue<sp<MiniFence>> mFences;
172 };
173
174 class FencedBuffer {
175 public:
176 FencedBuffer() : mBuffer(nullptr), mFence(MiniFence::NO_FENCE) {}
177
178 void setBuffer(buffer_handle_t buffer) { mBuffer = buffer; }
179 void setFence(int fenceFd) { mFence = new MiniFence(fenceFd); }
180
181 buffer_handle_t getBuffer() const { return mBuffer; }
182 int getFence() const { return mFence->dup(); }
183
184 private:
185 buffer_handle_t mBuffer;
186 sp<MiniFence> mFence;
187 };
188
189 class Display {
190 public:
191 Display(HWC2On1Adapter& device, HWC2::DisplayType type);
192
193 hwc2_display_t getId() const { return mId; }
194 HWC2On1Adapter& getDevice() const { return mDevice; }
195
196 // Does not require locking because it is set before adding the
197 // Displays to the Adapter's list of displays
198 void setHwc1Id(int32_t id) { mHwc1Id = id; }
199 int32_t getHwc1Id() const { return mHwc1Id; }
200
201 // HWC2 Display functions
202 HWC2::Error acceptChanges();
203 HWC2::Error createLayer(hwc2_layer_t* outLayerId);
204 HWC2::Error destroyLayer(hwc2_layer_t layerId);
205 HWC2::Error getActiveConfig(hwc2_config_t* outConfigId);
206 HWC2::Error getAttribute(hwc2_config_t configId,
207 HWC2::Attribute attribute, int32_t* outValue);
208 HWC2::Error getChangedCompositionTypes(uint32_t* outNumElements,
209 hwc2_layer_t* outLayers, int32_t* outTypes);
210 HWC2::Error getColorModes(uint32_t* outNumModes, int32_t* outModes);
211 HWC2::Error getConfigs(uint32_t* outNumConfigs,
212 hwc2_config_t* outConfigIds);
213 HWC2::Error getDozeSupport(int32_t* outSupport);
214 HWC2::Error getHdrCapabilities(uint32_t* outNumTypes,
215 int32_t* outTypes, float* outMaxLuminance,
216 float* outMaxAverageLuminance, float* outMinLuminance);
217 HWC2::Error getName(uint32_t* outSize, char* outName);
218 HWC2::Error getReleaseFences(uint32_t* outNumElements,
219 hwc2_layer_t* outLayers, int32_t* outFences);
220 HWC2::Error getRequests(int32_t* outDisplayRequests,
221 uint32_t* outNumElements, hwc2_layer_t* outLayers,
222 int32_t* outLayerRequests);
223 HWC2::Error getType(int32_t* outType);
224
225 // Since HWC1 "presents" (called "set" in HWC1) all Displays
226 // at once, the first call to any Display::present will trigger
227 // present() on all Displays in the Device. Subsequent calls without
228 // first calling validate() are noop (except for duping/returning
229 // the retire fence).
230 HWC2::Error present(int32_t* outRetireFence);
231
232 HWC2::Error setActiveConfig(hwc2_config_t configId);
233 HWC2::Error setClientTarget(buffer_handle_t target,
234 int32_t acquireFence, int32_t dataspace,
235 hwc_region_t damage);
236 HWC2::Error setColorMode(android_color_mode_t mode);
237 HWC2::Error setColorTransform(android_color_transform_t hint);
238 HWC2::Error setOutputBuffer(buffer_handle_t buffer,
239 int32_t releaseFence);
240 HWC2::Error setPowerMode(HWC2::PowerMode mode);
241 HWC2::Error setVsyncEnabled(HWC2::Vsync enabled);
242
243 // Since HWC1 "validates" (called "prepare" in HWC1) all Displays
244 // at once, the first call to any Display::validate() will trigger
245 // validate() on all other Displays in the Device.
246 HWC2::Error validate(uint32_t* outNumTypes,
247 uint32_t* outNumRequests);
248
249 HWC2::Error updateLayerZ(hwc2_layer_t layerId, uint32_t z);
250
251 HWC2::Error getClientTargetSupport(uint32_t width, uint32_t height,
252 int32_t format, int32_t dataspace);
253
254 // Read configs from HWC1 device
255 void populateConfigs();
256
257 // Set configs for a virtual display
258 void populateConfigs(uint32_t width, uint32_t height);
259
260 bool prepare();
261
262 // Called after hwc.prepare() with responses from the device.
263 void generateChanges();
264
265 bool hasChanges() const;
266 HWC2::Error set(hwc_display_contents_1& hwcContents);
267 void addRetireFence(int fenceFd);
268 void addReleaseFences(const hwc_display_contents_1& hwcContents);
269
270 bool hasColorTransform() const;
271
272 std::string dump() const;
273
274 // Return a rect from the pool allocated during validate()
275 hwc_rect_t* GetRects(size_t numRects);
276
277 hwc_display_contents_1* getDisplayContents();
278
279 void markGeometryChanged() { mGeometryChanged = true; }
280 void resetGeometryMarker() { mGeometryChanged = false;}
281 private:
282 class Config {
283 public:
284 Config(Display& display)
285 : mDisplay(display),
286 mId(0),
287 mAttributes() {}
288
289 bool isOnDisplay(const Display& display) const {
290 return display.getId() == mDisplay.getId();
291 }
292
293 void setAttribute(HWC2::Attribute attribute, int32_t value);
294 int32_t getAttribute(HWC2::Attribute attribute) const;
295
296 void setHwc1Id(uint32_t id);
297 bool hasHwc1Id(uint32_t id) const;
298 HWC2::Error getColorModeForHwc1Id(uint32_t id,
299 android_color_mode_t *outMode) const;
300 HWC2::Error getHwc1IdForColorMode(android_color_mode_t mode,
301 uint32_t* outId) const;
302
303 void setId(hwc2_config_t id) { mId = id; }
304 hwc2_config_t getId() const { return mId; }
305
306 // Attempts to merge two configs that differ only in color
307 // mode. Returns whether the merge was successful
308 bool merge(const Config& other);
309
310 std::set<android_color_mode_t> getColorModes() const;
311
312 // splitLine divides the output into two lines suitable for
313 // dumpsys SurfaceFlinger
314 std::string toString(bool splitLine = false) const;
315
316 private:
317 Display& mDisplay;
318 hwc2_config_t mId;
319 std::unordered_map<HWC2::Attribute, int32_t> mAttributes;
320
321 // Maps from color transform to HWC1 config ID
322 std::unordered_map<android_color_mode_t, uint32_t> mHwc1Ids;
323 };
324
325 // Stores changes requested from the device upon calling prepare().
326 // Handles change request to:
327 // - Layer composition type.
328 // - Layer hints.
329 class Changes {
330 public:
331 uint32_t getNumTypes() const {
332 return static_cast<uint32_t>(mTypeChanges.size());
333 }
334
335 uint32_t getNumLayerRequests() const {
336 return static_cast<uint32_t>(mLayerRequests.size());
337 }
338
339 const std::unordered_map<hwc2_layer_t, HWC2::Composition>&
340 getTypeChanges() const {
341 return mTypeChanges;
342 }
343
344 const std::unordered_map<hwc2_layer_t, HWC2::LayerRequest>&
345 getLayerRequests() const {
346 return mLayerRequests;
347 }
348
349 void addTypeChange(hwc2_layer_t layerId,
350 HWC2::Composition type) {
351 mTypeChanges.insert({layerId, type});
352 }
353
354 void clearTypeChanges() { mTypeChanges.clear(); }
355
356 void addLayerRequest(hwc2_layer_t layerId,
357 HWC2::LayerRequest request) {
358 mLayerRequests.insert({layerId, request});
359 }
360
361 private:
362 std::unordered_map<hwc2_layer_t, HWC2::Composition>
363 mTypeChanges;
364 std::unordered_map<hwc2_layer_t, HWC2::LayerRequest>
365 mLayerRequests;
366 };
367
368 std::shared_ptr<const Config>
369 getConfig(hwc2_config_t configId) const;
370
371 void populateColorModes();
372 void initializeActiveConfig();
373
374 // Creates a bi-directional mapping between index in HWC1
375 // prepare/set array and Layer object. Stores mapping in
376 // mHwc1LayerMap and also updates Layer's attribute mHwc1Id.
377 void assignHwc1LayerIds();
378
379 // Called after a response to prepare() has been received:
380 // Ingest composition type changes requested by the device.
381 void updateTypeChanges(const struct hwc_layer_1& hwc1Layer,
382 const Layer& layer);
383
384 // Called after a response to prepare() has been received:
385 // Ingest layer hint changes requested by the device.
386 void updateLayerRequests(const struct hwc_layer_1& hwc1Layer,
387 const Layer& layer);
388
389 // Set all fields in HWC1 comm array for layer containing the
390 // HWC_FRAMEBUFFER_TARGET (always the last layer).
391 void prepareFramebufferTarget();
392
393 // Display ID generator.
394 static std::atomic<hwc2_display_t> sNextId;
395 const hwc2_display_t mId;
396
397
398 HWC2On1Adapter& mDevice;
399
400 // The state of this display should only be modified from
401 // SurfaceFlinger's main loop, with the exception of when dump is
402 // called. To prevent a bad state from crashing us during a dump
403 // call, all public calls into Display must acquire this mutex.
404 //
405 // It is recursive because we don't want to deadlock in validate
406 // (or present) when we call HWC2On1Adapter::prepareAllDisplays
407 // (or setAllDisplays), which calls back into Display functions
408 // which require locking.
409 mutable std::recursive_mutex mStateMutex;
410
411 // Allocate RAM able to store all layers and rects used for
412 // communication with HWC1. Place allocated RAM in variable
413 // mHwc1RequestedContents.
414 void allocateRequestedContents();
415
416 // Array of structs exchanged between client and hwc1 device.
417 // Sent to device upon calling prepare().
418 std::unique_ptr<hwc_display_contents_1> mHwc1RequestedContents;
419 private:
420 DeferredFence mRetireFence;
421
422 // Will only be non-null after the Display has been validated and
423 // before it has been presented
424 std::unique_ptr<Changes> mChanges;
425
426 int32_t mHwc1Id;
427
428 std::vector<std::shared_ptr<Config>> mConfigs;
429 std::shared_ptr<const Config> mActiveConfig;
430 std::set<android_color_mode_t> mColorModes;
431 android_color_mode_t mActiveColorMode;
432 std::string mName;
433 HWC2::DisplayType mType;
434 HWC2::PowerMode mPowerMode;
435 HWC2::Vsync mVsyncEnabled;
436
437 // Used to populate HWC1 HWC_FRAMEBUFFER_TARGET layer
438 FencedBuffer mClientTarget;
439
440
441 FencedBuffer mOutputBuffer;
442
443 bool mHasColorTransform;
444
445 // All layers this Display is aware of.
446 std::multiset<std::shared_ptr<Layer>, SortLayersByZ> mLayers;
447
448 // Mapping between layer index in array of hwc_display_contents_1*
449 // passed to HWC1 during validate/set and Layer object.
450 std::unordered_map<size_t, std::shared_ptr<Layer>> mHwc1LayerMap;
451
452 // All communication with HWC1 via prepare/set is done with one
453 // alloc. This pointer is pointing to a pool of hwc_rect_t.
454 size_t mNumAvailableRects;
455 hwc_rect_t* mNextAvailableRect;
456
457 // True if any of the Layers contained in this Display have been
458 // updated with anything other than a buffer since last call to
459 // Display::set()
460 bool mGeometryChanged;
461 };
462
463 // Utility template calling a Display object method directly based on the
464 // hwc2_display_t displayId parameter.
465 template <typename ...Args>
466 static int32_t callDisplayFunction(hwc2_device_t* device,
467 hwc2_display_t displayId, HWC2::Error (Display::*member)(Args...),
468 Args... args) {
469 auto display = getAdapter(device)->getDisplay(displayId);
470 if (!display) {
471 return static_cast<int32_t>(HWC2::Error::BadDisplay);
472 }
473 auto error = ((*display).*member)(std::forward<Args>(args)...);
474 return static_cast<int32_t>(error);
475 }
476
477 template <typename MF, MF memFunc, typename ...Args>
478 static int32_t displayHook(hwc2_device_t* device, hwc2_display_t displayId,
479 Args... args) {
480 return HWC2On1Adapter::callDisplayFunction(device, displayId, memFunc,
481 std::forward<Args>(args)...);
482 }
483
484 static int32_t getDisplayAttributeHook(hwc2_device_t* device,
485 hwc2_display_t display, hwc2_config_t config,
486 int32_t intAttribute, int32_t* outValue) {
487 auto attribute = static_cast<HWC2::Attribute>(intAttribute);
488 return callDisplayFunction(device, display, &Display::getAttribute,
489 config, attribute, outValue);
490 }
491
492 static int32_t setColorTransformHook(hwc2_device_t* device,
493 hwc2_display_t display, const float* /*matrix*/,
494 int32_t /*android_color_transform_t*/ intHint) {
495 // We intentionally throw away the matrix, because if the hint is
496 // anything other than IDENTITY, we have to fall back to client
497 // composition anyway
498 auto hint = static_cast<android_color_transform_t>(intHint);
499 return callDisplayFunction(device, display, &Display::setColorTransform,
500 hint);
501 }
502
503 static int32_t setColorModeHook(hwc2_device_t* device,
504 hwc2_display_t display, int32_t /*android_color_mode_t*/ intMode) {
505 auto mode = static_cast<android_color_mode_t>(intMode);
506 return callDisplayFunction(device, display, &Display::setColorMode,
507 mode);
508 }
509
510 static int32_t setPowerModeHook(hwc2_device_t* device,
511 hwc2_display_t display, int32_t intMode) {
512 auto mode = static_cast<HWC2::PowerMode>(intMode);
513 return callDisplayFunction(device, display, &Display::setPowerMode,
514 mode);
515 }
516
517 static int32_t setVsyncEnabledHook(hwc2_device_t* device,
518 hwc2_display_t display, int32_t intEnabled) {
519 auto enabled = static_cast<HWC2::Vsync>(intEnabled);
520 return callDisplayFunction(device, display, &Display::setVsyncEnabled,
521 enabled);
522 }
523
524 class Layer {
525 public:
526 explicit Layer(Display& display);
527
528 bool operator==(const Layer& other) { return mId == other.mId; }
529 bool operator!=(const Layer& other) { return !(*this == other); }
530
531 hwc2_layer_t getId() const { return mId; }
532 Display& getDisplay() const { return mDisplay; }
533
534 // HWC2 Layer functions
535 HWC2::Error setBuffer(buffer_handle_t buffer, int32_t acquireFence);
536 HWC2::Error setCursorPosition(int32_t x, int32_t y);
537 HWC2::Error setSurfaceDamage(hwc_region_t damage);
538
539 // HWC2 Layer state functions
540 HWC2::Error setBlendMode(HWC2::BlendMode mode);
541 HWC2::Error setColor(hwc_color_t color);
542 HWC2::Error setCompositionType(HWC2::Composition type);
543 HWC2::Error setDataspace(android_dataspace_t dataspace);
544 HWC2::Error setDisplayFrame(hwc_rect_t frame);
545 HWC2::Error setPlaneAlpha(float alpha);
546 HWC2::Error setSidebandStream(const native_handle_t* stream);
547 HWC2::Error setSourceCrop(hwc_frect_t crop);
548 HWC2::Error setTransform(HWC2::Transform transform);
549 HWC2::Error setVisibleRegion(hwc_region_t visible);
550 HWC2::Error setZ(uint32_t z);
551
552 HWC2::Composition getCompositionType() const {
553 return mCompositionType;
554 }
555 uint32_t getZ() const { return mZ; }
556
557 void addReleaseFence(int fenceFd);
558 const sp<MiniFence>& getReleaseFence() const;
559
560 void setHwc1Id(size_t id) { mHwc1Id = id; }
561 size_t getHwc1Id() const { return mHwc1Id; }
562
563 // Write state to HWC1 communication struct.
564 void applyState(struct hwc_layer_1& hwc1Layer);
565
566 std::string dump() const;
567
568 std::size_t getNumVisibleRegions() { return mVisibleRegion.size(); }
569
570 std::size_t getNumSurfaceDamages() { return mSurfaceDamage.size(); }
571
572 // True if a layer cannot be properly rendered by the device due
573 // to usage of SolidColor (a.k.a BackgroundColor in HWC1).
574 bool hasUnsupportedBackgroundColor() {
575 return (mCompositionType == HWC2::Composition::SolidColor &&
576 !mDisplay.getDevice().supportsBackgroundColor());
577 }
578 private:
579 void applyCommonState(struct hwc_layer_1& hwc1Layer);
580 void applySolidColorState(struct hwc_layer_1& hwc1Layer);
581 void applySidebandState(struct hwc_layer_1& hwc1Layer);
582 void applyBufferState(struct hwc_layer_1& hwc1Layer);
583 void applyCompositionType(struct hwc_layer_1& hwc1Layer);
584
585 static std::atomic<hwc2_layer_t> sNextId;
586 const hwc2_layer_t mId;
587 Display& mDisplay;
588
589 FencedBuffer mBuffer;
590 std::vector<hwc_rect_t> mSurfaceDamage;
591
592 HWC2::BlendMode mBlendMode;
593 hwc_color_t mColor;
594 HWC2::Composition mCompositionType;
595 hwc_rect_t mDisplayFrame;
596 float mPlaneAlpha;
597 const native_handle_t* mSidebandStream;
598 hwc_frect_t mSourceCrop;
599 HWC2::Transform mTransform;
600 std::vector<hwc_rect_t> mVisibleRegion;
601
602 uint32_t mZ;
603
604 DeferredFence mReleaseFence;
605
606 size_t mHwc1Id;
607 bool mHasUnsupportedPlaneAlpha;
608 };
609
610 // Utility tempate calling a Layer object method based on ID parameters:
611 // hwc2_display_t displayId
612 // and
613 // hwc2_layer_t layerId
614 template <typename ...Args>
615 static int32_t callLayerFunction(hwc2_device_t* device,
616 hwc2_display_t displayId, hwc2_layer_t layerId,
617 HWC2::Error (Layer::*member)(Args...), Args... args) {
618 auto result = getAdapter(device)->getLayer(displayId, layerId);
619 auto error = std::get<HWC2::Error>(result);
620 if (error == HWC2::Error::None) {
621 auto layer = std::get<Layer*>(result);
622 error = ((*layer).*member)(std::forward<Args>(args)...);
623 }
624 return static_cast<int32_t>(error);
625 }
626
627 template <typename MF, MF memFunc, typename ...Args>
628 static int32_t layerHook(hwc2_device_t* device, hwc2_display_t displayId,
629 hwc2_layer_t layerId, Args... args) {
630 return HWC2On1Adapter::callLayerFunction(device, displayId, layerId,
631 memFunc, std::forward<Args>(args)...);
632 }
633
634 // Layer state functions
635
636 static int32_t setLayerBlendModeHook(hwc2_device_t* device,
637 hwc2_display_t display, hwc2_layer_t layer, int32_t intMode) {
638 auto mode = static_cast<HWC2::BlendMode>(intMode);
639 return callLayerFunction(device, display, layer,
640 &Layer::setBlendMode, mode);
641 }
642
643 static int32_t setLayerCompositionTypeHook(hwc2_device_t* device,
644 hwc2_display_t display, hwc2_layer_t layer, int32_t intType) {
645 auto type = static_cast<HWC2::Composition>(intType);
646 return callLayerFunction(device, display, layer,
647 &Layer::setCompositionType, type);
648 }
649
650 static int32_t setLayerDataspaceHook(hwc2_device_t* device,
651 hwc2_display_t display, hwc2_layer_t layer, int32_t intDataspace) {
652 auto dataspace = static_cast<android_dataspace_t>(intDataspace);
653 return callLayerFunction(device, display, layer, &Layer::setDataspace,
654 dataspace);
655 }
656
657 static int32_t setLayerTransformHook(hwc2_device_t* device,
658 hwc2_display_t display, hwc2_layer_t layer, int32_t intTransform) {
659 auto transform = static_cast<HWC2::Transform>(intTransform);
660 return callLayerFunction(device, display, layer, &Layer::setTransform,
661 transform);
662 }
663
664 static int32_t setLayerZOrderHook(hwc2_device_t* device,
665 hwc2_display_t display, hwc2_layer_t layer, uint32_t z) {
666 return callDisplayFunction(device, display, &Display::updateLayerZ,
667 layer, z);
668 }
669
670 // Adapter internals
671
672 void populateCapabilities();
673 Display* getDisplay(hwc2_display_t id);
674 std::tuple<Layer*, HWC2::Error> getLayer(hwc2_display_t displayId,
675 hwc2_layer_t layerId);
676 void populatePrimary();
677
678 bool prepareAllDisplays();
679 std::vector<struct hwc_display_contents_1*> mHwc1Contents;
680 HWC2::Error setAllDisplays();
681
682 // Callbacks
683 void hwc1Invalidate();
684 void hwc1Vsync(int hwc1DisplayId, int64_t timestamp);
685 void hwc1Hotplug(int hwc1DisplayId, int connected);
686
687 // These are set in the constructor and before any asynchronous events are
688 // possible
689
690 struct hwc_composer_device_1* const mHwc1Device;
691 const uint8_t mHwc1MinorVersion;
692 bool mHwc1SupportsVirtualDisplays;
693 bool mHwc1SupportsBackgroundColor;
694
695 class Callbacks;
696 const std::unique_ptr<Callbacks> mHwc1Callbacks;
697
698 std::unordered_set<HWC2::Capability> mCapabilities;
699
700 // These are only accessed from the main SurfaceFlinger thread (not from
701 // callbacks or dump
702
703 std::map<hwc2_layer_t, std::shared_ptr<Layer>> mLayers;
704
705 // A HWC1 supports only one virtual display.
706 std::shared_ptr<Display> mHwc1VirtualDisplay;
707
708 // These are potentially accessed from multiple threads, and are protected
709 // by this mutex. This needs to be recursive, since the HWC1 implementation
710 // can call back into the invalidate callback on the same thread that is
711 // calling prepare.
712 std::recursive_timed_mutex mStateMutex;
713
714 struct CallbackInfo {
715 hwc2_callback_data_t data;
716 hwc2_function_pointer_t pointer;
717 };
718 std::unordered_map<HWC2::Callback, CallbackInfo> mCallbacks;
719 bool mHasPendingInvalidate;
720
721 // There is a small gap between the time the HWC1 module is started and
722 // when the callbacks for vsync and hotplugs are registered by the
723 // HWC2on1Adapter. To prevent losing events they are stored in these arrays
724 // and fed to the callback as soon as possible.
725 std::vector<std::pair<int, int64_t>> mPendingVsyncs;
726 std::vector<std::pair<int, int>> mPendingHotplugs;
727
728 // Mapping between HWC1 display id and Display objects.
729 std::map<hwc2_display_t, std::shared_ptr<Display>> mDisplays;
730
731 // Map HWC1 display type (HWC_DISPLAY_PRIMARY, HWC_DISPLAY_EXTERNAL,
732 // HWC_DISPLAY_VIRTUAL) to Display IDs generated by HWC2on1Adapter objects.
733 std::unordered_map<int, hwc2_display_t> mHwc1DisplayMap;
734};
735
736} // namespace android
737
738#endif
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/include/hwc2on1adapter/MiniFence.h b/graphics/composer/2.1/utils/hwc2on1adapter/include/hwc2on1adapter/MiniFence.h
new file mode 100644
index 00000000..75de764d
--- /dev/null
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/include/hwc2on1adapter/MiniFence.h
@@ -0,0 +1,59 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef MINIFENCE_H
18#define MINIFENCE_H
19
20#include <utils/RefBase.h>
21
22namespace android {
23
24/* MiniFence is a minimal re-implementation of Fence from libui. It exists to
25 * avoid linking the HWC2on1Adapter to libui and satisfy Treble requirements.
26 */
27class MiniFence : public LightRefBase<MiniFence> {
28public:
29 static const sp<MiniFence> NO_FENCE;
30
31 // Construct a new MiniFence object with an invalid file descriptor.
32 MiniFence();
33
34 // Construct a new MiniFence object to manage a given fence file descriptor.
35 // When the new MiniFence object is destructed the file descriptor will be
36 // closed.
37 explicit MiniFence(int fenceFd);
38
39 // Not copyable or movable.
40 MiniFence(const MiniFence& rhs) = delete;
41 MiniFence& operator=(const MiniFence& rhs) = delete;
42 MiniFence(MiniFence&& rhs) = delete;
43 MiniFence& operator=(MiniFence&& rhs) = delete;
44
45 // Return a duplicate of the fence file descriptor. The caller is
46 // responsible for closing the returned file descriptor. On error, -1 will
47 // be returned and errno will indicate the problem.
48 int dup() const;
49
50private:
51 // Only allow instantiation using ref counting.
52 friend class LightRefBase<MiniFence>;
53 ~MiniFence();
54
55 int mFenceFd;
56
57};
58}
59#endif //MINIFENCE_H
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
new file mode 100644
index 00000000..73a41f7f
--- /dev/null
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
@@ -0,0 +1,33 @@
1// Copyright 2010 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15cc_library_shared {
16 name: "libhwc2onfbadapter",
17 vendor: true,
18
19 clang: true,
20 cflags: [
21 "-Wall",
22 "-Wextra",
23 "-Werror",
24 ],
25
26 srcs: [
27 "HWC2OnFbAdapter.cpp",
28 ],
29
30 header_libs: ["libhardware_headers"],
31 shared_libs: ["liblog", "libsync"],
32 export_include_dirs: ["include"],
33}
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp b/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp
new file mode 100644
index 00000000..7c9e6518
--- /dev/null
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp
@@ -0,0 +1,887 @@
1/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "HWC2OnFbAdapter"
18
19//#define LOG_NDEBUG 0
20
21#include "hwc2onfbadapter/HWC2OnFbAdapter.h"
22
23#include <algorithm>
24#include <type_traits>
25
26#include <inttypes.h>
27#include <time.h>
28#include <sys/prctl.h>
29#include <unistd.h> // for close
30
31#include <hardware/fb.h>
32#include <log/log.h>
33#include <sync/sync.h>
34
35namespace android {
36
37namespace {
38
39void dumpHook(hwc2_device_t* device, uint32_t* outSize, char* outBuffer) {
40 auto& adapter = HWC2OnFbAdapter::cast(device);
41 if (outBuffer) {
42 *outSize = adapter.getDebugString().copy(outBuffer, *outSize);
43 } else {
44 adapter.updateDebugString();
45 *outSize = adapter.getDebugString().size();
46 }
47}
48
49int32_t registerCallbackHook(hwc2_device_t* device, int32_t descriptor,
50 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
51 auto& adapter = HWC2OnFbAdapter::cast(device);
52 switch (descriptor) {
53 case HWC2_CALLBACK_HOTPLUG:
54 if (pointer) {
55 reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer)(callbackData, adapter.getDisplayId(),
56 HWC2_CONNECTION_CONNECTED);
57 }
58 break;
59 case HWC2_CALLBACK_REFRESH:
60 break;
61 case HWC2_CALLBACK_VSYNC:
62 adapter.setVsyncCallback(reinterpret_cast<HWC2_PFN_VSYNC>(pointer), callbackData);
63 break;
64 default:
65 return HWC2_ERROR_BAD_PARAMETER;
66 }
67
68 return HWC2_ERROR_NONE;
69}
70
71uint32_t getMaxVirtualDisplayCountHook(hwc2_device_t* /*device*/) {
72 return 0;
73}
74
75int32_t createVirtualDisplayHook(hwc2_device_t* /*device*/, uint32_t /*width*/, uint32_t /*height*/,
76 int32_t* /*format*/, hwc2_display_t* /*outDisplay*/) {
77 return HWC2_ERROR_NO_RESOURCES;
78}
79
80int32_t destroyVirtualDisplayHook(hwc2_device_t* /*device*/, hwc2_display_t /*display*/) {
81 return HWC2_ERROR_BAD_DISPLAY;
82}
83
84int32_t setOutputBufferHook(hwc2_device_t* /*device*/, hwc2_display_t /*display*/,
85 buffer_handle_t /*buffer*/, int32_t /*releaseFence*/) {
86 return HWC2_ERROR_BAD_DISPLAY;
87}
88
89int32_t getDisplayNameHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outSize,
90 char* outName) {
91 auto& adapter = HWC2OnFbAdapter::cast(device);
92 if (adapter.getDisplayId() != display) {
93 return HWC2_ERROR_BAD_DISPLAY;
94 }
95
96 const auto& info = adapter.getInfo();
97 if (outName) {
98 *outSize = info.name.copy(outName, *outSize);
99 } else {
100 *outSize = info.name.size();
101 }
102
103 return HWC2_ERROR_NONE;
104}
105
106int32_t getDisplayTypeHook(hwc2_device_t* device, hwc2_display_t display, int32_t* outType) {
107 auto& adapter = HWC2OnFbAdapter::cast(device);
108 if (adapter.getDisplayId() != display) {
109 return HWC2_ERROR_BAD_DISPLAY;
110 }
111
112 *outType = HWC2_DISPLAY_TYPE_PHYSICAL;
113 return HWC2_ERROR_NONE;
114}
115
116int32_t getDozeSupportHook(hwc2_device_t* device, hwc2_display_t display, int32_t* outSupport) {
117 auto& adapter = HWC2OnFbAdapter::cast(device);
118 if (adapter.getDisplayId() != display) {
119 return HWC2_ERROR_BAD_DISPLAY;
120 }
121
122 *outSupport = 0;
123 return HWC2_ERROR_NONE;
124}
125
126int32_t getHdrCapabilitiesHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumTypes,
127 int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
128 float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
129 auto& adapter = HWC2OnFbAdapter::cast(device);
130 if (adapter.getDisplayId() != display) {
131 return HWC2_ERROR_BAD_DISPLAY;
132 }
133
134 *outNumTypes = 0;
135 return HWC2_ERROR_NONE;
136}
137
138int32_t setPowerModeHook(hwc2_device_t* device, hwc2_display_t display, int32_t /*mode*/) {
139 auto& adapter = HWC2OnFbAdapter::cast(device);
140 if (adapter.getDisplayId() != display) {
141 return HWC2_ERROR_BAD_DISPLAY;
142 }
143
144 // pretend that it works
145 return HWC2_ERROR_NONE;
146}
147
148int32_t setVsyncEnabledHook(hwc2_device_t* device, hwc2_display_t display, int32_t enabled) {
149 auto& adapter = HWC2OnFbAdapter::cast(device);
150 if (adapter.getDisplayId() != display) {
151 return HWC2_ERROR_BAD_DISPLAY;
152 }
153
154 adapter.enableVsync(enabled == HWC2_VSYNC_ENABLE);
155 return HWC2_ERROR_NONE;
156}
157
158int32_t getColorModesHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumModes,
159 int32_t* outModes) {
160 auto& adapter = HWC2OnFbAdapter::cast(device);
161 if (adapter.getDisplayId() != display) {
162 return HWC2_ERROR_BAD_DISPLAY;
163 }
164
165 if (outModes) {
166 if (*outNumModes > 0) {
167 outModes[0] = HAL_COLOR_MODE_NATIVE;
168 *outNumModes = 1;
169 }
170 } else {
171 *outNumModes = 1;
172 }
173
174 return HWC2_ERROR_NONE;
175}
176
177int32_t setColorModeHook(hwc2_device_t* device, hwc2_display_t display, int32_t mode) {
178 auto& adapter = HWC2OnFbAdapter::cast(device);
179 if (adapter.getDisplayId() != display) {
180 return HWC2_ERROR_BAD_DISPLAY;
181 }
182 if (mode != HAL_COLOR_MODE_NATIVE) {
183 return HWC2_ERROR_BAD_PARAMETER;
184 }
185
186 return HWC2_ERROR_NONE;
187}
188
189int32_t setColorTransformHook(hwc2_device_t* device, hwc2_display_t display,
190 const float* /*matrix*/, int32_t /*hint*/) {
191 auto& adapter = HWC2OnFbAdapter::cast(device);
192 if (adapter.getDisplayId() != display) {
193 return HWC2_ERROR_BAD_DISPLAY;
194 }
195
196 // we always force client composition
197 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
198 return HWC2_ERROR_NONE;
199}
200
201int32_t getClientTargetSupportHook(hwc2_device_t* device, hwc2_display_t display, uint32_t width,
202 uint32_t height, int32_t format, int32_t dataspace) {
203 auto& adapter = HWC2OnFbAdapter::cast(device);
204 if (adapter.getDisplayId() != display) {
205 return HWC2_ERROR_BAD_DISPLAY;
206 }
207 if (dataspace != HAL_DATASPACE_UNKNOWN) {
208 return HWC2_ERROR_UNSUPPORTED;
209 }
210
211 const auto& info = adapter.getInfo();
212 return (info.width == width && info.height == height && info.format == format)
213 ? HWC2_ERROR_NONE
214 : HWC2_ERROR_UNSUPPORTED;
215}
216
217int32_t setClientTargetHook(hwc2_device_t* device, hwc2_display_t display, buffer_handle_t target,
218 int32_t acquireFence, int32_t dataspace, hwc_region_t /*damage*/) {
219 if (acquireFence >= 0) {
220 sync_wait(acquireFence, -1);
221 close(acquireFence);
222 }
223
224 auto& adapter = HWC2OnFbAdapter::cast(device);
225 if (adapter.getDisplayId() != display) {
226 return HWC2_ERROR_BAD_DISPLAY;
227 }
228 if (dataspace != HAL_DATASPACE_UNKNOWN) {
229 return HWC2_ERROR_BAD_PARAMETER;
230 }
231
232 // no state change
233 adapter.setBuffer(target);
234 return HWC2_ERROR_NONE;
235}
236
237int32_t getDisplayConfigsHook(hwc2_device_t* device, hwc2_display_t display,
238 uint32_t* outNumConfigs, hwc2_config_t* outConfigs) {
239 auto& adapter = HWC2OnFbAdapter::cast(device);
240 if (adapter.getDisplayId() != display) {
241 return HWC2_ERROR_BAD_DISPLAY;
242 }
243
244 if (outConfigs) {
245 if (*outNumConfigs > 0) {
246 outConfigs[0] = adapter.getConfigId();
247 *outNumConfigs = 1;
248 }
249 } else {
250 *outNumConfigs = 1;
251 }
252
253 return HWC2_ERROR_NONE;
254}
255
256int32_t getDisplayAttributeHook(hwc2_device_t* device, hwc2_display_t display, hwc2_config_t config,
257 int32_t attribute, int32_t* outValue) {
258 auto& adapter = HWC2OnFbAdapter::cast(device);
259 if (adapter.getDisplayId() != display) {
260 return HWC2_ERROR_BAD_DISPLAY;
261 }
262 if (adapter.getConfigId() != config) {
263 return HWC2_ERROR_BAD_CONFIG;
264 }
265
266 const auto& info = adapter.getInfo();
267 switch (attribute) {
268 case HWC2_ATTRIBUTE_WIDTH:
269 *outValue = int32_t(info.width);
270 break;
271 case HWC2_ATTRIBUTE_HEIGHT:
272 *outValue = int32_t(info.height);
273 break;
274 case HWC2_ATTRIBUTE_VSYNC_PERIOD:
275 *outValue = int32_t(info.vsync_period_ns);
276 break;
277 case HWC2_ATTRIBUTE_DPI_X:
278 *outValue = int32_t(info.xdpi_scaled);
279 break;
280 case HWC2_ATTRIBUTE_DPI_Y:
281 *outValue = int32_t(info.ydpi_scaled);
282 break;
283 default:
284 return HWC2_ERROR_BAD_PARAMETER;
285 }
286
287 return HWC2_ERROR_NONE;
288}
289
290int32_t getActiveConfigHook(hwc2_device_t* device, hwc2_display_t display,
291 hwc2_config_t* outConfig) {
292 auto& adapter = HWC2OnFbAdapter::cast(device);
293 if (adapter.getDisplayId() != display) {
294 return HWC2_ERROR_BAD_DISPLAY;
295 }
296
297 *outConfig = adapter.getConfigId();
298 return HWC2_ERROR_NONE;
299}
300
301int32_t setActiveConfigHook(hwc2_device_t* device, hwc2_display_t display, hwc2_config_t config) {
302 auto& adapter = HWC2OnFbAdapter::cast(device);
303 if (adapter.getDisplayId() != display) {
304 return HWC2_ERROR_BAD_DISPLAY;
305 }
306 if (adapter.getConfigId() != config) {
307 return HWC2_ERROR_BAD_CONFIG;
308 }
309
310 return HWC2_ERROR_NONE;
311}
312
313int32_t validateDisplayHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumTypes,
314 uint32_t* outNumRequests) {
315 auto& adapter = HWC2OnFbAdapter::cast(device);
316 if (adapter.getDisplayId() != display) {
317 return HWC2_ERROR_BAD_DISPLAY;
318 }
319
320 const auto& dirtyLayers = adapter.getDirtyLayers();
321 *outNumTypes = dirtyLayers.size();
322 *outNumRequests = 0;
323
324 if (*outNumTypes > 0) {
325 adapter.setState(HWC2OnFbAdapter::State::VALIDATED_WITH_CHANGES);
326 return HWC2_ERROR_HAS_CHANGES;
327 } else {
328 adapter.setState(HWC2OnFbAdapter::State::VALIDATED);
329 return HWC2_ERROR_NONE;
330 }
331}
332
333int32_t getChangedCompositionTypesHook(hwc2_device_t* device, hwc2_display_t display,
334 uint32_t* outNumElements, hwc2_layer_t* outLayers,
335 int32_t* outTypes) {
336 auto& adapter = HWC2OnFbAdapter::cast(device);
337 if (adapter.getDisplayId() != display) {
338 return HWC2_ERROR_BAD_DISPLAY;
339 }
340 if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) {
341 return HWC2_ERROR_NOT_VALIDATED;
342 }
343
344 // request client composition for all layers
345 const auto& dirtyLayers = adapter.getDirtyLayers();
346 if (outLayers && outTypes) {
347 *outNumElements = std::min(*outNumElements, uint32_t(dirtyLayers.size()));
348 auto iter = dirtyLayers.cbegin();
349 for (uint32_t i = 0; i < *outNumElements; i++) {
350 outLayers[i] = *iter++;
351 outTypes[i] = HWC2_COMPOSITION_CLIENT;
352 }
353 } else {
354 *outNumElements = dirtyLayers.size();
355 }
356
357 return HWC2_ERROR_NONE;
358}
359
360int32_t getDisplayRequestsHook(hwc2_device_t* device, hwc2_display_t display,
361 int32_t* outDisplayRequests, uint32_t* outNumElements,
362 hwc2_layer_t* /*outLayers*/, int32_t* /*outLayerRequests*/) {
363 auto& adapter = HWC2OnFbAdapter::cast(device);
364 if (adapter.getDisplayId() != display) {
365 return HWC2_ERROR_BAD_DISPLAY;
366 }
367 if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) {
368 return HWC2_ERROR_NOT_VALIDATED;
369 }
370
371 *outDisplayRequests = 0;
372 *outNumElements = 0;
373 return HWC2_ERROR_NONE;
374}
375
376int32_t acceptDisplayChangesHook(hwc2_device_t* device, hwc2_display_t display) {
377 auto& adapter = HWC2OnFbAdapter::cast(device);
378 if (adapter.getDisplayId() != display) {
379 return HWC2_ERROR_BAD_DISPLAY;
380 }
381 if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) {
382 return HWC2_ERROR_NOT_VALIDATED;
383 }
384
385 adapter.clearDirtyLayers();
386 adapter.setState(HWC2OnFbAdapter::State::VALIDATED);
387 return HWC2_ERROR_NONE;
388}
389
390int32_t presentDisplayHook(hwc2_device_t* device, hwc2_display_t display,
391 int32_t* outPresentFence) {
392 auto& adapter = HWC2OnFbAdapter::cast(device);
393 if (adapter.getDisplayId() != display) {
394 return HWC2_ERROR_BAD_DISPLAY;
395 }
396 if (adapter.getState() != HWC2OnFbAdapter::State::VALIDATED) {
397 return HWC2_ERROR_NOT_VALIDATED;
398 }
399
400 adapter.postBuffer();
401 *outPresentFence = -1;
402
403 return HWC2_ERROR_NONE;
404}
405
406int32_t getReleaseFencesHook(hwc2_device_t* device, hwc2_display_t display,
407 uint32_t* outNumElements, hwc2_layer_t* /*outLayers*/,
408 int32_t* /*outFences*/) {
409 auto& adapter = HWC2OnFbAdapter::cast(device);
410 if (adapter.getDisplayId() != display) {
411 return HWC2_ERROR_BAD_DISPLAY;
412 }
413
414 *outNumElements = 0;
415 return HWC2_ERROR_NONE;
416}
417
418int32_t createLayerHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t* outLayer) {
419 auto& adapter = HWC2OnFbAdapter::cast(device);
420 if (adapter.getDisplayId() != display) {
421 return HWC2_ERROR_BAD_DISPLAY;
422 }
423
424 *outLayer = adapter.addLayer();
425 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
426 return HWC2_ERROR_NONE;
427}
428
429int32_t destroyLayerHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer) {
430 auto& adapter = HWC2OnFbAdapter::cast(device);
431 if (adapter.getDisplayId() != display) {
432 return HWC2_ERROR_BAD_DISPLAY;
433 }
434
435 if (adapter.removeLayer(layer)) {
436 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
437 return HWC2_ERROR_NONE;
438 } else {
439 return HWC2_ERROR_BAD_LAYER;
440 }
441}
442
443int32_t setCursorPositionHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t /*layer*/,
444 int32_t /*x*/, int32_t /*y*/) {
445 auto& adapter = HWC2OnFbAdapter::cast(device);
446 if (adapter.getDisplayId() != display) {
447 return HWC2_ERROR_BAD_DISPLAY;
448 }
449
450 // always an error
451 return HWC2_ERROR_BAD_LAYER;
452}
453
454int32_t setLayerBufferHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
455 buffer_handle_t /*buffer*/, int32_t acquireFence) {
456 if (acquireFence >= 0) {
457 sync_wait(acquireFence, -1);
458 close(acquireFence);
459 }
460
461 auto& adapter = HWC2OnFbAdapter::cast(device);
462 if (adapter.getDisplayId() != display) {
463 return HWC2_ERROR_BAD_DISPLAY;
464 }
465 if (!adapter.hasLayer(layer)) {
466 return HWC2_ERROR_BAD_LAYER;
467 }
468
469 // no state change
470 return HWC2_ERROR_NONE;
471}
472
473int32_t setLayerSurfaceDamageHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
474 hwc_region_t /*damage*/) {
475 auto& adapter = HWC2OnFbAdapter::cast(device);
476 if (adapter.getDisplayId() != display) {
477 return HWC2_ERROR_BAD_DISPLAY;
478 }
479 if (!adapter.hasLayer(layer)) {
480 return HWC2_ERROR_BAD_LAYER;
481 }
482
483 // no state change
484 return HWC2_ERROR_NONE;
485}
486
487int32_t setLayerCompositionTypeHook(hwc2_device_t* device, hwc2_display_t display,
488 hwc2_layer_t layer, int32_t type) {
489 auto& adapter = HWC2OnFbAdapter::cast(device);
490 if (adapter.getDisplayId() != display) {
491 return HWC2_ERROR_BAD_DISPLAY;
492 }
493 if (!adapter.markLayerDirty(layer, type != HWC2_COMPOSITION_CLIENT)) {
494 return HWC2_ERROR_BAD_LAYER;
495 }
496
497 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
498 return HWC2_ERROR_NONE;
499}
500
501template <typename... Args>
502int32_t setLayerStateHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
503 Args... /*args*/) {
504 auto& adapter = HWC2OnFbAdapter::cast(device);
505 if (adapter.getDisplayId() != display) {
506 return HWC2_ERROR_BAD_DISPLAY;
507 }
508 if (!adapter.hasLayer(layer)) {
509 return HWC2_ERROR_BAD_LAYER;
510 }
511
512 adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
513 return HWC2_ERROR_NONE;
514}
515
516template <typename PFN, typename T>
517static hwc2_function_pointer_t asFP(T function) {
518 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
519 return reinterpret_cast<hwc2_function_pointer_t>(function);
520}
521
522hwc2_function_pointer_t getFunctionHook(hwc2_device_t* /*device*/, int32_t descriptor) {
523 switch (descriptor) {
524 // global functions
525 case HWC2_FUNCTION_DUMP:
526 return asFP<HWC2_PFN_DUMP>(dumpHook);
527 case HWC2_FUNCTION_REGISTER_CALLBACK:
528 return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
529
530 // virtual display functions
531 case HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT:
532 return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(getMaxVirtualDisplayCountHook);
533 case HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY:
534 return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(createVirtualDisplayHook);
535 case HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY:
536 return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(destroyVirtualDisplayHook);
537 case HWC2_FUNCTION_SET_OUTPUT_BUFFER:
538 return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(setOutputBufferHook);
539
540 // display functions
541 case HWC2_FUNCTION_GET_DISPLAY_NAME:
542 return asFP<HWC2_PFN_GET_DISPLAY_NAME>(getDisplayNameHook);
543 case HWC2_FUNCTION_GET_DISPLAY_TYPE:
544 return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(getDisplayTypeHook);
545 case HWC2_FUNCTION_GET_DOZE_SUPPORT:
546 return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(getDozeSupportHook);
547 case HWC2_FUNCTION_GET_HDR_CAPABILITIES:
548 return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(getHdrCapabilitiesHook);
549 case HWC2_FUNCTION_SET_POWER_MODE:
550 return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
551 case HWC2_FUNCTION_SET_VSYNC_ENABLED:
552 return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook);
553 case HWC2_FUNCTION_GET_COLOR_MODES:
554 return asFP<HWC2_PFN_GET_COLOR_MODES>(getColorModesHook);
555 case HWC2_FUNCTION_SET_COLOR_MODE:
556 return asFP<HWC2_PFN_SET_COLOR_MODE>(setColorModeHook);
557 case HWC2_FUNCTION_SET_COLOR_TRANSFORM:
558 return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
559 case HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT:
560 return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(getClientTargetSupportHook);
561 case HWC2_FUNCTION_SET_CLIENT_TARGET:
562 return asFP<HWC2_PFN_SET_CLIENT_TARGET>(setClientTargetHook);
563
564 // config functions
565 case HWC2_FUNCTION_GET_DISPLAY_CONFIGS:
566 return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(getDisplayConfigsHook);
567 case HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE:
568 return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(getDisplayAttributeHook);
569 case HWC2_FUNCTION_GET_ACTIVE_CONFIG:
570 return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(getActiveConfigHook);
571 case HWC2_FUNCTION_SET_ACTIVE_CONFIG:
572 return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(setActiveConfigHook);
573
574 // validate/present functions
575 case HWC2_FUNCTION_VALIDATE_DISPLAY:
576 return asFP<HWC2_PFN_VALIDATE_DISPLAY>(validateDisplayHook);
577 case HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES:
578 return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(getChangedCompositionTypesHook);
579 case HWC2_FUNCTION_GET_DISPLAY_REQUESTS:
580 return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(getDisplayRequestsHook);
581 case HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES:
582 return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(acceptDisplayChangesHook);
583 case HWC2_FUNCTION_PRESENT_DISPLAY:
584 return asFP<HWC2_PFN_PRESENT_DISPLAY>(presentDisplayHook);
585 case HWC2_FUNCTION_GET_RELEASE_FENCES:
586 return asFP<HWC2_PFN_GET_RELEASE_FENCES>(getReleaseFencesHook);
587
588 // layer create/destroy
589 case HWC2_FUNCTION_CREATE_LAYER:
590 return asFP<HWC2_PFN_CREATE_LAYER>(createLayerHook);
591 case HWC2_FUNCTION_DESTROY_LAYER:
592 return asFP<HWC2_PFN_DESTROY_LAYER>(destroyLayerHook);
593
594 // layer functions; validateDisplay not required
595 case HWC2_FUNCTION_SET_CURSOR_POSITION:
596 return asFP<HWC2_PFN_SET_CURSOR_POSITION>(setCursorPositionHook);
597 case HWC2_FUNCTION_SET_LAYER_BUFFER:
598 return asFP<HWC2_PFN_SET_LAYER_BUFFER>(setLayerBufferHook);
599 case HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE:
600 return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(setLayerSurfaceDamageHook);
601
602 // layer state functions; validateDisplay required
603 case HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE:
604 return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(setLayerCompositionTypeHook);
605 case HWC2_FUNCTION_SET_LAYER_BLEND_MODE:
606 return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(setLayerStateHook<int32_t>);
607 case HWC2_FUNCTION_SET_LAYER_COLOR:
608 return asFP<HWC2_PFN_SET_LAYER_COLOR>(setLayerStateHook<hwc_color_t>);
609 case HWC2_FUNCTION_SET_LAYER_DATASPACE:
610 return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerStateHook<int32_t>);
611 case HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME:
612 return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(setLayerStateHook<hwc_rect_t>);
613 case HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA:
614 return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(setLayerStateHook<float>);
615 case HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM:
616 return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(setLayerStateHook<buffer_handle_t>);
617 case HWC2_FUNCTION_SET_LAYER_SOURCE_CROP:
618 return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(setLayerStateHook<hwc_frect_t>);
619 case HWC2_FUNCTION_SET_LAYER_TRANSFORM:
620 return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerStateHook<int32_t>);
621 case HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION:
622 return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(setLayerStateHook<hwc_region_t>);
623 case HWC2_FUNCTION_SET_LAYER_Z_ORDER:
624 return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerStateHook<uint32_t>);
625
626 default:
627 ALOGE("unknown function descriptor %d", descriptor);
628 return nullptr;
629 }
630}
631
632void getCapabilitiesHook(hwc2_device_t* /*device*/, uint32_t* outCount,
633 int32_t* /*outCapabilities*/) {
634 *outCount = 0;
635}
636
637int closeHook(hw_device_t* device) {
638 auto& adapter = HWC2OnFbAdapter::cast(device);
639 adapter.close();
640 return 0;
641}
642
643} // anonymous namespace
644
645HWC2OnFbAdapter::HWC2OnFbAdapter(framebuffer_device_t* fbDevice)
646 : hwc2_device_t(), mFbDevice(fbDevice) {
647 common.close = closeHook;
648 hwc2_device::getCapabilities = getCapabilitiesHook;
649 hwc2_device::getFunction = getFunctionHook;
650
651 mFbInfo.name = "fbdev";
652 mFbInfo.width = mFbDevice->width;
653 mFbInfo.height = mFbDevice->height;
654 mFbInfo.format = mFbDevice->format;
655 mFbInfo.vsync_period_ns = int(1e9 / mFbDevice->fps);
656 mFbInfo.xdpi_scaled = int(mFbDevice->xdpi * 1000.0f);
657 mFbInfo.ydpi_scaled = int(mFbDevice->ydpi * 1000.0f);
658
659 mVsyncThread.start(0, mFbInfo.vsync_period_ns);
660}
661
662HWC2OnFbAdapter& HWC2OnFbAdapter::cast(hw_device_t* device) {
663 return *reinterpret_cast<HWC2OnFbAdapter*>(device);
664}
665
666HWC2OnFbAdapter& HWC2OnFbAdapter::cast(hwc2_device_t* device) {
667 return *reinterpret_cast<HWC2OnFbAdapter*>(device);
668}
669
670hwc2_display_t HWC2OnFbAdapter::getDisplayId() {
671 return 0;
672}
673
674hwc2_config_t HWC2OnFbAdapter::getConfigId() {
675 return 0;
676}
677
678void HWC2OnFbAdapter::close() {
679 mVsyncThread.stop();
680 framebuffer_close(mFbDevice);
681}
682
683const HWC2OnFbAdapter::Info& HWC2OnFbAdapter::getInfo() const {
684 return mFbInfo;
685}
686
687void HWC2OnFbAdapter::updateDebugString() {
688 if (mFbDevice->common.version >= 1 && mFbDevice->dump) {
689 char buffer[4096];
690 mFbDevice->dump(mFbDevice, buffer, sizeof(buffer));
691 buffer[sizeof(buffer) - 1] = '\0';
692
693 mDebugString = buffer;
694 }
695}
696
697const std::string& HWC2OnFbAdapter::getDebugString() const {
698 return mDebugString;
699}
700
701void HWC2OnFbAdapter::setState(State state) {
702 mState = state;
703}
704
705HWC2OnFbAdapter::State HWC2OnFbAdapter::getState() const {
706 return mState;
707}
708
709hwc2_layer_t HWC2OnFbAdapter::addLayer() {
710 hwc2_layer_t id = ++mNextLayerId;
711
712 mLayers.insert(id);
713 mDirtyLayers.insert(id);
714
715 return id;
716}
717
718bool HWC2OnFbAdapter::removeLayer(hwc2_layer_t layer) {
719 mDirtyLayers.erase(layer);
720 return mLayers.erase(layer);
721}
722
723bool HWC2OnFbAdapter::hasLayer(hwc2_layer_t layer) const {
724 return mLayers.count(layer) > 0;
725}
726
727bool HWC2OnFbAdapter::markLayerDirty(hwc2_layer_t layer, bool dirty) {
728 if (mLayers.count(layer) == 0) {
729 return false;
730 }
731
732 if (dirty) {
733 mDirtyLayers.insert(layer);
734 } else {
735 mDirtyLayers.erase(layer);
736 }
737
738 return true;
739}
740
741const std::unordered_set<hwc2_layer_t>& HWC2OnFbAdapter::getDirtyLayers() const {
742 return mDirtyLayers;
743}
744
745void HWC2OnFbAdapter::clearDirtyLayers() {
746 mDirtyLayers.clear();
747}
748
749/*
750 * For each frame, SurfaceFlinger
751 *
752 * - peforms GLES composition
753 * - calls eglSwapBuffers
754 * - calls setClientTarget, which maps to setBuffer below
755 * - calls presentDisplay, which maps to postBuffer below
756 *
757 * setBuffer should be a good place to call compositionComplete.
758 *
759 * As for post, it
760 *
761 * - schedules the buffer for presentation on the next vsync
762 * - locks the buffer and blocks all other users trying to lock it
763 *
764 * It does not give us a way to return a present fence, and we need to live
765 * with that. The implication is that, when we are double-buffered,
766 * SurfaceFlinger assumes the front buffer is available for rendering again
767 * immediately after the back buffer is posted. The locking semantics
768 * hopefully are strong enough that the rendering will be blocked.
769 */
770void HWC2OnFbAdapter::setBuffer(buffer_handle_t buffer) {
771 if (mFbDevice->compositionComplete) {
772 mFbDevice->compositionComplete(mFbDevice);
773 }
774 mBuffer = buffer;
775}
776
777bool HWC2OnFbAdapter::postBuffer() {
778 int error = 0;
779 if (mBuffer) {
780 error = mFbDevice->post(mFbDevice, mBuffer);
781 }
782
783 return error == 0;
784}
785
786void HWC2OnFbAdapter::setVsyncCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data) {
787 mVsyncThread.setCallback(callback, data);
788}
789
790void HWC2OnFbAdapter::enableVsync(bool enable) {
791 mVsyncThread.enableCallback(enable);
792}
793
794int64_t HWC2OnFbAdapter::VsyncThread::now() {
795 struct timespec ts;
796 clock_gettime(CLOCK_MONOTONIC, &ts);
797
798 return int64_t(ts.tv_sec) * 1'000'000'000 + ts.tv_nsec;
799}
800
801bool HWC2OnFbAdapter::VsyncThread::sleepUntil(int64_t t) {
802 struct timespec ts;
803 ts.tv_sec = t / 1'000'000'000;
804 ts.tv_nsec = t % 1'000'000'000;
805
806 while (true) {
807 int error = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, nullptr);
808 if (error) {
809 if (error == EINTR) {
810 continue;
811 }
812 return false;
813 } else {
814 return true;
815 }
816 }
817}
818
819void HWC2OnFbAdapter::VsyncThread::start(int64_t firstVsync, int64_t period) {
820 mNextVsync = firstVsync;
821 mPeriod = period;
822 mStarted = true;
823 mThread = std::thread(&VsyncThread::vsyncLoop, this);
824}
825
826void HWC2OnFbAdapter::VsyncThread::stop() {
827 {
828 std::lock_guard<std::mutex> lock(mMutex);
829 mStarted = false;
830 }
831 mCondition.notify_all();
832 mThread.join();
833}
834
835void HWC2OnFbAdapter::VsyncThread::setCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data) {
836 std::lock_guard<std::mutex> lock(mMutex);
837 mCallback = callback;
838 mCallbackData = data;
839}
840
841void HWC2OnFbAdapter::VsyncThread::enableCallback(bool enable) {
842 {
843 std::lock_guard<std::mutex> lock(mMutex);
844 mCallbackEnabled = enable;
845 }
846 mCondition.notify_all();
847}
848
849void HWC2OnFbAdapter::VsyncThread::vsyncLoop() {
850 prctl(PR_SET_NAME, "VsyncThread", 0, 0, 0);
851
852 std::unique_lock<std::mutex> lock(mMutex);
853 if (!mStarted) {
854 return;
855 }
856
857 while (true) {
858 if (!mCallbackEnabled) {
859 mCondition.wait(lock, [this] { return mCallbackEnabled || !mStarted; });
860 if (!mStarted) {
861 break;
862 }
863 }
864
865 lock.unlock();
866
867 // adjust mNextVsync if necessary
868 int64_t t = now();
869 if (mNextVsync < t) {
870 int64_t n = (t - mNextVsync + mPeriod - 1) / mPeriod;
871 mNextVsync += mPeriod * n;
872 }
873 bool fire = sleepUntil(mNextVsync);
874
875 lock.lock();
876
877 if (fire) {
878 ALOGV("VsyncThread(%" PRId64 ")", mNextVsync);
879 if (mCallback) {
880 mCallback(mCallbackData, getDisplayId(), mNextVsync);
881 }
882 mNextVsync += mPeriod;
883 }
884 }
885}
886
887} // namespace android
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h b/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
new file mode 100644
index 00000000..d6272fdb
--- /dev/null
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
@@ -0,0 +1,123 @@
1/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_SF_HWC2_ON_FB_ADAPTER_H
18#define ANDROID_SF_HWC2_ON_FB_ADAPTER_H
19
20#include <condition_variable>
21#include <mutex>
22#include <string>
23#include <thread>
24#include <unordered_set>
25
26#include <hardware/hwcomposer2.h>
27
28struct framebuffer_device_t;
29
30namespace android {
31
32class HWC2OnFbAdapter : public hwc2_device_t {
33public:
34 HWC2OnFbAdapter(framebuffer_device_t* fbDevice);
35
36 static HWC2OnFbAdapter& cast(hw_device_t* device);
37 static HWC2OnFbAdapter& cast(hwc2_device_t* device);
38
39 static hwc2_display_t getDisplayId();
40 static hwc2_config_t getConfigId();
41
42 void close();
43
44 struct Info {
45 std::string name;
46 uint32_t width;
47 uint32_t height;
48 int format;
49 int vsync_period_ns;
50 int xdpi_scaled;
51 int ydpi_scaled;
52 };
53 const Info& getInfo() const;
54
55 void updateDebugString();
56 const std::string& getDebugString() const;
57
58 enum class State {
59 MODIFIED,
60 VALIDATED_WITH_CHANGES,
61 VALIDATED,
62 };
63 void setState(State state);
64 State getState() const;
65
66 hwc2_layer_t addLayer();
67 bool removeLayer(hwc2_layer_t layer);
68 bool hasLayer(hwc2_layer_t layer) const;
69 bool markLayerDirty(hwc2_layer_t layer, bool dirty);
70 const std::unordered_set<hwc2_layer_t>& getDirtyLayers() const;
71 void clearDirtyLayers();
72
73 void setBuffer(buffer_handle_t buffer);
74 bool postBuffer();
75
76 void setVsyncCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data);
77 void enableVsync(bool enable);
78
79private:
80 framebuffer_device_t* mFbDevice{nullptr};
81 Info mFbInfo{};
82
83 std::string mDebugString;
84
85 State mState{State::MODIFIED};
86
87 uint64_t mNextLayerId{0};
88 std::unordered_set<hwc2_layer_t> mLayers;
89 std::unordered_set<hwc2_layer_t> mDirtyLayers;
90
91 buffer_handle_t mBuffer{nullptr};
92
93 class VsyncThread {
94 public:
95 static int64_t now();
96 static bool sleepUntil(int64_t t);
97
98 void start(int64_t first, int64_t period);
99 void stop();
100 void setCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data);
101 void enableCallback(bool enable);
102
103 private:
104 void vsyncLoop();
105 bool waitUntilNextVsync();
106
107 std::thread mThread;
108 int64_t mNextVsync{0};
109 int64_t mPeriod{0};
110
111 std::mutex mMutex;
112 std::condition_variable mCondition;
113 bool mStarted{false};
114 HWC2_PFN_VSYNC mCallback{nullptr};
115 hwc2_callback_data_t mCallbackData{nullptr};
116 bool mCallbackEnabled{false};
117 };
118 VsyncThread mVsyncThread;
119};
120
121} // namespace android
122
123#endif // ANDROID_SF_HWC2_ON_FB_ADAPTER_H
diff --git a/graphics/composer/2.1/utils/passthrough/Android.bp b/graphics/composer/2.1/utils/passthrough/Android.bp
new file mode 100644
index 00000000..4d3c976a
--- /dev/null
+++ b/graphics/composer/2.1/utils/passthrough/Android.bp
@@ -0,0 +1,22 @@
1cc_library_headers {
2 name: "android.hardware.graphics.composer@2.1-passthrough",
3 defaults: ["hidl_defaults"],
4 vendor: true,
5 shared_libs: [
6 "libhardware",
7 "libhwc2on1adapter",
8 "libhwc2onfbadapter",
9 ],
10 export_shared_lib_headers: [
11 "libhardware",
12 "libhwc2on1adapter",
13 "libhwc2onfbadapter",
14 ],
15 header_libs: [
16 "android.hardware.graphics.composer@2.1-hal",
17 ],
18 export_header_lib_headers: [
19 "android.hardware.graphics.composer@2.1-hal",
20 ],
21 export_include_dirs: ["include"],
22}
diff --git a/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h
new file mode 100644
index 00000000..964e75bd
--- /dev/null
+++ b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h
@@ -0,0 +1,670 @@
1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "HwcHal.h included without LOG_TAG"
21#endif
22
23#include <atomic>
24#include <cstring> // for strerror
25#include <type_traits>
26#include <unordered_set>
27#include <vector>
28
29#include <android/hardware/graphics/composer/2.1/IComposer.h>
30#include <composer-hal/2.1/ComposerHal.h>
31#define HWC2_INCLUDE_STRINGIFICATION
32#define HWC2_USE_CPP11
33#include <hardware/hwcomposer2.h>
34#undef HWC2_INCLUDE_STRINGIFICATION
35#undef HWC2_USE_CPP11
36#include <log/log.h>
37
38namespace android {
39namespace hardware {
40namespace graphics {
41namespace composer {
42namespace V2_1 {
43namespace passthrough {
44
45namespace detail {
46
47using android::hardware::graphics::common::V1_0::ColorMode;
48using android::hardware::graphics::common::V1_0::ColorTransform;
49using android::hardware::graphics::common::V1_0::Dataspace;
50using android::hardware::graphics::common::V1_0::Hdr;
51using android::hardware::graphics::common::V1_0::PixelFormat;
52using android::hardware::graphics::common::V1_0::Transform;
53
54// HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
55template <typename Hal>
56class HwcHalImpl : public Hal {
57 public:
58 virtual ~HwcHalImpl() {
59 if (mDevice) {
60 hwc2_close(mDevice);
61 }
62 }
63
64 bool initWithModule(const hw_module_t* module) {
65 hwc2_device_t* device;
66 int result = hwc2_open(module, &device);
67 if (result) {
68 ALOGE("failed to open hwcomposer2 device: %s", strerror(-result));
69 return false;
70 }
71
72 return initWithDevice(std::move(device), true);
73 }
74
75 bool initWithDevice(hwc2_device_t* device, bool requireReliablePresentFence) {
76 // we own the device from this point on
77 mDevice = device;
78
79 initCapabilities();
80 if (requireReliablePresentFence &&
81 hasCapability(HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE)) {
82 ALOGE("present fence must be reliable");
83 mDevice->common.close(&mDevice->common);
84 mDevice = nullptr;
85 return false;
86 }
87
88 if (!initDispatch()) {
89 mDevice->common.close(&mDevice->common);
90 mDevice = nullptr;
91 return false;
92 }
93
94 return true;
95 }
96
97 bool hasCapability(hwc2_capability_t capability) override {
98 return (mCapabilities.count(capability) > 0);
99 }
100
101 std::string dumpDebugInfo() override {
102 uint32_t len = 0;
103 mDispatch.dump(mDevice, &len, nullptr);
104
105 std::vector<char> buf(len + 1);
106 mDispatch.dump(mDevice, &len, buf.data());
107 buf.resize(len + 1);
108 buf[len] = '\0';
109
110 return buf.data();
111 }
112
113 void registerEventCallback(hal::ComposerHal::EventCallback* callback) override {
114 mMustValidateDisplay = true;
115 mEventCallback = callback;
116
117 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
118 reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
119 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
120 reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
121 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
122 reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
123 }
124
125 void unregisterEventCallback() override {
126 // we assume the callback functions
127 //
128 // - can be unregistered
129 // - can be in-flight
130 // - will never be called afterward
131 //
132 // which is likely incorrect
133 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, nullptr);
134 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, nullptr);
135 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this, nullptr);
136
137 mEventCallback = nullptr;
138 }
139
140 uint32_t getMaxVirtualDisplayCount() override {
141 return mDispatch.getMaxVirtualDisplayCount(mDevice);
142 }
143
144 Error createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format,
145 Display* outDisplay) override {
146 int32_t hwc_format = static_cast<int32_t>(*format);
147 int32_t err =
148 mDispatch.createVirtualDisplay(mDevice, width, height, &hwc_format, outDisplay);
149 *format = static_cast<PixelFormat>(hwc_format);
150
151 return static_cast<Error>(err);
152 }
153
154 Error destroyVirtualDisplay(Display display) override {
155 int32_t err = mDispatch.destroyVirtualDisplay(mDevice, display);
156 return static_cast<Error>(err);
157 }
158
159 Error createLayer(Display display, Layer* outLayer) override {
160 int32_t err = mDispatch.createLayer(mDevice, display, outLayer);
161 return static_cast<Error>(err);
162 }
163
164 Error destroyLayer(Display display, Layer layer) override {
165 int32_t err = mDispatch.destroyLayer(mDevice, display, layer);
166 return static_cast<Error>(err);
167 }
168
169 Error getActiveConfig(Display display, Config* outConfig) override {
170 int32_t err = mDispatch.getActiveConfig(mDevice, display, outConfig);
171 return static_cast<Error>(err);
172 }
173
174 Error getClientTargetSupport(Display display, uint32_t width, uint32_t height,
175 PixelFormat format, Dataspace dataspace) override {
176 int32_t err = mDispatch.getClientTargetSupport(mDevice, display, width, height,
177 static_cast<int32_t>(format),
178 static_cast<int32_t>(dataspace));
179 return static_cast<Error>(err);
180 }
181
182 Error getColorModes(Display display, hidl_vec<ColorMode>* outModes) override {
183 uint32_t count = 0;
184 int32_t err = mDispatch.getColorModes(mDevice, display, &count, nullptr);
185 if (err != HWC2_ERROR_NONE) {
186 return static_cast<Error>(err);
187 }
188
189 outModes->resize(count);
190 err = mDispatch.getColorModes(
191 mDevice, display, &count,
192 reinterpret_cast<std::underlying_type<ColorMode>::type*>(outModes->data()));
193 if (err != HWC2_ERROR_NONE) {
194 *outModes = hidl_vec<ColorMode>();
195 return static_cast<Error>(err);
196 }
197
198 return Error::NONE;
199 }
200
201 Error getDisplayAttribute(Display display, Config config, IComposerClient::Attribute attribute,
202 int32_t* outValue) override {
203 int32_t err = mDispatch.getDisplayAttribute(mDevice, display, config,
204 static_cast<int32_t>(attribute), outValue);
205 return static_cast<Error>(err);
206 }
207
208 Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) override {
209 uint32_t count = 0;
210 int32_t err = mDispatch.getDisplayConfigs(mDevice, display, &count, nullptr);
211 if (err != HWC2_ERROR_NONE) {
212 return static_cast<Error>(err);
213 }
214
215 outConfigs->resize(count);
216 err = mDispatch.getDisplayConfigs(mDevice, display, &count, outConfigs->data());
217 if (err != HWC2_ERROR_NONE) {
218 *outConfigs = hidl_vec<Config>();
219 return static_cast<Error>(err);
220 }
221
222 return Error::NONE;
223 }
224
225 Error getDisplayName(Display display, hidl_string* outName) override {
226 uint32_t count = 0;
227 int32_t err = mDispatch.getDisplayName(mDevice, display, &count, nullptr);
228 if (err != HWC2_ERROR_NONE) {
229 return static_cast<Error>(err);
230 }
231
232 std::vector<char> buf(count + 1);
233 err = mDispatch.getDisplayName(mDevice, display, &count, buf.data());
234 if (err != HWC2_ERROR_NONE) {
235 return static_cast<Error>(err);
236 }
237 buf.resize(count + 1);
238 buf[count] = '\0';
239
240 *outName = buf.data();
241
242 return Error::NONE;
243 }
244
245 Error getDisplayType(Display display, IComposerClient::DisplayType* outType) override {
246 int32_t hwc_type = HWC2_DISPLAY_TYPE_INVALID;
247 int32_t err = mDispatch.getDisplayType(mDevice, display, &hwc_type);
248 *outType = static_cast<IComposerClient::DisplayType>(hwc_type);
249
250 return static_cast<Error>(err);
251 }
252
253 Error getDozeSupport(Display display, bool* outSupport) override {
254 int32_t hwc_support = 0;
255 int32_t err = mDispatch.getDozeSupport(mDevice, display, &hwc_support);
256 *outSupport = hwc_support;
257
258 return static_cast<Error>(err);
259 }
260
261 Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes, float* outMaxLuminance,
262 float* outMaxAverageLuminance, float* outMinLuminance) override {
263 uint32_t count = 0;
264 int32_t err =
265 mDispatch.getHdrCapabilities(mDevice, display, &count, nullptr, outMaxLuminance,
266 outMaxAverageLuminance, outMinLuminance);
267 if (err != HWC2_ERROR_NONE) {
268 return static_cast<Error>(err);
269 }
270
271 outTypes->resize(count);
272 err = mDispatch.getHdrCapabilities(
273 mDevice, display, &count,
274 reinterpret_cast<std::underlying_type<Hdr>::type*>(outTypes->data()), outMaxLuminance,
275 outMaxAverageLuminance, outMinLuminance);
276 if (err != HWC2_ERROR_NONE) {
277 *outTypes = hidl_vec<Hdr>();
278 return static_cast<Error>(err);
279 }
280
281 return Error::NONE;
282 }
283
284 Error setActiveConfig(Display display, Config config) override {
285 int32_t err = mDispatch.setActiveConfig(mDevice, display, config);
286 return static_cast<Error>(err);
287 }
288
289 Error setColorMode(Display display, ColorMode mode) override {
290 int32_t err = mDispatch.setColorMode(mDevice, display, static_cast<int32_t>(mode));
291 return static_cast<Error>(err);
292 }
293
294 Error setPowerMode(Display display, IComposerClient::PowerMode mode) override {
295 int32_t err = mDispatch.setPowerMode(mDevice, display, static_cast<int32_t>(mode));
296 return static_cast<Error>(err);
297 }
298
299 Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled) override {
300 int32_t err = mDispatch.setVsyncEnabled(mDevice, display, static_cast<int32_t>(enabled));
301 return static_cast<Error>(err);
302 }
303
304 Error setColorTransform(Display display, const float* matrix, int32_t hint) override {
305 int32_t err = mDispatch.setColorTransform(mDevice, display, matrix, hint);
306 return static_cast<Error>(err);
307 }
308
309 Error setClientTarget(Display display, buffer_handle_t target, int32_t acquireFence,
310 int32_t dataspace, const std::vector<hwc_rect_t>& damage) override {
311 hwc_region region = {damage.size(), damage.data()};
312 int32_t err =
313 mDispatch.setClientTarget(mDevice, display, target, acquireFence, dataspace, region);
314 return static_cast<Error>(err);
315 }
316
317 Error setOutputBuffer(Display display, buffer_handle_t buffer, int32_t releaseFence) override {
318 int32_t err = mDispatch.setOutputBuffer(mDevice, display, buffer, releaseFence);
319 // unlike in setClientTarget, releaseFence is owned by us
320 if (err == HWC2_ERROR_NONE && releaseFence >= 0) {
321 close(releaseFence);
322 }
323
324 return static_cast<Error>(err);
325 }
326
327 Error validateDisplay(Display display, std::vector<Layer>* outChangedLayers,
328 std::vector<IComposerClient::Composition>* outCompositionTypes,
329 uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
330 std::vector<uint32_t>* outRequestMasks) override {
331 uint32_t typesCount = 0;
332 uint32_t reqsCount = 0;
333 int32_t err = mDispatch.validateDisplay(mDevice, display, &typesCount, &reqsCount);
334 mMustValidateDisplay = false;
335
336 if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) {
337 return static_cast<Error>(err);
338 }
339
340 err = mDispatch.getChangedCompositionTypes(mDevice, display, &typesCount, nullptr, nullptr);
341 if (err != HWC2_ERROR_NONE) {
342 return static_cast<Error>(err);
343 }
344
345 std::vector<Layer> changedLayers(typesCount);
346 std::vector<IComposerClient::Composition> compositionTypes(typesCount);
347 err = mDispatch.getChangedCompositionTypes(
348 mDevice, display, &typesCount, changedLayers.data(),
349 reinterpret_cast<std::underlying_type<IComposerClient::Composition>::type*>(
350 compositionTypes.data()));
351 if (err != HWC2_ERROR_NONE) {
352 return static_cast<Error>(err);
353 }
354
355 int32_t displayReqs = 0;
356 err = mDispatch.getDisplayRequests(mDevice, display, &displayReqs, &reqsCount, nullptr,
357 nullptr);
358 if (err != HWC2_ERROR_NONE) {
359 return static_cast<Error>(err);
360 }
361
362 std::vector<Layer> requestedLayers(reqsCount);
363 std::vector<uint32_t> requestMasks(reqsCount);
364 err = mDispatch.getDisplayRequests(mDevice, display, &displayReqs, &reqsCount,
365 requestedLayers.data(),
366 reinterpret_cast<int32_t*>(requestMasks.data()));
367 if (err != HWC2_ERROR_NONE) {
368 return static_cast<Error>(err);
369 }
370
371 *outChangedLayers = std::move(changedLayers);
372 *outCompositionTypes = std::move(compositionTypes);
373 *outDisplayRequestMask = displayReqs;
374 *outRequestedLayers = std::move(requestedLayers);
375 *outRequestMasks = std::move(requestMasks);
376
377 return static_cast<Error>(err);
378 }
379
380 Error acceptDisplayChanges(Display display) override {
381 int32_t err = mDispatch.acceptDisplayChanges(mDevice, display);
382 return static_cast<Error>(err);
383 }
384
385 Error presentDisplay(Display display, int32_t* outPresentFence, std::vector<Layer>* outLayers,
386 std::vector<int32_t>* outReleaseFences) override {
387 if (mMustValidateDisplay) {
388 return Error::NOT_VALIDATED;
389 }
390
391 *outPresentFence = -1;
392 int32_t err = mDispatch.presentDisplay(mDevice, display, outPresentFence);
393 if (err != HWC2_ERROR_NONE) {
394 return static_cast<Error>(err);
395 }
396
397 uint32_t count = 0;
398 err = mDispatch.getReleaseFences(mDevice, display, &count, nullptr, nullptr);
399 if (err != HWC2_ERROR_NONE) {
400 ALOGW("failed to get release fences");
401 return Error::NONE;
402 }
403
404 outLayers->resize(count);
405 outReleaseFences->resize(count);
406 err = mDispatch.getReleaseFences(mDevice, display, &count, outLayers->data(),
407 outReleaseFences->data());
408 if (err != HWC2_ERROR_NONE) {
409 ALOGW("failed to get release fences");
410 outLayers->clear();
411 outReleaseFences->clear();
412 return Error::NONE;
413 }
414
415 return static_cast<Error>(err);
416 }
417
418 Error setLayerCursorPosition(Display display, Layer layer, int32_t x, int32_t y) override {
419 int32_t err = mDispatch.setCursorPosition(mDevice, display, layer, x, y);
420 return static_cast<Error>(err);
421 }
422
423 Error setLayerBuffer(Display display, Layer layer, buffer_handle_t buffer,
424 int32_t acquireFence) override {
425 int32_t err = mDispatch.setLayerBuffer(mDevice, display, layer, buffer, acquireFence);
426 return static_cast<Error>(err);
427 }
428
429 Error setLayerSurfaceDamage(Display display, Layer layer,
430 const std::vector<hwc_rect_t>& damage) override {
431 hwc_region region = {damage.size(), damage.data()};
432 int32_t err = mDispatch.setLayerSurfaceDamage(mDevice, display, layer, region);
433 return static_cast<Error>(err);
434 }
435
436 Error setLayerBlendMode(Display display, Layer layer, int32_t mode) override {
437 int32_t err = mDispatch.setLayerBlendMode(mDevice, display, layer, mode);
438 return static_cast<Error>(err);
439 }
440
441 Error setLayerColor(Display display, Layer layer, IComposerClient::Color color) override {
442 hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
443 int32_t err = mDispatch.setLayerColor(mDevice, display, layer, hwc_color);
444 return static_cast<Error>(err);
445 }
446
447 Error setLayerCompositionType(Display display, Layer layer, int32_t type) override {
448 int32_t err = mDispatch.setLayerCompositionType(mDevice, display, layer, type);
449 return static_cast<Error>(err);
450 }
451
452 Error setLayerDataspace(Display display, Layer layer, int32_t dataspace) override {
453 int32_t err = mDispatch.setLayerDataspace(mDevice, display, layer, dataspace);
454 return static_cast<Error>(err);
455 }
456
457 Error setLayerDisplayFrame(Display display, Layer layer, const hwc_rect_t& frame) override {
458 int32_t err = mDispatch.setLayerDisplayFrame(mDevice, display, layer, frame);
459 return static_cast<Error>(err);
460 }
461
462 Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override {
463 int32_t err = mDispatch.setLayerPlaneAlpha(mDevice, display, layer, alpha);
464 return static_cast<Error>(err);
465 }
466
467 Error setLayerSidebandStream(Display display, Layer layer, buffer_handle_t stream) override {
468 int32_t err = mDispatch.setLayerSidebandStream(mDevice, display, layer, stream);
469 return static_cast<Error>(err);
470 }
471
472 Error setLayerSourceCrop(Display display, Layer layer, const hwc_frect_t& crop) override {
473 int32_t err = mDispatch.setLayerSourceCrop(mDevice, display, layer, crop);
474 return static_cast<Error>(err);
475 }
476
477 Error setLayerTransform(Display display, Layer layer, int32_t transform) override {
478 int32_t err = mDispatch.setLayerTransform(mDevice, display, layer, transform);
479 return static_cast<Error>(err);
480 }
481
482 Error setLayerVisibleRegion(Display display, Layer layer,
483 const std::vector<hwc_rect_t>& visible) override {
484 hwc_region_t region = {visible.size(), visible.data()};
485 int32_t err = mDispatch.setLayerVisibleRegion(mDevice, display, layer, region);
486 return static_cast<Error>(err);
487 }
488
489 Error setLayerZOrder(Display display, Layer layer, uint32_t z) override {
490 int32_t err = mDispatch.setLayerZOrder(mDevice, display, layer, z);
491 return static_cast<Error>(err);
492 }
493
494 protected:
495 virtual void initCapabilities() {
496 uint32_t count = 0;
497 mDevice->getCapabilities(mDevice, &count, nullptr);
498
499 std::vector<int32_t> caps(count);
500 mDevice->getCapabilities(mDevice, &count, caps.data());
501 caps.resize(count);
502
503 mCapabilities.reserve(count);
504 for (auto cap : caps) {
505 mCapabilities.insert(static_cast<hwc2_capability_t>(cap));
506 }
507 }
508
509 template <typename T>
510 bool initDispatch(hwc2_function_descriptor_t desc, T* outPfn) {
511 auto pfn = mDevice->getFunction(mDevice, desc);
512 if (pfn) {
513 *outPfn = reinterpret_cast<T>(pfn);
514 return true;
515 } else {
516 ALOGE("failed to get hwcomposer2 function %d", desc);
517 return false;
518 }
519 }
520
521 virtual bool initDispatch() {
522 if (!initDispatch(HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES, &mDispatch.acceptDisplayChanges) ||
523 !initDispatch(HWC2_FUNCTION_CREATE_LAYER, &mDispatch.createLayer) ||
524 !initDispatch(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY, &mDispatch.createVirtualDisplay) ||
525 !initDispatch(HWC2_FUNCTION_DESTROY_LAYER, &mDispatch.destroyLayer) ||
526 !initDispatch(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
527 &mDispatch.destroyVirtualDisplay) ||
528 !initDispatch(HWC2_FUNCTION_DUMP, &mDispatch.dump) ||
529 !initDispatch(HWC2_FUNCTION_GET_ACTIVE_CONFIG, &mDispatch.getActiveConfig) ||
530 !initDispatch(HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
531 &mDispatch.getChangedCompositionTypes) ||
532 !initDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
533 &mDispatch.getClientTargetSupport) ||
534 !initDispatch(HWC2_FUNCTION_GET_COLOR_MODES, &mDispatch.getColorModes) ||
535 !initDispatch(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE, &mDispatch.getDisplayAttribute) ||
536 !initDispatch(HWC2_FUNCTION_GET_DISPLAY_CONFIGS, &mDispatch.getDisplayConfigs) ||
537 !initDispatch(HWC2_FUNCTION_GET_DISPLAY_NAME, &mDispatch.getDisplayName) ||
538 !initDispatch(HWC2_FUNCTION_GET_DISPLAY_REQUESTS, &mDispatch.getDisplayRequests) ||
539 !initDispatch(HWC2_FUNCTION_GET_DISPLAY_TYPE, &mDispatch.getDisplayType) ||
540 !initDispatch(HWC2_FUNCTION_GET_DOZE_SUPPORT, &mDispatch.getDozeSupport) ||
541 !initDispatch(HWC2_FUNCTION_GET_HDR_CAPABILITIES, &mDispatch.getHdrCapabilities) ||
542 !initDispatch(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
543 &mDispatch.getMaxVirtualDisplayCount) ||
544 !initDispatch(HWC2_FUNCTION_GET_RELEASE_FENCES, &mDispatch.getReleaseFences) ||
545 !initDispatch(HWC2_FUNCTION_PRESENT_DISPLAY, &mDispatch.presentDisplay) ||
546 !initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK, &mDispatch.registerCallback) ||
547 !initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG, &mDispatch.setActiveConfig) ||
548 !initDispatch(HWC2_FUNCTION_SET_CLIENT_TARGET, &mDispatch.setClientTarget) ||
549 !initDispatch(HWC2_FUNCTION_SET_COLOR_MODE, &mDispatch.setColorMode) ||
550 !initDispatch(HWC2_FUNCTION_SET_COLOR_TRANSFORM, &mDispatch.setColorTransform) ||
551 !initDispatch(HWC2_FUNCTION_SET_CURSOR_POSITION, &mDispatch.setCursorPosition) ||
552 !initDispatch(HWC2_FUNCTION_SET_LAYER_BLEND_MODE, &mDispatch.setLayerBlendMode) ||
553 !initDispatch(HWC2_FUNCTION_SET_LAYER_BUFFER, &mDispatch.setLayerBuffer) ||
554 !initDispatch(HWC2_FUNCTION_SET_LAYER_COLOR, &mDispatch.setLayerColor) ||
555 !initDispatch(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
556 &mDispatch.setLayerCompositionType) ||
557 !initDispatch(HWC2_FUNCTION_SET_LAYER_DATASPACE, &mDispatch.setLayerDataspace) ||
558 !initDispatch(HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME, &mDispatch.setLayerDisplayFrame) ||
559 !initDispatch(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA, &mDispatch.setLayerPlaneAlpha)) {
560 return false;
561 }
562
563 if (hasCapability(HWC2_CAPABILITY_SIDEBAND_STREAM)) {
564 if (!initDispatch(HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM,
565 &mDispatch.setLayerSidebandStream)) {
566 return false;
567 }
568 }
569
570 if (!initDispatch(HWC2_FUNCTION_SET_LAYER_SOURCE_CROP, &mDispatch.setLayerSourceCrop) ||
571 !initDispatch(HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
572 &mDispatch.setLayerSurfaceDamage) ||
573 !initDispatch(HWC2_FUNCTION_SET_LAYER_TRANSFORM, &mDispatch.setLayerTransform) ||
574 !initDispatch(HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
575 &mDispatch.setLayerVisibleRegion) ||
576 !initDispatch(HWC2_FUNCTION_SET_LAYER_Z_ORDER, &mDispatch.setLayerZOrder) ||
577 !initDispatch(HWC2_FUNCTION_SET_OUTPUT_BUFFER, &mDispatch.setOutputBuffer) ||
578 !initDispatch(HWC2_FUNCTION_SET_POWER_MODE, &mDispatch.setPowerMode) ||
579 !initDispatch(HWC2_FUNCTION_SET_VSYNC_ENABLED, &mDispatch.setVsyncEnabled) ||
580 !initDispatch(HWC2_FUNCTION_VALIDATE_DISPLAY, &mDispatch.validateDisplay)) {
581 return false;
582 }
583
584 return true;
585 }
586
587 static void hotplugHook(hwc2_callback_data_t callbackData, hwc2_display_t display,
588 int32_t connected) {
589 auto hal = static_cast<HwcHalImpl*>(callbackData);
590 hal->mEventCallback->onHotplug(display,
591 static_cast<IComposerCallback::Connection>(connected));
592 }
593
594 static void refreshHook(hwc2_callback_data_t callbackData, hwc2_display_t display) {
595 auto hal = static_cast<HwcHalImpl*>(callbackData);
596 hal->mMustValidateDisplay = true;
597 hal->mEventCallback->onRefresh(display);
598 }
599
600 static void vsyncHook(hwc2_callback_data_t callbackData, hwc2_display_t display,
601 int64_t timestamp) {
602 auto hal = static_cast<HwcHalImpl*>(callbackData);
603 hal->mEventCallback->onVsync(display, timestamp);
604 }
605
606 hwc2_device_t* mDevice = nullptr;
607
608 std::unordered_set<hwc2_capability_t> mCapabilities;
609
610 struct {
611 HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;
612 HWC2_PFN_CREATE_LAYER createLayer;
613 HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay;
614 HWC2_PFN_DESTROY_LAYER destroyLayer;
615 HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay;
616 HWC2_PFN_DUMP dump;
617 HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig;
618 HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes;
619 HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport;
620 HWC2_PFN_GET_COLOR_MODES getColorModes;
621 HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute;
622 HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs;
623 HWC2_PFN_GET_DISPLAY_NAME getDisplayName;
624 HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests;
625 HWC2_PFN_GET_DISPLAY_TYPE getDisplayType;
626 HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport;
627 HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities;
628 HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount;
629 HWC2_PFN_GET_RELEASE_FENCES getReleaseFences;
630 HWC2_PFN_PRESENT_DISPLAY presentDisplay;
631 HWC2_PFN_REGISTER_CALLBACK registerCallback;
632 HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig;
633 HWC2_PFN_SET_CLIENT_TARGET setClientTarget;
634 HWC2_PFN_SET_COLOR_MODE setColorMode;
635 HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform;
636 HWC2_PFN_SET_CURSOR_POSITION setCursorPosition;
637 HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode;
638 HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer;
639 HWC2_PFN_SET_LAYER_COLOR setLayerColor;
640 HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType;
641 HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace;
642 HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame;
643 HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha;
644 HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream;
645 HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop;
646 HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage;
647 HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform;
648 HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion;
649 HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder;
650 HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer;
651 HWC2_PFN_SET_POWER_MODE setPowerMode;
652 HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled;
653 HWC2_PFN_VALIDATE_DISPLAY validateDisplay;
654 } mDispatch = {};
655
656 hal::ComposerHal::EventCallback* mEventCallback = nullptr;
657
658 std::atomic<bool> mMustValidateDisplay{true};
659};
660
661} // namespace detail
662
663using HwcHal = detail::HwcHalImpl<hal::ComposerHal>;
664
665} // namespace passthrough
666} // namespace V2_1
667} // namespace composer
668} // namespace graphics
669} // namespace hardware
670} // namespace android
diff --git a/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h
new file mode 100644
index 00000000..33c914dd
--- /dev/null
+++ b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h
@@ -0,0 +1,152 @@
1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "HwcLoader.h included without LOG_TAG"
21#endif
22
23#include <memory>
24
25#include <composer-hal/2.1/Composer.h>
26#include <composer-passthrough/2.1/HwcHal.h>
27#include <hardware/fb.h>
28#include <hardware/gralloc.h>
29#include <hardware/hardware.h>
30#include <hardware/hwcomposer.h>
31#include <hardware/hwcomposer2.h>
32#include <hwc2on1adapter/HWC2On1Adapter.h>
33#include <hwc2onfbadapter/HWC2OnFbAdapter.h>
34#include <log/log.h>
35
36namespace android {
37namespace hardware {
38namespace graphics {
39namespace composer {
40namespace V2_1 {
41namespace passthrough {
42
43class HwcLoader {
44 public:
45 static IComposer* load() {
46 const hw_module_t* module = loadModule();
47 if (!module) {
48 return nullptr;
49 }
50
51 auto hal = createHalWithAdapter(module);
52 if (!hal) {
53 return nullptr;
54 }
55
56 return createComposer(std::move(hal));
57 }
58
59 // load hwcomposer2 module
60 static const hw_module_t* loadModule() {
61 const hw_module_t* module;
62 int error = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
63 if (error) {
64 ALOGI("falling back to gralloc module");
65 error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
66 }
67
68 if (error) {
69 ALOGE("failed to get hwcomposer or gralloc module");
70 return nullptr;
71 }
72
73 return module;
74 }
75
76 // create a ComposerHal instance
77 static std::unique_ptr<hal::ComposerHal> createHal(const hw_module_t* module) {
78 auto hal = std::make_unique<HwcHal>();
79 return hal->initWithModule(module) ? std::move(hal) : nullptr;
80 }
81
82 // create a ComposerHal instance, insert an adapter if necessary
83 static std::unique_ptr<hal::ComposerHal> createHalWithAdapter(const hw_module_t* module) {
84 bool adapted;
85 hwc2_device_t* device = openDeviceWithAdapter(module, &adapted);
86 if (!device) {
87 return nullptr;
88 }
89 auto hal = std::make_unique<HwcHal>();
90 return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr;
91 }
92
93 // create an IComposer instance
94 static IComposer* createComposer(std::unique_ptr<hal::ComposerHal> hal) {
95 return hal::Composer::create(std::move(hal)).release();
96 }
97
98 protected:
99 // open hwcomposer2 device, install an adapter if necessary
100 static hwc2_device_t* openDeviceWithAdapter(const hw_module_t* module, bool* outAdapted) {
101 if (module->id && std::string(module->id) == GRALLOC_HARDWARE_MODULE_ID) {
102 *outAdapted = true;
103 return adaptGrallocModule(module);
104 }
105
106 hw_device_t* device;
107 int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
108 if (error) {
109 ALOGE("failed to open hwcomposer device: %s", strerror(-error));
110 return nullptr;
111 }
112
113 int major = (device->version >> 24) & 0xf;
114 if (major != 2) {
115 *outAdapted = true;
116 return adaptHwc1Device(std::move(reinterpret_cast<hwc_composer_device_1*>(device)));
117 }
118
119 *outAdapted = false;
120 return reinterpret_cast<hwc2_device_t*>(device);
121 }
122
123 private:
124 static hwc2_device_t* adaptGrallocModule(const hw_module_t* module) {
125 framebuffer_device_t* device;
126 int error = framebuffer_open(module, &device);
127 if (error) {
128 ALOGE("failed to open framebuffer device: %s", strerror(-error));
129 return nullptr;
130 }
131
132 return new HWC2OnFbAdapter(device);
133 }
134
135 static hwc2_device_t* adaptHwc1Device(hwc_composer_device_1* device) {
136 int minor = (device->common.version >> 16) & 0xf;
137 if (minor < 1) {
138 ALOGE("hwcomposer 1.0 is not supported");
139 device->common.close(&device->common);
140 return nullptr;
141 }
142
143 return new HWC2On1Adapter(device);
144 }
145};
146
147} // namespace passthrough
148} // namespace V2_1
149} // namespace composer
150} // namespace graphics
151} // namespace hardware
152} // namespace android
diff --git a/graphics/composer/2.1/utils/vts/Android.bp b/graphics/composer/2.1/utils/vts/Android.bp
new file mode 100644
index 00000000..846cfdf3
--- /dev/null
+++ b/graphics/composer/2.1/utils/vts/Android.bp
@@ -0,0 +1,38 @@
1//
2// Copyright (C) 2016 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17cc_library_static {
18 name: "android.hardware.graphics.composer@2.1-vts",
19 defaults: ["hidl_defaults"],
20 srcs: [
21 "ComposerVts.cpp",
22 "GraphicsComposerCallback.cpp",
23 "TestCommandReader.cpp",
24 ],
25 static_libs: [
26 "VtsHalHidlTargetTestBase",
27 "android.hardware.graphics.composer@2.1",
28 ],
29 header_libs: [
30 "android.hardware.graphics.composer@2.1-command-buffer",
31 ],
32 cflags: [
33 "-O0",
34 "-g",
35 "-DLOG_TAG=\"ComposerVts\"",
36 ],
37 export_include_dirs: ["include"],
38}
diff --git a/graphics/composer/2.1/utils/vts/ComposerVts.cpp b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
new file mode 100644
index 00000000..2f531b41
--- /dev/null
+++ b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
@@ -0,0 +1,324 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <composer-vts/2.1/ComposerVts.h>
18
19#include <VtsHalHidlTargetTestBase.h>
20
21namespace android {
22namespace hardware {
23namespace graphics {
24namespace composer {
25namespace V2_1 {
26namespace vts {
27
28Composer::Composer() {
29 mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>();
30 init();
31}
32
33Composer::Composer(const std::string& name) {
34 mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>(name);
35 init();
36}
37
38void Composer::init() {
39 ASSERT_NE(nullptr, mComposer.get()) << "failed to get composer service";
40
41 std::vector<IComposer::Capability> capabilities = getCapabilities();
42 mCapabilities.insert(capabilities.begin(), capabilities.end());
43}
44
45sp<IComposer> Composer::getRaw() const {
46 return mComposer;
47}
48
49bool Composer::hasCapability(IComposer::Capability capability) const {
50 return mCapabilities.count(capability) > 0;
51}
52
53std::vector<IComposer::Capability> Composer::getCapabilities() {
54 std::vector<IComposer::Capability> capabilities;
55 mComposer->getCapabilities(
56 [&](const auto& tmpCapabilities) { capabilities = tmpCapabilities; });
57
58 return capabilities;
59}
60
61std::string Composer::dumpDebugInfo() {
62 std::string debugInfo;
63 mComposer->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
64
65 return debugInfo;
66}
67
68std::unique_ptr<ComposerClient> Composer::createClient() {
69 std::unique_ptr<ComposerClient> client;
70 mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {
71 ASSERT_EQ(Error::NONE, tmpError) << "failed to create client";
72 client = std::make_unique<ComposerClient>(tmpClient);
73 });
74
75 return client;
76}
77
78ComposerClient::ComposerClient(const sp<IComposerClient>& client) : mClient(client) {}
79
80ComposerClient::~ComposerClient() {
81 for (auto it : mDisplayResources) {
82 Display display = it.first;
83 DisplayResource& resource = it.second;
84
85 for (auto layer : resource.layers) {
86 EXPECT_EQ(Error::NONE, mClient->destroyLayer(display, layer))
87 << "failed to destroy layer " << layer;
88 }
89
90 if (resource.isVirtual) {
91 EXPECT_EQ(Error::NONE, mClient->destroyVirtualDisplay(display))
92 << "failed to destroy virtual display " << display;
93 }
94 }
95 mDisplayResources.clear();
96}
97
98sp<IComposerClient> ComposerClient::getRaw() const {
99 return mClient;
100}
101
102void ComposerClient::registerCallback(const sp<IComposerCallback>& callback) {
103 mClient->registerCallback(callback);
104}
105
106uint32_t ComposerClient::getMaxVirtualDisplayCount() {
107 return mClient->getMaxVirtualDisplayCount();
108}
109
110Display ComposerClient::createVirtualDisplay(uint32_t width, uint32_t height,
111 PixelFormat formatHint, uint32_t outputBufferSlotCount,
112 PixelFormat* outFormat) {
113 Display display = 0;
114 mClient->createVirtualDisplay(
115 width, height, formatHint, outputBufferSlotCount,
116 [&](const auto& tmpError, const auto& tmpDisplay, const auto& tmpFormat) {
117 ASSERT_EQ(Error::NONE, tmpError) << "failed to create virtual display";
118 display = tmpDisplay;
119 *outFormat = tmpFormat;
120
121 ASSERT_TRUE(mDisplayResources.insert({display, DisplayResource(true)}).second)
122 << "duplicated virtual display id " << display;
123 });
124
125 return display;
126}
127
128void ComposerClient::destroyVirtualDisplay(Display display) {
129 Error error = mClient->destroyVirtualDisplay(display);
130 ASSERT_EQ(Error::NONE, error) << "failed to destroy virtual display " << display;
131
132 mDisplayResources.erase(display);
133}
134
135Layer ComposerClient::createLayer(Display display, uint32_t bufferSlotCount) {
136 Layer layer = 0;
137 mClient->createLayer(display, bufferSlotCount, [&](const auto& tmpError, const auto& tmpLayer) {
138 ASSERT_EQ(Error::NONE, tmpError) << "failed to create layer";
139 layer = tmpLayer;
140
141 auto resourceIt = mDisplayResources.find(display);
142 if (resourceIt == mDisplayResources.end()) {
143 resourceIt = mDisplayResources.insert({display, DisplayResource(false)}).first;
144 }
145
146 ASSERT_TRUE(resourceIt->second.layers.insert(layer).second)
147 << "duplicated layer id " << layer;
148 });
149
150 return layer;
151}
152
153void ComposerClient::destroyLayer(Display display, Layer layer) {
154 Error error = mClient->destroyLayer(display, layer);
155 ASSERT_EQ(Error::NONE, error) << "failed to destroy layer " << layer;
156
157 auto resourceIt = mDisplayResources.find(display);
158 ASSERT_NE(mDisplayResources.end(), resourceIt);
159 resourceIt->second.layers.erase(layer);
160}
161
162Config ComposerClient::getActiveConfig(Display display) {
163 Config config = 0;
164 mClient->getActiveConfig(display, [&](const auto& tmpError, const auto& tmpConfig) {
165 ASSERT_EQ(Error::NONE, tmpError) << "failed to get active config";
166 config = tmpConfig;
167 });
168
169 return config;
170}
171
172bool ComposerClient::getClientTargetSupport(Display display, uint32_t width, uint32_t height,
173 PixelFormat format, Dataspace dataspace) {
174 Error error = mClient->getClientTargetSupport(display, width, height, format, dataspace);
175 return error == Error::NONE;
176}
177
178std::vector<ColorMode> ComposerClient::getColorModes(Display display) {
179 std::vector<ColorMode> modes;
180 mClient->getColorModes(display, [&](const auto& tmpError, const auto& tmpMode) {
181 ASSERT_EQ(Error::NONE, tmpError) << "failed to get color mode";
182 modes = tmpMode;
183 });
184
185 return modes;
186}
187
188int32_t ComposerClient::getDisplayAttribute(Display display, Config config,
189 IComposerClient::Attribute attribute) {
190 int32_t value = 0;
191 mClient->getDisplayAttribute(
192 display, config, attribute, [&](const auto& tmpError, const auto& tmpValue) {
193 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display attribute";
194 value = tmpValue;
195 });
196
197 return value;
198}
199
200std::vector<Config> ComposerClient::getDisplayConfigs(Display display) {
201 std::vector<Config> configs;
202 mClient->getDisplayConfigs(display, [&](const auto& tmpError, const auto& tmpConfigs) {
203 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display configs";
204 configs = tmpConfigs;
205 });
206
207 return configs;
208}
209
210std::string ComposerClient::getDisplayName(Display display) {
211 std::string name;
212 mClient->getDisplayName(display, [&](const auto& tmpError, const auto& tmpName) {
213 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display name";
214 name = tmpName.c_str();
215 });
216
217 return name;
218}
219
220IComposerClient::DisplayType ComposerClient::getDisplayType(Display display) {
221 IComposerClient::DisplayType type = IComposerClient::DisplayType::INVALID;
222 mClient->getDisplayType(display, [&](const auto& tmpError, const auto& tmpType) {
223 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display type";
224 type = tmpType;
225 });
226
227 return type;
228}
229
230bool ComposerClient::getDozeSupport(Display display) {
231 bool support = false;
232 mClient->getDozeSupport(display, [&](const auto& tmpError, const auto& tmpSupport) {
233 ASSERT_EQ(Error::NONE, tmpError) << "failed to get doze support";
234 support = tmpSupport;
235 });
236
237 return support;
238}
239
240std::vector<Hdr> ComposerClient::getHdrCapabilities(Display display, float* outMaxLuminance,
241 float* outMaxAverageLuminance,
242 float* outMinLuminance) {
243 std::vector<Hdr> types;
244 mClient->getHdrCapabilities(
245 display, [&](const auto& tmpError, const auto& tmpTypes, const auto& tmpMaxLuminance,
246 const auto& tmpMaxAverageLuminance, const auto& tmpMinLuminance) {
247 ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR capabilities";
248 types = tmpTypes;
249 *outMaxLuminance = tmpMaxLuminance;
250 *outMaxAverageLuminance = tmpMaxAverageLuminance;
251 *outMinLuminance = tmpMinLuminance;
252 });
253
254 return types;
255}
256
257void ComposerClient::setClientTargetSlotCount(Display display, uint32_t clientTargetSlotCount) {
258 Error error = mClient->setClientTargetSlotCount(display, clientTargetSlotCount);
259 ASSERT_EQ(Error::NONE, error) << "failed to set client target slot count";
260}
261
262void ComposerClient::setActiveConfig(Display display, Config config) {
263 Error error = mClient->setActiveConfig(display, config);
264 ASSERT_EQ(Error::NONE, error) << "failed to set active config";
265}
266
267void ComposerClient::setColorMode(Display display, ColorMode mode) {
268 Error error = mClient->setColorMode(display, mode);
269 ASSERT_EQ(Error::NONE, error) << "failed to set color mode";
270}
271
272void ComposerClient::setPowerMode(Display display, IComposerClient::PowerMode mode) {
273 Error error = mClient->setPowerMode(display, mode);
274 ASSERT_EQ(Error::NONE, error) << "failed to set power mode";
275}
276
277void ComposerClient::setVsyncEnabled(Display display, bool enabled) {
278 IComposerClient::Vsync vsync =
279 (enabled) ? IComposerClient::Vsync::ENABLE : IComposerClient::Vsync::DISABLE;
280 Error error = mClient->setVsyncEnabled(display, vsync);
281 ASSERT_EQ(Error::NONE, error) << "failed to set vsync mode";
282
283 // give the hwbinder thread some time to handle any pending vsync callback
284 if (!enabled) {
285 usleep(5 * 1000);
286 }
287}
288
289void ComposerClient::execute(TestCommandReader* reader, CommandWriterBase* writer) {
290 bool queueChanged = false;
291 uint32_t commandLength = 0;
292 hidl_vec<hidl_handle> commandHandles;
293 ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
294
295 if (queueChanged) {
296 auto ret = mClient->setInputCommandQueue(*writer->getMQDescriptor());
297 ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
298 return;
299 }
300
301 mClient->executeCommands(commandLength, commandHandles,
302 [&](const auto& tmpError, const auto& tmpOutQueueChanged,
303 const auto& tmpOutLength, const auto& tmpOutHandles) {
304 ASSERT_EQ(Error::NONE, tmpError);
305
306 if (tmpOutQueueChanged) {
307 mClient->getOutputCommandQueue(
308 [&](const auto& tmpError, const auto& tmpDescriptor) {
309 ASSERT_EQ(Error::NONE, tmpError);
310 reader->setMQDescriptor(tmpDescriptor);
311 });
312 }
313
314 ASSERT_TRUE(reader->readQueue(tmpOutLength, tmpOutHandles));
315 reader->parse();
316 });
317}
318
319} // namespace vts
320} // namespace V2_1
321} // namespace composer
322} // namespace graphics
323} // namespace hardware
324} // namespace android
diff --git a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.cpp b/graphics/composer/2.1/utils/vts/GraphicsComposerCallback.cpp
index 0ad440c1..1ead138e 100644
--- a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.cpp
+++ b/graphics/composer/2.1/utils/vts/GraphicsComposerCallback.cpp
@@ -14,78 +14,77 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include "GraphicsComposerCallback.h" 17#include <composer-vts/2.1/GraphicsComposerCallback.h>
18 18
19namespace android { 19namespace android {
20namespace hardware { 20namespace hardware {
21namespace graphics { 21namespace graphics {
22namespace composer { 22namespace composer {
23namespace V2_1 { 23namespace V2_1 {
24namespace tests { 24namespace vts {
25 25
26void GraphicsComposerCallback::setVsyncAllowed(bool allowed) { 26void GraphicsComposerCallback::setVsyncAllowed(bool allowed) {
27 std::lock_guard<std::mutex> lock(mMutex); 27 std::lock_guard<std::mutex> lock(mMutex);
28 mVsyncAllowed = allowed; 28 mVsyncAllowed = allowed;
29} 29}
30 30
31std::vector<Display> GraphicsComposerCallback::getDisplays() const { 31std::vector<Display> GraphicsComposerCallback::getDisplays() const {
32 std::lock_guard<std::mutex> lock(mMutex); 32 std::lock_guard<std::mutex> lock(mMutex);
33 return std::vector<Display>(mDisplays.begin(), mDisplays.end()); 33 return std::vector<Display>(mDisplays.begin(), mDisplays.end());
34} 34}
35 35
36int GraphicsComposerCallback::getInvalidHotplugCount() const { 36int GraphicsComposerCallback::getInvalidHotplugCount() const {
37 std::lock_guard<std::mutex> lock(mMutex); 37 std::lock_guard<std::mutex> lock(mMutex);
38 return mInvalidHotplugCount; 38 return mInvalidHotplugCount;
39} 39}
40 40
41int GraphicsComposerCallback::getInvalidRefreshCount() const { 41int GraphicsComposerCallback::getInvalidRefreshCount() const {
42 std::lock_guard<std::mutex> lock(mMutex); 42 std::lock_guard<std::mutex> lock(mMutex);
43 return mInvalidRefreshCount; 43 return mInvalidRefreshCount;
44} 44}
45 45
46int GraphicsComposerCallback::getInvalidVsyncCount() const { 46int GraphicsComposerCallback::getInvalidVsyncCount() const {
47 std::lock_guard<std::mutex> lock(mMutex); 47 std::lock_guard<std::mutex> lock(mMutex);
48 return mInvalidVsyncCount; 48 return mInvalidVsyncCount;
49} 49}
50 50
51Return<void> GraphicsComposerCallback::onHotplug(Display display, 51Return<void> GraphicsComposerCallback::onHotplug(Display display, Connection connection) {
52 Connection connection) { 52 std::lock_guard<std::mutex> lock(mMutex);
53 std::lock_guard<std::mutex> lock(mMutex); 53
54 54 if (connection == Connection::CONNECTED) {
55 if (connection == Connection::CONNECTED) { 55 if (!mDisplays.insert(display).second) {
56 if (!mDisplays.insert(display).second) { 56 mInvalidHotplugCount++;
57 mInvalidHotplugCount++; 57 }
58 } 58 } else if (connection == Connection::DISCONNECTED) {
59 } else if (connection == Connection::DISCONNECTED) { 59 if (!mDisplays.erase(display)) {
60 if (!mDisplays.erase(display)) { 60 mInvalidHotplugCount++;
61 mInvalidHotplugCount++; 61 }
62 } 62 }
63 }
64 63
65 return Void(); 64 return Void();
66} 65}
67 66
68Return<void> GraphicsComposerCallback::onRefresh(Display display) { 67Return<void> GraphicsComposerCallback::onRefresh(Display display) {
69 std::lock_guard<std::mutex> lock(mMutex); 68 std::lock_guard<std::mutex> lock(mMutex);
70 69
71 if (mDisplays.count(display) == 0) { 70 if (mDisplays.count(display) == 0) {
72 mInvalidRefreshCount++; 71 mInvalidRefreshCount++;
73 } 72 }
74 73
75 return Void(); 74 return Void();
76} 75}
77 76
78Return<void> GraphicsComposerCallback::onVsync(Display display, int64_t) { 77Return<void> GraphicsComposerCallback::onVsync(Display display, int64_t) {
79 std::lock_guard<std::mutex> lock(mMutex); 78 std::lock_guard<std::mutex> lock(mMutex);
80 79
81 if (!mVsyncAllowed || mDisplays.count(display) == 0) { 80 if (!mVsyncAllowed || mDisplays.count(display) == 0) {
82 mInvalidVsyncCount++; 81 mInvalidVsyncCount++;
83 } 82 }
84 83
85 return Void(); 84 return Void();
86} 85}
87 86
88} // namespace tests 87} // namespace vts
89} // namespace V2_1 88} // namespace V2_1
90} // namespace composer 89} // namespace composer
91} // namespace graphics 90} // namespace graphics
diff --git a/graphics/composer/2.1/utils/vts/TestCommandReader.cpp b/graphics/composer/2.1/utils/vts/TestCommandReader.cpp
new file mode 100644
index 00000000..6f8f1ad4
--- /dev/null
+++ b/graphics/composer/2.1/utils/vts/TestCommandReader.cpp
@@ -0,0 +1,62 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <composer-vts/2.1/TestCommandReader.h>
18
19#include <gtest/gtest.h>
20
21namespace android {
22namespace hardware {
23namespace graphics {
24namespace composer {
25namespace V2_1 {
26namespace vts {
27
28void TestCommandReader::parse() {
29 while (!isEmpty()) {
30 IComposerClient::Command command;
31 uint16_t length;
32 ASSERT_TRUE(beginCommand(&command, &length));
33
34 switch (command) {
35 case IComposerClient::Command::SET_ERROR: {
36 ASSERT_EQ(2, length);
37 auto loc = read();
38 auto err = readSigned();
39 GTEST_FAIL() << "unexpected error " << err << " at location " << loc;
40 } break;
41 case IComposerClient::Command::SELECT_DISPLAY:
42 case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
43 case IComposerClient::Command::SET_DISPLAY_REQUESTS:
44 case IComposerClient::Command::SET_PRESENT_FENCE:
45 case IComposerClient::Command::SET_RELEASE_FENCES:
46 break;
47 default:
48 GTEST_FAIL() << "unexpected return command " << std::hex
49 << static_cast<int>(command);
50 break;
51 }
52
53 endCommand();
54 }
55}
56
57} // namespace vts
58} // namespace V2_1
59} // namespace composer
60} // namespace graphics
61} // namespace hardware
62} // namespace android
diff --git a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h
new file mode 100644
index 00000000..0d883e4f
--- /dev/null
+++ b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <memory>
20#include <string>
21#include <unordered_map>
22#include <unordered_set>
23#include <vector>
24
25#include <android/hardware/graphics/composer/2.1/IComposer.h>
26#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
27#include <composer-vts/2.1/TestCommandReader.h>
28#include <utils/StrongPointer.h>
29
30namespace android {
31namespace hardware {
32namespace graphics {
33namespace composer {
34namespace V2_1 {
35namespace vts {
36
37using android::hardware::graphics::common::V1_0::ColorMode;
38using android::hardware::graphics::common::V1_0::Dataspace;
39using android::hardware::graphics::common::V1_0::Hdr;
40using android::hardware::graphics::common::V1_0::PixelFormat;
41
42class ComposerClient;
43
44// A wrapper to IComposer.
45class Composer {
46 public:
47 Composer();
48 explicit Composer(const std::string& name);
49
50 sp<IComposer> getRaw() const;
51
52 // Returns true when the composer supports the specified capability.
53 bool hasCapability(IComposer::Capability capability) const;
54
55 std::vector<IComposer::Capability> getCapabilities();
56 std::string dumpDebugInfo();
57 std::unique_ptr<ComposerClient> createClient();
58
59 protected:
60 sp<IComposer> mComposer;
61
62 private:
63 void init();
64
65 std::unordered_set<IComposer::Capability> mCapabilities;
66};
67
68// A wrapper to IComposerClient.
69class ComposerClient {
70 public:
71 ComposerClient(const sp<IComposerClient>& client);
72 ~ComposerClient();
73
74 sp<IComposerClient> getRaw() const;
75
76 void registerCallback(const sp<IComposerCallback>& callback);
77 uint32_t getMaxVirtualDisplayCount();
78
79 Display createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat formatHint,
80 uint32_t outputBufferSlotCount, PixelFormat* outFormat);
81 void destroyVirtualDisplay(Display display);
82
83 Layer createLayer(Display display, uint32_t bufferSlotCount);
84 void destroyLayer(Display display, Layer layer);
85
86 Config getActiveConfig(Display display);
87 bool getClientTargetSupport(Display display, uint32_t width, uint32_t height,
88 PixelFormat format, Dataspace dataspace);
89 std::vector<ColorMode> getColorModes(Display display);
90 int32_t getDisplayAttribute(Display display, Config config,
91 IComposerClient::Attribute attribute);
92 std::vector<Config> getDisplayConfigs(Display display);
93 std::string getDisplayName(Display display);
94 IComposerClient::DisplayType getDisplayType(Display display);
95 bool getDozeSupport(Display display);
96 std::vector<Hdr> getHdrCapabilities(Display display, float* outMaxLuminance,
97 float* outMaxAverageLuminance, float* outMinLuminance);
98
99 void setClientTargetSlotCount(Display display, uint32_t clientTargetSlotCount);
100 void setActiveConfig(Display display, Config config);
101 void setColorMode(Display display, ColorMode mode);
102 void setPowerMode(Display display, IComposerClient::PowerMode mode);
103 void setVsyncEnabled(Display display, bool enabled);
104
105 void execute(TestCommandReader* reader, CommandWriterBase* writer);
106
107 private:
108 sp<IComposerClient> mClient;
109
110 // Keep track of all virtual displays and layers. When a test fails with
111 // ASSERT_*, the destructor will clean up the resources for the test.
112 struct DisplayResource {
113 DisplayResource(bool isVirtual_) : isVirtual(isVirtual_) {}
114
115 bool isVirtual;
116 std::unordered_set<Layer> layers;
117 };
118 std::unordered_map<Display, DisplayResource> mDisplayResources;
119};
120
121} // namespace vts
122} // namespace V2_1
123} // namespace composer
124} // namespace graphics
125} // namespace hardware
126} // namespace android
diff --git a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/GraphicsComposerCallback.h
index e3320865..e3c348f7 100644
--- a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
+++ b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/GraphicsComposerCallback.h
@@ -14,8 +14,7 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#ifndef GRAPHICS_COMPOSER_CALLBACK_H 17#pragma once
18#define GRAPHICS_COMPOSER_CALLBACK_H
19 18
20#include <android/hardware/graphics/composer/2.1/IComposerCallback.h> 19#include <android/hardware/graphics/composer/2.1/IComposerCallback.h>
21 20
@@ -27,43 +26,41 @@ namespace hardware {
27namespace graphics { 26namespace graphics {
28namespace composer { 27namespace composer {
29namespace V2_1 { 28namespace V2_1 {
30namespace tests { 29namespace vts {
31 30
32// IComposerCallback to be installed with IComposerClient::registerCallback. 31// IComposerCallback to be installed with IComposerClient::registerCallback.
33class GraphicsComposerCallback : public IComposerCallback { 32class GraphicsComposerCallback : public IComposerCallback {
34 public: 33 public:
35 void setVsyncAllowed(bool allowed); 34 void setVsyncAllowed(bool allowed);
36 35
37 std::vector<Display> getDisplays() const; 36 std::vector<Display> getDisplays() const;
38 37
39 int getInvalidHotplugCount() const; 38 int getInvalidHotplugCount() const;
40 39
41 int getInvalidRefreshCount() const; 40 int getInvalidRefreshCount() const;
42 41
43 int getInvalidVsyncCount() const; 42 int getInvalidVsyncCount() const;
44 43
45 private: 44 private:
46 Return<void> onHotplug(Display display, Connection connection) override; 45 Return<void> onHotplug(Display display, Connection connection) override;
47 Return<void> onRefresh(Display display) override; 46 Return<void> onRefresh(Display display) override;
48 Return<void> onVsync(Display display, int64_t) override; 47 Return<void> onVsync(Display display, int64_t) override;
49 48
50 mutable std::mutex mMutex; 49 mutable std::mutex mMutex;
51 // the set of all currently connected displays 50 // the set of all currently connected displays
52 std::unordered_set<Display> mDisplays; 51 std::unordered_set<Display> mDisplays;
53 // true only when vsync is enabled 52 // true only when vsync is enabled
54 bool mVsyncAllowed = true; 53 bool mVsyncAllowed = true;
55 54
56 // track invalid callbacks 55 // track invalid callbacks
57 int mInvalidHotplugCount = 0; 56 int mInvalidHotplugCount = 0;
58 int mInvalidRefreshCount = 0; 57 int mInvalidRefreshCount = 0;
59 int mInvalidVsyncCount = 0; 58 int mInvalidVsyncCount = 0;
60}; 59};
61 60
62} // namespace tests 61} // namespace vts
63} // namespace V2_1 62} // namespace V2_1
64} // namespace composer 63} // namespace composer
65} // namespace graphics 64} // namespace graphics
66} // namespace hardware 65} // namespace hardware
67} // namespace android 66} // namespace android
68
69#endif // GRAPHICS_COMPOSER_CALLBACK_H
diff --git a/graphics/composer/2.1/vts/functional/TestCommandReader.h b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h
index ae25d2d6..3888eebe 100644
--- a/graphics/composer/2.1/vts/functional/TestCommandReader.h
+++ b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h
@@ -14,8 +14,7 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#ifndef TEST_COMMAND_READER_H 17#pragma once
18#define TEST_COMMAND_READER_H
19 18
20#include <composer-command-buffer/2.1/ComposerCommandBuffer.h> 19#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
21 20
@@ -24,22 +23,20 @@ namespace hardware {
24namespace graphics { 23namespace graphics {
25namespace composer { 24namespace composer {
26namespace V2_1 { 25namespace V2_1 {
27namespace tests { 26namespace vts {
28 27
29// A command parser that checks that no error nor unexpected commands are 28// A command parser that checks that no error nor unexpected commands are
30// returned. 29// returned.
31class TestCommandReader : public CommandReaderBase { 30class TestCommandReader : public CommandReaderBase {
32 public: 31 public:
33 // Parse all commands in the return command queue. Call GTEST_FAIL() for 32 // Parse all commands in the return command queue. Call GTEST_FAIL() for
34 // unexpected errors or commands. 33 // unexpected errors or commands.
35 void parse(); 34 void parse();
36}; 35};
37 36
38} // namespace tests 37} // namespace vts
39} // namespace V2_1 38} // namespace V2_1
40} // namespace composer 39} // namespace composer
41} // namespace graphics 40} // namespace graphics
42} // namespace hardware 41} // namespace hardware
43} // namespace android 42} // namespace android
44
45#endif // TEST_COMMAND_READER_H
diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp
index 92b65a36..8e346df9 100644
--- a/graphics/composer/2.1/vts/functional/Android.bp
+++ b/graphics/composer/2.1/vts/functional/Android.bp
@@ -14,36 +14,6 @@
14// limitations under the License. 14// limitations under the License.
15// 15//
16 16
17cc_library_static {
18 name: "libVtsHalGraphicsComposerTestUtils",
19 defaults: ["hidl_defaults"],
20 srcs: [
21 "GraphicsComposerCallback.cpp",
22 "TestCommandReader.cpp",
23 "VtsHalGraphicsComposerTestUtils.cpp",
24 ],
25 shared_libs: [
26 "android.hardware.graphics.composer@2.1",
27 "libfmq",
28 "libsync",
29 ],
30 static_libs: [
31 "VtsHalHidlTargetTestBase",
32 ],
33 header_libs: [
34 "android.hardware.graphics.composer@2.1-command-buffer",
35 ],
36 cflags: [
37 "-Wall",
38 "-Wextra",
39 "-Werror",
40 "-O0",
41 "-g",
42 "-DLOG_TAG=\"GraphicsComposerTestUtils\"",
43 ],
44 export_include_dirs: ["."],
45}
46
47cc_test { 17cc_test {
48 name: "VtsHalGraphicsComposerV2_1TargetTest", 18 name: "VtsHalGraphicsComposerV2_1TargetTest",
49 defaults: ["VtsHalTargetTestDefaults"], 19 defaults: ["VtsHalTargetTestDefaults"],
@@ -57,10 +27,9 @@ cc_test {
57 static_libs: [ 27 static_libs: [
58 "android.hardware.graphics.allocator@2.0", 28 "android.hardware.graphics.allocator@2.0",
59 "android.hardware.graphics.composer@2.1", 29 "android.hardware.graphics.composer@2.1",
30 "android.hardware.graphics.composer@2.1-vts",
60 "android.hardware.graphics.mapper@2.0", 31 "android.hardware.graphics.mapper@2.0",
61 "android.hardware.graphics.mapper@2.0-vts", 32 "android.hardware.graphics.mapper@2.0-vts",
62 "libVtsHalGraphicsComposerTestUtils",
63 "libnativehelper",
64 ], 33 ],
65 header_libs: [ 34 header_libs: [
66 "android.hardware.graphics.composer@2.1-command-buffer", 35 "android.hardware.graphics.composer@2.1-command-buffer",
diff --git a/graphics/composer/2.1/vts/functional/TestCommandReader.cpp b/graphics/composer/2.1/vts/functional/TestCommandReader.cpp
deleted file mode 100644
index b1f9aca5..00000000
--- a/graphics/composer/2.1/vts/functional/TestCommandReader.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "TestCommandReader.h"
18
19#include <gtest/gtest.h>
20
21namespace android {
22namespace hardware {
23namespace graphics {
24namespace composer {
25namespace V2_1 {
26namespace tests {
27
28void TestCommandReader::parse() {
29 while (!isEmpty()) {
30 IComposerClient::Command command;
31 uint16_t length;
32 ASSERT_TRUE(beginCommand(&command, &length));
33
34 switch (command) {
35 case IComposerClient::Command::SET_ERROR: {
36 ASSERT_EQ(2, length);
37 auto loc = read();
38 auto err = readSigned();
39 GTEST_FAIL() << "unexpected error " << err << " at location " << loc;
40 } break;
41 case IComposerClient::Command::SELECT_DISPLAY:
42 case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
43 case IComposerClient::Command::SET_DISPLAY_REQUESTS:
44 case IComposerClient::Command::SET_PRESENT_FENCE:
45 case IComposerClient::Command::SET_RELEASE_FENCES:
46 break;
47 default:
48 GTEST_FAIL() << "unexpected return command " << std::hex
49 << static_cast<int>(command);
50 break;
51 }
52
53 endCommand();
54 }
55}
56
57} // namespace tests
58} // namespace V2_1
59} // namespace composer
60} // namespace graphics
61} // namespace hardware
62} // namespace android
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
deleted file mode 100644
index c66cdd0c..00000000
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <VtsHalHidlTargetTestBase.h>
18
19#include "VtsHalGraphicsComposerTestUtils.h"
20
21namespace android {
22namespace hardware {
23namespace graphics {
24namespace composer {
25namespace V2_1 {
26namespace tests {
27
28Composer::Composer() {
29 mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>();
30 init();
31}
32
33Composer::Composer(const std::string& name) {
34 mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>(name);
35 init();
36}
37
38void Composer::init() {
39 ASSERT_NE(nullptr, mComposer.get()) << "failed to get composer service";
40
41 std::vector<IComposer::Capability> capabilities = getCapabilities();
42 mCapabilities.insert(capabilities.begin(), capabilities.end());
43}
44
45sp<IComposer> Composer::getRaw() const { return mComposer; }
46
47bool Composer::hasCapability(IComposer::Capability capability) const {
48 return mCapabilities.count(capability) > 0;
49}
50
51std::vector<IComposer::Capability> Composer::getCapabilities() {
52 std::vector<IComposer::Capability> capabilities;
53 mComposer->getCapabilities(
54 [&](const auto& tmpCapabilities) { capabilities = tmpCapabilities; });
55
56 return capabilities;
57}
58
59std::string Composer::dumpDebugInfo() {
60 std::string debugInfo;
61 mComposer->dumpDebugInfo(
62 [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
63
64 return debugInfo;
65}
66
67std::unique_ptr<ComposerClient> Composer::createClient() {
68 std::unique_ptr<ComposerClient> client;
69 mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {
70 ASSERT_EQ(Error::NONE, tmpError) << "failed to create client";
71 client = std::make_unique<ComposerClient>(tmpClient);
72 });
73
74 return client;
75}
76
77ComposerClient::ComposerClient(const sp<IComposerClient>& client)
78 : mClient(client) {}
79
80ComposerClient::~ComposerClient() {
81 for (auto it : mDisplayResources) {
82 Display display = it.first;
83 DisplayResource& resource = it.second;
84
85 for (auto layer : resource.layers) {
86 EXPECT_EQ(Error::NONE, mClient->destroyLayer(display, layer))
87 << "failed to destroy layer " << layer;
88 }
89
90 if (resource.isVirtual) {
91 EXPECT_EQ(Error::NONE, mClient->destroyVirtualDisplay(display))
92 << "failed to destroy virtual display " << display;
93 }
94 }
95 mDisplayResources.clear();
96}
97
98sp<IComposerClient> ComposerClient::getRaw() const { return mClient; }
99
100void ComposerClient::registerCallback(const sp<IComposerCallback>& callback) {
101 mClient->registerCallback(callback);
102}
103
104uint32_t ComposerClient::getMaxVirtualDisplayCount() {
105 return mClient->getMaxVirtualDisplayCount();
106}
107
108Display ComposerClient::createVirtualDisplay(uint32_t width, uint32_t height,
109 PixelFormat formatHint,
110 uint32_t outputBufferSlotCount,
111 PixelFormat* outFormat) {
112 Display display = 0;
113 mClient->createVirtualDisplay(
114 width, height, formatHint, outputBufferSlotCount,
115 [&](const auto& tmpError, const auto& tmpDisplay, const auto& tmpFormat) {
116 ASSERT_EQ(Error::NONE, tmpError) << "failed to create virtual display";
117 display = tmpDisplay;
118 *outFormat = tmpFormat;
119
120 ASSERT_TRUE(
121 mDisplayResources.insert({display, DisplayResource(true)}).second)
122 << "duplicated virtual display id " << display;
123 });
124
125 return display;
126}
127
128void ComposerClient::destroyVirtualDisplay(Display display) {
129 Error error = mClient->destroyVirtualDisplay(display);
130 ASSERT_EQ(Error::NONE, error)
131 << "failed to destroy virtual display " << display;
132
133 mDisplayResources.erase(display);
134}
135
136Layer ComposerClient::createLayer(Display display, uint32_t bufferSlotCount) {
137 Layer layer = 0;
138 mClient->createLayer(
139 display, bufferSlotCount,
140 [&](const auto& tmpError, const auto& tmpLayer) {
141 ASSERT_EQ(Error::NONE, tmpError) << "failed to create layer";
142 layer = tmpLayer;
143
144 auto resourceIt = mDisplayResources.find(display);
145 if (resourceIt == mDisplayResources.end()) {
146 resourceIt =
147 mDisplayResources.insert({display, DisplayResource(false)}).first;
148 }
149
150 ASSERT_TRUE(resourceIt->second.layers.insert(layer).second)
151 << "duplicated layer id " << layer;
152 });
153
154 return layer;
155}
156
157void ComposerClient::destroyLayer(Display display, Layer layer) {
158 Error error = mClient->destroyLayer(display, layer);
159 ASSERT_EQ(Error::NONE, error) << "failed to destroy layer " << layer;
160
161 auto resourceIt = mDisplayResources.find(display);
162 ASSERT_NE(mDisplayResources.end(), resourceIt);
163 resourceIt->second.layers.erase(layer);
164}
165
166Config ComposerClient::getActiveConfig(Display display) {
167 Config config = 0;
168 mClient->getActiveConfig(
169 display, [&](const auto& tmpError, const auto& tmpConfig) {
170 ASSERT_EQ(Error::NONE, tmpError) << "failed to get active config";
171 config = tmpConfig;
172 });
173
174 return config;
175}
176
177bool ComposerClient::getClientTargetSupport(Display display, uint32_t width,
178 uint32_t height, PixelFormat format,
179 Dataspace dataspace) {
180 Error error = mClient->getClientTargetSupport(display, width, height, format,
181 dataspace);
182 return error == Error::NONE;
183}
184
185std::vector<ColorMode> ComposerClient::getColorModes(Display display) {
186 std::vector<ColorMode> modes;
187 mClient->getColorModes(
188 display, [&](const auto& tmpError, const auto& tmpMode) {
189 ASSERT_EQ(Error::NONE, tmpError) << "failed to get color mode";
190 modes = tmpMode;
191 });
192
193 return modes;
194}
195
196int32_t ComposerClient::getDisplayAttribute(
197 Display display, Config config, IComposerClient::Attribute attribute) {
198 int32_t value = 0;
199 mClient->getDisplayAttribute(display, config, attribute,
200 [&](const auto& tmpError, const auto& tmpValue) {
201 ASSERT_EQ(Error::NONE, tmpError)
202 << "failed to get display attribute";
203 value = tmpValue;
204 });
205
206 return value;
207}
208
209std::vector<Config> ComposerClient::getDisplayConfigs(Display display) {
210 std::vector<Config> configs;
211 mClient->getDisplayConfigs(
212 display, [&](const auto& tmpError, const auto& tmpConfigs) {
213 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display configs";
214 configs = tmpConfigs;
215 });
216
217 return configs;
218}
219
220std::string ComposerClient::getDisplayName(Display display) {
221 std::string name;
222 mClient->getDisplayName(
223 display, [&](const auto& tmpError, const auto& tmpName) {
224 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display name";
225 name = tmpName.c_str();
226 });
227
228 return name;
229}
230
231IComposerClient::DisplayType ComposerClient::getDisplayType(Display display) {
232 IComposerClient::DisplayType type = IComposerClient::DisplayType::INVALID;
233 mClient->getDisplayType(
234 display, [&](const auto& tmpError, const auto& tmpType) {
235 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display type";
236 type = tmpType;
237 });
238
239 return type;
240}
241
242bool ComposerClient::getDozeSupport(Display display) {
243 bool support = false;
244 mClient->getDozeSupport(
245 display, [&](const auto& tmpError, const auto& tmpSupport) {
246 ASSERT_EQ(Error::NONE, tmpError) << "failed to get doze support";
247 support = tmpSupport;
248 });
249
250 return support;
251}
252
253std::vector<Hdr> ComposerClient::getHdrCapabilities(
254 Display display, float* outMaxLuminance, float* outMaxAverageLuminance,
255 float* outMinLuminance) {
256 std::vector<Hdr> types;
257 mClient->getHdrCapabilities(
258 display,
259 [&](const auto& tmpError, const auto& tmpTypes,
260 const auto& tmpMaxLuminance, const auto& tmpMaxAverageLuminance,
261 const auto& tmpMinLuminance) {
262 ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR capabilities";
263 types = tmpTypes;
264 *outMaxLuminance = tmpMaxLuminance;
265 *outMaxAverageLuminance = tmpMaxAverageLuminance;
266 *outMinLuminance = tmpMinLuminance;
267 });
268
269 return types;
270}
271
272void ComposerClient::setClientTargetSlotCount(Display display,
273 uint32_t clientTargetSlotCount) {
274 Error error =
275 mClient->setClientTargetSlotCount(display, clientTargetSlotCount);
276 ASSERT_EQ(Error::NONE, error) << "failed to set client target slot count";
277}
278
279void ComposerClient::setActiveConfig(Display display, Config config) {
280 Error error = mClient->setActiveConfig(display, config);
281 ASSERT_EQ(Error::NONE, error) << "failed to set active config";
282}
283
284void ComposerClient::setColorMode(Display display, ColorMode mode) {
285 Error error = mClient->setColorMode(display, mode);
286 ASSERT_EQ(Error::NONE, error) << "failed to set color mode";
287}
288
289void ComposerClient::setPowerMode(Display display,
290 IComposerClient::PowerMode mode) {
291 Error error = mClient->setPowerMode(display, mode);
292 ASSERT_EQ(Error::NONE, error) << "failed to set power mode";
293}
294
295void ComposerClient::setVsyncEnabled(Display display, bool enabled) {
296 IComposerClient::Vsync vsync = (enabled) ? IComposerClient::Vsync::ENABLE
297 : IComposerClient::Vsync::DISABLE;
298 Error error = mClient->setVsyncEnabled(display, vsync);
299 ASSERT_EQ(Error::NONE, error) << "failed to set vsync mode";
300
301 // give the hwbinder thread some time to handle any pending vsync callback
302 if (!enabled) {
303 usleep(5 * 1000);
304 }
305}
306
307void ComposerClient::execute(TestCommandReader* reader,
308 CommandWriterBase* writer) {
309 bool queueChanged = false;
310 uint32_t commandLength = 0;
311 hidl_vec<hidl_handle> commandHandles;
312 ASSERT_TRUE(
313 writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
314
315 if (queueChanged) {
316 auto ret = mClient->setInputCommandQueue(*writer->getMQDescriptor());
317 ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
318 return;
319 }
320
321 mClient->executeCommands(
322 commandLength, commandHandles,
323 [&](const auto& tmpError, const auto& tmpOutQueueChanged,
324 const auto& tmpOutLength, const auto& tmpOutHandles) {
325 ASSERT_EQ(Error::NONE, tmpError);
326
327 if (tmpOutQueueChanged) {
328 mClient->getOutputCommandQueue(
329 [&](const auto& tmpError, const auto& tmpDescriptor) {
330 ASSERT_EQ(Error::NONE, tmpError);
331 reader->setMQDescriptor(tmpDescriptor);
332 });
333 }
334
335 ASSERT_TRUE(reader->readQueue(tmpOutLength, tmpOutHandles));
336 reader->parse();
337 });
338}
339
340} // namespace tests
341} // namespace V2_1
342} // namespace composer
343} // namespace graphics
344} // namespace hardware
345} // namespace android
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.h b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.h
deleted file mode 100644
index 00d9d8c9..00000000
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.h
+++ /dev/null
@@ -1,134 +0,0 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef VTS_HAL_GRAPHICS_COMPOSER_UTILS
18#define VTS_HAL_GRAPHICS_COMPOSER_UTILS
19
20#include <memory>
21#include <string>
22#include <unordered_map>
23#include <unordered_set>
24#include <vector>
25
26#include <android/hardware/graphics/composer/2.1/IComposer.h>
27#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
28#include <utils/StrongPointer.h>
29
30#include "TestCommandReader.h"
31
32namespace android {
33namespace hardware {
34namespace graphics {
35namespace composer {
36namespace V2_1 {
37namespace tests {
38
39using android::hardware::graphics::common::V1_0::ColorMode;
40using android::hardware::graphics::common::V1_0::Dataspace;
41using android::hardware::graphics::common::V1_0::Hdr;
42using android::hardware::graphics::common::V1_0::PixelFormat;
43
44class ComposerClient;
45
46// A wrapper to IComposer.
47class Composer {
48 public:
49 Composer();
50 explicit Composer(const std::string& name);
51
52 sp<IComposer> getRaw() const;
53
54 // Returns true when the composer supports the specified capability.
55 bool hasCapability(IComposer::Capability capability) const;
56
57 std::vector<IComposer::Capability> getCapabilities();
58 std::string dumpDebugInfo();
59 std::unique_ptr<ComposerClient> createClient();
60
61 protected:
62 sp<IComposer> mComposer;
63
64 private:
65 void init();
66
67 std::unordered_set<IComposer::Capability> mCapabilities;
68};
69
70// A wrapper to IComposerClient.
71class ComposerClient {
72 public:
73 ComposerClient(const sp<IComposerClient>& client);
74 ~ComposerClient();
75
76 sp<IComposerClient> getRaw() const;
77
78 void registerCallback(const sp<IComposerCallback>& callback);
79 uint32_t getMaxVirtualDisplayCount();
80
81 Display createVirtualDisplay(uint32_t width, uint32_t height,
82 PixelFormat formatHint,
83 uint32_t outputBufferSlotCount,
84 PixelFormat* outFormat);
85 void destroyVirtualDisplay(Display display);
86
87 Layer createLayer(Display display, uint32_t bufferSlotCount);
88 void destroyLayer(Display display, Layer layer);
89
90 Config getActiveConfig(Display display);
91 bool getClientTargetSupport(Display display, uint32_t width, uint32_t height,
92 PixelFormat format, Dataspace dataspace);
93 std::vector<ColorMode> getColorModes(Display display);
94 int32_t getDisplayAttribute(Display display, Config config,
95 IComposerClient::Attribute attribute);
96 std::vector<Config> getDisplayConfigs(Display display);
97 std::string getDisplayName(Display display);
98 IComposerClient::DisplayType getDisplayType(Display display);
99 bool getDozeSupport(Display display);
100 std::vector<Hdr> getHdrCapabilities(Display display, float* outMaxLuminance,
101 float* outMaxAverageLuminance,
102 float* outMinLuminance);
103
104 void setClientTargetSlotCount(Display display,
105 uint32_t clientTargetSlotCount);
106 void setActiveConfig(Display display, Config config);
107 void setColorMode(Display display, ColorMode mode);
108 void setPowerMode(Display display, IComposerClient::PowerMode mode);
109 void setVsyncEnabled(Display display, bool enabled);
110
111 void execute(TestCommandReader* reader, CommandWriterBase* writer);
112
113 private:
114 sp<IComposerClient> mClient;
115
116 // Keep track of all virtual displays and layers. When a test fails with
117 // ASSERT_*, the destructor will clean up the resources for the test.
118 struct DisplayResource {
119 DisplayResource(bool isVirtual_) : isVirtual(isVirtual_) {}
120
121 bool isVirtual;
122 std::unordered_set<Layer> layers;
123 };
124 std::unordered_map<Display, DisplayResource> mDisplayResources;
125};
126
127} // namespace tests
128} // namespace V2_1
129} // namespace composer
130} // namespace graphics
131} // namespace hardware
132} // namespace android
133
134#endif // VTS_HAL_GRAPHICS_COMPOSER_UTILS
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 376ee379..8b8b530a 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -17,10 +17,10 @@
17#define LOG_TAG "graphics_composer_hidl_hal_test" 17#define LOG_TAG "graphics_composer_hidl_hal_test"
18 18
19#include <android-base/logging.h> 19#include <android-base/logging.h>
20#include <composer-vts/2.1/ComposerVts.h>
21#include <composer-vts/2.1/GraphicsComposerCallback.h>
22#include <composer-vts/2.1/TestCommandReader.h>
20#include <mapper-vts/2.0/MapperVts.h> 23#include <mapper-vts/2.0/MapperVts.h>
21#include "GraphicsComposerCallback.h"
22#include "TestCommandReader.h"
23#include "VtsHalGraphicsComposerTestUtils.h"
24 24
25#include <VtsHalHidlTargetTestBase.h> 25#include <VtsHalHidlTargetTestBase.h>
26#include <VtsHalHidlTargetTestEnvBase.h> 26#include <VtsHalHidlTargetTestEnvBase.h>
@@ -38,7 +38,7 @@ namespace hardware {
38namespace graphics { 38namespace graphics {
39namespace composer { 39namespace composer {
40namespace V2_1 { 40namespace V2_1 {
41namespace tests { 41namespace vts {
42namespace { 42namespace {
43 43
44using android::hardware::graphics::common::V1_0::BufferUsage; 44using android::hardware::graphics::common::V1_0::BufferUsage;
@@ -69,53 +69,53 @@ class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEn
69}; 69};
70 70
71class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase { 71class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
72 protected: 72 protected:
73 void SetUp() override { 73 void SetUp() override {
74 ASSERT_NO_FATAL_FAILURE( 74 ASSERT_NO_FATAL_FAILURE(
75 mComposer = std::make_unique<Composer>( 75 mComposer = std::make_unique<Composer>(
76 GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>())); 76 GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
77 ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient()); 77 ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
78 78
79 mComposerCallback = new GraphicsComposerCallback; 79 mComposerCallback = new GraphicsComposerCallback;
80 mComposerClient->registerCallback(mComposerCallback); 80 mComposerClient->registerCallback(mComposerCallback);
81 81
82 // assume the first display is primary and is never removed 82 // assume the first display is primary and is never removed
83 mPrimaryDisplay = waitForFirstDisplay(); 83 mPrimaryDisplay = waitForFirstDisplay();
84 84
85 // explicitly disable vsync 85 // explicitly disable vsync
86 mComposerClient->setVsyncEnabled(mPrimaryDisplay, false); 86 mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
87 mComposerCallback->setVsyncAllowed(false); 87 mComposerCallback->setVsyncAllowed(false);
88 }
89
90 void TearDown() override {
91 if (mComposerCallback != nullptr) {
92 EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
93 EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
94 EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
95 } 88 }
96 } 89
97 90 void TearDown() override {
98 // use the slot count usually set by SF 91 if (mComposerCallback != nullptr) {
99 static constexpr uint32_t kBufferSlotCount = 64; 92 EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
100 93 EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
101 std::unique_ptr<Composer> mComposer; 94 EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
102 std::unique_ptr<ComposerClient> mComposerClient; 95 }
103 sp<GraphicsComposerCallback> mComposerCallback; 96 }
104 // the first display and is assumed never to be removed 97
105 Display mPrimaryDisplay; 98 // use the slot count usually set by SF
106 99 static constexpr uint32_t kBufferSlotCount = 64;
107 private: 100
108 Display waitForFirstDisplay() { 101 std::unique_ptr<Composer> mComposer;
109 while (true) { 102 std::unique_ptr<ComposerClient> mComposerClient;
110 std::vector<Display> displays = mComposerCallback->getDisplays(); 103 sp<GraphicsComposerCallback> mComposerCallback;
111 if (displays.empty()) { 104 // the first display and is assumed never to be removed
112 usleep(5 * 1000); 105 Display mPrimaryDisplay;
113 continue; 106
114 } 107 private:
115 108 Display waitForFirstDisplay() {
116 return displays[0]; 109 while (true) {
110 std::vector<Display> displays = mComposerCallback->getDisplays();
111 if (displays.empty()) {
112 usleep(5 * 1000);
113 continue;
114 }
115
116 return displays[0];
117 }
117 } 118 }
118 }
119}; 119};
120 120
121/** 121/**
@@ -124,16 +124,17 @@ class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
124 * Test that IComposer::getCapabilities returns no invalid capabilities. 124 * Test that IComposer::getCapabilities returns no invalid capabilities.
125 */ 125 */
126TEST_F(GraphicsComposerHidlTest, GetCapabilities) { 126TEST_F(GraphicsComposerHidlTest, GetCapabilities) {
127 auto capabilities = mComposer->getCapabilities(); 127 auto capabilities = mComposer->getCapabilities();
128 ASSERT_EQ(capabilities.end(), 128 ASSERT_EQ(capabilities.end(),
129 std::find(capabilities.begin(), capabilities.end(), 129 std::find(capabilities.begin(), capabilities.end(), IComposer::Capability::INVALID));
130 IComposer::Capability::INVALID));
131} 130}
132 131
133/** 132/**
134 * Test IComposer::dumpDebugInfo. 133 * Test IComposer::dumpDebugInfo.
135 */ 134 */
136TEST_F(GraphicsComposerHidlTest, DumpDebugInfo) { mComposer->dumpDebugInfo(); } 135TEST_F(GraphicsComposerHidlTest, DumpDebugInfo) {
136 mComposer->dumpDebugInfo();
137}
137 138
138/** 139/**
139 * Test IComposer::createClient. 140 * Test IComposer::createClient.
@@ -141,9 +142,8 @@ TEST_F(GraphicsComposerHidlTest, DumpDebugInfo) { mComposer->dumpDebugInfo(); }
141 * Test that IComposerClient is a singleton. 142 * Test that IComposerClient is a singleton.
142 */ 143 */
143TEST_F(GraphicsComposerHidlTest, CreateClientSingleton) { 144TEST_F(GraphicsComposerHidlTest, CreateClientSingleton) {
144 mComposer->getRaw()->createClient([&](const auto& tmpError, const auto&) { 145 mComposer->getRaw()->createClient(
145 EXPECT_EQ(Error::NO_RESOURCES, tmpError); 146 [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::NO_RESOURCES, tmpError); });
146 });
147} 147}
148 148
149/** 149/**
@@ -153,22 +153,22 @@ TEST_F(GraphicsComposerHidlTest, CreateClientSingleton) {
153 * Test that virtual displays can be created and has the correct display type. 153 * Test that virtual displays can be created and has the correct display type.
154 */ 154 */
155TEST_F(GraphicsComposerHidlTest, CreateVirtualDisplay) { 155TEST_F(GraphicsComposerHidlTest, CreateVirtualDisplay) {
156 if (mComposerClient->getMaxVirtualDisplayCount() == 0) { 156 if (mComposerClient->getMaxVirtualDisplayCount() == 0) {
157 GTEST_SUCCEED() << "no virtual display support"; 157 GTEST_SUCCEED() << "no virtual display support";
158 return; 158 return;
159 } 159 }
160 160
161 Display display; 161 Display display;
162 PixelFormat format; 162 PixelFormat format;
163 ASSERT_NO_FATAL_FAILURE(display = mComposerClient->createVirtualDisplay( 163 ASSERT_NO_FATAL_FAILURE(
164 64, 64, PixelFormat::IMPLEMENTATION_DEFINED, 164 display = mComposerClient->createVirtualDisplay(64, 64, PixelFormat::IMPLEMENTATION_DEFINED,
165 kBufferSlotCount, &format)); 165 kBufferSlotCount, &format));
166 166
167 // test display type 167 // test display type
168 IComposerClient::DisplayType type = mComposerClient->getDisplayType(display); 168 IComposerClient::DisplayType type = mComposerClient->getDisplayType(display);
169 EXPECT_EQ(IComposerClient::DisplayType::VIRTUAL, type); 169 EXPECT_EQ(IComposerClient::DisplayType::VIRTUAL, type);
170 170
171 mComposerClient->destroyVirtualDisplay(display); 171 mComposerClient->destroyVirtualDisplay(display);
172} 172}
173 173
174/** 174/**
@@ -177,18 +177,18 @@ TEST_F(GraphicsComposerHidlTest, CreateVirtualDisplay) {
177 * Test that layers can be created and destroyed. 177 * Test that layers can be created and destroyed.
178 */ 178 */
179TEST_F(GraphicsComposerHidlTest, CreateLayer) { 179TEST_F(GraphicsComposerHidlTest, CreateLayer) {
180 Layer layer; 180 Layer layer;
181 ASSERT_NO_FATAL_FAILURE( 181 ASSERT_NO_FATAL_FAILURE(layer =
182 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 182 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
183 183
184 mComposerClient->destroyLayer(mPrimaryDisplay, layer); 184 mComposerClient->destroyLayer(mPrimaryDisplay, layer);
185} 185}
186 186
187/** 187/**
188 * Test IComposerClient::getDisplayName. 188 * Test IComposerClient::getDisplayName.
189 */ 189 */
190TEST_F(GraphicsComposerHidlTest, GetDisplayName) { 190TEST_F(GraphicsComposerHidlTest, GetDisplayName) {
191 mComposerClient->getDisplayName(mPrimaryDisplay); 191 mComposerClient->getDisplayName(mPrimaryDisplay);
192} 192}
193 193
194/** 194/**
@@ -198,8 +198,8 @@ TEST_F(GraphicsComposerHidlTest, GetDisplayName) {
198 * for the primary display. 198 * for the primary display.
199 */ 199 */
200TEST_F(GraphicsComposerHidlTest, GetDisplayType) { 200TEST_F(GraphicsComposerHidlTest, GetDisplayType) {
201 ASSERT_EQ(IComposerClient::DisplayType::PHYSICAL, 201 ASSERT_EQ(IComposerClient::DisplayType::PHYSICAL,
202 mComposerClient->getDisplayType(mPrimaryDisplay)); 202 mComposerClient->getDisplayType(mPrimaryDisplay));
203} 203}
204 204
205/** 205/**
@@ -209,22 +209,20 @@ TEST_F(GraphicsComposerHidlTest, GetDisplayType) {
209 * required client targets. 209 * required client targets.
210 */ 210 */
211TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport) { 211TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport) {
212 std::vector<Config> configs = 212 std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
213 mComposerClient->getDisplayConfigs(mPrimaryDisplay); 213 for (auto config : configs) {
214 for (auto config : configs) { 214 int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
215 int32_t width = mComposerClient->getDisplayAttribute( 215 IComposerClient::Attribute::WIDTH);
216 mPrimaryDisplay, config, IComposerClient::Attribute::WIDTH); 216 int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
217 int32_t height = mComposerClient->getDisplayAttribute( 217 IComposerClient::Attribute::HEIGHT);
218 mPrimaryDisplay, config, IComposerClient::Attribute::HEIGHT); 218 ASSERT_LT(0, width);
219 ASSERT_LT(0, width); 219 ASSERT_LT(0, height);
220 ASSERT_LT(0, height); 220
221 221 mComposerClient->setActiveConfig(mPrimaryDisplay, config);
222 mComposerClient->setActiveConfig(mPrimaryDisplay, config); 222
223 223 ASSERT_TRUE(mComposerClient->getClientTargetSupport(
224 ASSERT_TRUE(mComposerClient->getClientTargetSupport( 224 mPrimaryDisplay, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN));
225 mPrimaryDisplay, width, height, PixelFormat::RGBA_8888, 225 }
226 Dataspace::UNKNOWN));
227 }
228} 226}
229 227
230/** 228/**
@@ -234,47 +232,44 @@ TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport) {
234 * formats, and succeeds or fails correctly for optional attributes. 232 * formats, and succeeds or fails correctly for optional attributes.
235 */ 233 */
236TEST_F(GraphicsComposerHidlTest, GetDisplayAttribute) { 234TEST_F(GraphicsComposerHidlTest, GetDisplayAttribute) {
237 std::vector<Config> configs = 235 std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
238 mComposerClient->getDisplayConfigs(mPrimaryDisplay); 236 for (auto config : configs) {
239 for (auto config : configs) { 237 const std::array<IComposerClient::Attribute, 3> requiredAttributes = {{
240 const std::array<IComposerClient::Attribute, 3> requiredAttributes = {{ 238 IComposerClient::Attribute::WIDTH, IComposerClient::Attribute::HEIGHT,
241 IComposerClient::Attribute::WIDTH, IComposerClient::Attribute::HEIGHT, 239 IComposerClient::Attribute::VSYNC_PERIOD,
242 IComposerClient::Attribute::VSYNC_PERIOD, 240 }};
243 }}; 241 for (auto attribute : requiredAttributes) {
244 for (auto attribute : requiredAttributes) { 242 mComposerClient->getDisplayAttribute(mPrimaryDisplay, config, attribute);
245 mComposerClient->getDisplayAttribute(mPrimaryDisplay, config, attribute); 243 }
246 } 244
247 245 const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{
248 const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{ 246 IComposerClient::Attribute::DPI_X, IComposerClient::Attribute::DPI_Y,
249 IComposerClient::Attribute::DPI_X, IComposerClient::Attribute::DPI_Y, 247 }};
250 }}; 248 for (auto attribute : optionalAttributes) {
251 for (auto attribute : optionalAttributes) { 249 mComposerClient->getRaw()->getDisplayAttribute(
252 mComposerClient->getRaw()->getDisplayAttribute( 250 mPrimaryDisplay, config, attribute, [&](const auto& tmpError, const auto&) {
253 mPrimaryDisplay, config, attribute, 251 EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED);
254 [&](const auto& tmpError, const auto&) { 252 });
255 EXPECT_TRUE(tmpError == Error::NONE || 253 }
256 tmpError == Error::UNSUPPORTED);
257 });
258 } 254 }
259 }
260} 255}
261 256
262/** 257/**
263 * Test IComposerClient::getHdrCapabilities. 258 * Test IComposerClient::getHdrCapabilities.
264 */ 259 */
265TEST_F(GraphicsComposerHidlTest, GetHdrCapabilities) { 260TEST_F(GraphicsComposerHidlTest, GetHdrCapabilities) {
266 float maxLuminance; 261 float maxLuminance;
267 float maxAverageLuminance; 262 float maxAverageLuminance;
268 float minLuminance; 263 float minLuminance;
269 mComposerClient->getHdrCapabilities(mPrimaryDisplay, &maxLuminance, 264 mComposerClient->getHdrCapabilities(mPrimaryDisplay, &maxLuminance, &maxAverageLuminance,
270 &maxAverageLuminance, &minLuminance); 265 &minLuminance);
271} 266}
272 267
273/** 268/**
274 * Test IComposerClient::setClientTargetSlotCount. 269 * Test IComposerClient::setClientTargetSlotCount.
275 */ 270 */
276TEST_F(GraphicsComposerHidlTest, SetClientTargetSlotCount) { 271TEST_F(GraphicsComposerHidlTest, SetClientTargetSlotCount) {
277 mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount); 272 mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount);
278} 273}
279 274
280/** 275/**
@@ -284,12 +279,11 @@ TEST_F(GraphicsComposerHidlTest, SetClientTargetSlotCount) {
284 * configs. 279 * configs.
285 */ 280 */
286TEST_F(GraphicsComposerHidlTest, SetActiveConfig) { 281TEST_F(GraphicsComposerHidlTest, SetActiveConfig) {
287 std::vector<Config> configs = 282 std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
288 mComposerClient->getDisplayConfigs(mPrimaryDisplay); 283 for (auto config : configs) {
289 for (auto config : configs) { 284 mComposerClient->setActiveConfig(mPrimaryDisplay, config);
290 mComposerClient->setActiveConfig(mPrimaryDisplay, config); 285 ASSERT_EQ(config, mComposerClient->getActiveConfig(mPrimaryDisplay));
291 ASSERT_EQ(config, mComposerClient->getActiveConfig(mPrimaryDisplay)); 286 }
292 }
293} 287}
294 288
295/** 289/**
@@ -298,11 +292,10 @@ TEST_F(GraphicsComposerHidlTest, SetActiveConfig) {
298 * Test that IComposerClient::setColorMode succeeds for all color modes. 292 * Test that IComposerClient::setColorMode succeeds for all color modes.
299 */ 293 */
300TEST_F(GraphicsComposerHidlTest, SetColorMode) { 294TEST_F(GraphicsComposerHidlTest, SetColorMode) {
301 std::vector<ColorMode> modes = 295 std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
302 mComposerClient->getColorModes(mPrimaryDisplay); 296 for (auto mode : modes) {
303 for (auto mode : modes) { 297 mComposerClient->setColorMode(mPrimaryDisplay, mode);
304 mComposerClient->setColorMode(mPrimaryDisplay, mode); 298 }
305 }
306} 299}
307 300
308/** 301/**
@@ -311,20 +304,20 @@ TEST_F(GraphicsComposerHidlTest, SetColorMode) {
311 * Test that IComposerClient::setPowerMode succeeds for all power modes. 304 * Test that IComposerClient::setPowerMode succeeds for all power modes.
312 */ 305 */
313TEST_F(GraphicsComposerHidlTest, SetPowerMode) { 306TEST_F(GraphicsComposerHidlTest, SetPowerMode) {
314 std::vector<IComposerClient::PowerMode> modes; 307 std::vector<IComposerClient::PowerMode> modes;
315 modes.push_back(IComposerClient::PowerMode::OFF); 308 modes.push_back(IComposerClient::PowerMode::OFF);
316 309
317 if (mComposerClient->getDozeSupport(mPrimaryDisplay)) { 310 if (mComposerClient->getDozeSupport(mPrimaryDisplay)) {
318 modes.push_back(IComposerClient::PowerMode::DOZE); 311 modes.push_back(IComposerClient::PowerMode::DOZE);
319 modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND); 312 modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND);
320 } 313 }
321 314
322 // push ON last 315 // push ON last
323 modes.push_back(IComposerClient::PowerMode::ON); 316 modes.push_back(IComposerClient::PowerMode::ON);
324 317
325 for (auto mode : modes) { 318 for (auto mode : modes) {
326 mComposerClient->setPowerMode(mPrimaryDisplay, mode); 319 mComposerClient->setPowerMode(mPrimaryDisplay, mode);
327 } 320 }
328} 321}
329 322
330/** 323/**
@@ -334,369 +327,365 @@ TEST_F(GraphicsComposerHidlTest, SetPowerMode) {
334 * spurious vsync events. 327 * spurious vsync events.
335 */ 328 */
336TEST_F(GraphicsComposerHidlTest, SetVsyncEnabled) { 329TEST_F(GraphicsComposerHidlTest, SetVsyncEnabled) {
337 mComposerCallback->setVsyncAllowed(true); 330 mComposerCallback->setVsyncAllowed(true);
338 331
339 mComposerClient->setVsyncEnabled(mPrimaryDisplay, true); 332 mComposerClient->setVsyncEnabled(mPrimaryDisplay, true);
340 usleep(60 * 1000); 333 usleep(60 * 1000);
341 mComposerClient->setVsyncEnabled(mPrimaryDisplay, false); 334 mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
342 335
343 mComposerCallback->setVsyncAllowed(false); 336 mComposerCallback->setVsyncAllowed(false);
344} 337}
345 338
346// Tests for IComposerClient::Command. 339// Tests for IComposerClient::Command.
347class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest { 340class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
348 protected: 341 protected:
349 void SetUp() override { 342 void SetUp() override {
350 ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp()); 343 ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
351 344
352 ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>()); 345 ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
353 346
354 mWriter = std::make_unique<CommandWriterBase>(1024); 347 mWriter = std::make_unique<CommandWriterBase>(1024);
355 mReader = std::make_unique<TestCommandReader>(); 348 mReader = std::make_unique<TestCommandReader>();
356 } 349 }
357 350
358 void TearDown() override { 351 void TearDown() override { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); }
359 ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
360 }
361 352
362 const native_handle_t* allocate() { 353 const native_handle_t* allocate() {
363 IMapper::BufferDescriptorInfo info{}; 354 IMapper::BufferDescriptorInfo info{};
364 info.width = 64; 355 info.width = 64;
365 info.height = 64; 356 info.height = 64;
366 info.layerCount = 1; 357 info.layerCount = 1;
367 info.format = PixelFormat::RGBA_8888; 358 info.format = PixelFormat::RGBA_8888;
368 info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | 359 info.usage =
369 BufferUsage::CPU_READ_OFTEN); 360 static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
370 361
371 return mGralloc->allocate(info); 362 return mGralloc->allocate(info);
372 } 363 }
373 364
374 void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); } 365 void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
375 366
376 std::unique_ptr<CommandWriterBase> mWriter; 367 std::unique_ptr<CommandWriterBase> mWriter;
377 std::unique_ptr<TestCommandReader> mReader; 368 std::unique_ptr<TestCommandReader> mReader;
378 369
379 private: 370 private:
380 std::unique_ptr<Gralloc> mGralloc; 371 std::unique_ptr<Gralloc> mGralloc;
381}; 372};
382 373
383/** 374/**
384 * Test IComposerClient::Command::SET_COLOR_TRANSFORM. 375 * Test IComposerClient::Command::SET_COLOR_TRANSFORM.
385 */ 376 */
386TEST_F(GraphicsComposerHidlCommandTest, SET_COLOR_TRANSFORM) { 377TEST_F(GraphicsComposerHidlCommandTest, SET_COLOR_TRANSFORM) {
387 const std::array<float, 16> identity = {{ 378 const std::array<float, 16> identity = {{
388 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 379 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
389 0.0f, 0.0f, 0.0f, 1.0f, 380 1.0f,
390 }}; 381 }};
391 382
392 mWriter->selectDisplay(mPrimaryDisplay); 383 mWriter->selectDisplay(mPrimaryDisplay);
393 mWriter->setColorTransform(identity.data(), ColorTransform::IDENTITY); 384 mWriter->setColorTransform(identity.data(), ColorTransform::IDENTITY);
394 385
395 execute(); 386 execute();
396} 387}
397 388
398/** 389/**
399 * Test IComposerClient::Command::SET_CLIENT_TARGET. 390 * Test IComposerClient::Command::SET_CLIENT_TARGET.
400 */ 391 */
401TEST_F(GraphicsComposerHidlCommandTest, SET_CLIENT_TARGET) { 392TEST_F(GraphicsComposerHidlCommandTest, SET_CLIENT_TARGET) {
402 mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount); 393 mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount);
403 394
404 mWriter->selectDisplay(mPrimaryDisplay); 395 mWriter->selectDisplay(mPrimaryDisplay);
405 mWriter->setClientTarget(0, nullptr, -1, Dataspace::UNKNOWN, 396 mWriter->setClientTarget(0, nullptr, -1, Dataspace::UNKNOWN,
406 std::vector<IComposerClient::Rect>()); 397 std::vector<IComposerClient::Rect>());
407 398
408 execute(); 399 execute();
409} 400}
410 401
411/** 402/**
412 * Test IComposerClient::Command::SET_OUTPUT_BUFFER. 403 * Test IComposerClient::Command::SET_OUTPUT_BUFFER.
413 */ 404 */
414TEST_F(GraphicsComposerHidlCommandTest, SET_OUTPUT_BUFFER) { 405TEST_F(GraphicsComposerHidlCommandTest, SET_OUTPUT_BUFFER) {
415 if (mComposerClient->getMaxVirtualDisplayCount() == 0) { 406 if (mComposerClient->getMaxVirtualDisplayCount() == 0) {
416 GTEST_SUCCEED() << "no virtual display support"; 407 GTEST_SUCCEED() << "no virtual display support";
417 return; 408 return;
418 } 409 }
419 410
420 Display display; 411 Display display;
421 PixelFormat format; 412 PixelFormat format;
422 ASSERT_NO_FATAL_FAILURE(display = mComposerClient->createVirtualDisplay( 413 ASSERT_NO_FATAL_FAILURE(
423 64, 64, PixelFormat::IMPLEMENTATION_DEFINED, 414 display = mComposerClient->createVirtualDisplay(64, 64, PixelFormat::IMPLEMENTATION_DEFINED,
424 kBufferSlotCount, &format)); 415 kBufferSlotCount, &format));
425 416
426 const native_handle_t* handle; 417 const native_handle_t* handle;
427 ASSERT_NO_FATAL_FAILURE(handle = allocate()); 418 ASSERT_NO_FATAL_FAILURE(handle = allocate());
428 419
429 mWriter->selectDisplay(display); 420 mWriter->selectDisplay(display);
430 mWriter->setOutputBuffer(0, handle, -1); 421 mWriter->setOutputBuffer(0, handle, -1);
431 execute(); 422 execute();
432} 423}
433 424
434/** 425/**
435 * Test IComposerClient::Command::VALIDATE_DISPLAY. 426 * Test IComposerClient::Command::VALIDATE_DISPLAY.
436 */ 427 */
437TEST_F(GraphicsComposerHidlCommandTest, VALIDATE_DISPLAY) { 428TEST_F(GraphicsComposerHidlCommandTest, VALIDATE_DISPLAY) {
438 mWriter->selectDisplay(mPrimaryDisplay); 429 mWriter->selectDisplay(mPrimaryDisplay);
439 mWriter->validateDisplay(); 430 mWriter->validateDisplay();
440 execute(); 431 execute();
441} 432}
442 433
443/** 434/**
444 * Test IComposerClient::Command::ACCEPT_DISPLAY_CHANGES. 435 * Test IComposerClient::Command::ACCEPT_DISPLAY_CHANGES.
445 */ 436 */
446TEST_F(GraphicsComposerHidlCommandTest, ACCEPT_DISPLAY_CHANGES) { 437TEST_F(GraphicsComposerHidlCommandTest, ACCEPT_DISPLAY_CHANGES) {
447 mWriter->selectDisplay(mPrimaryDisplay); 438 mWriter->selectDisplay(mPrimaryDisplay);
448 mWriter->validateDisplay(); 439 mWriter->validateDisplay();
449 mWriter->acceptDisplayChanges(); 440 mWriter->acceptDisplayChanges();
450 execute(); 441 execute();
451} 442}
452 443
453/** 444/**
454 * Test IComposerClient::Command::PRESENT_DISPLAY. 445 * Test IComposerClient::Command::PRESENT_DISPLAY.
455 */ 446 */
456TEST_F(GraphicsComposerHidlCommandTest, PRESENT_DISPLAY) { 447TEST_F(GraphicsComposerHidlCommandTest, PRESENT_DISPLAY) {
457 mWriter->selectDisplay(mPrimaryDisplay); 448 mWriter->selectDisplay(mPrimaryDisplay);
458 mWriter->validateDisplay(); 449 mWriter->validateDisplay();
459 mWriter->presentDisplay(); 450 mWriter->presentDisplay();
460 execute(); 451 execute();
461} 452}
462 453
463/** 454/**
464 * Test IComposerClient::Command::SET_LAYER_CURSOR_POSITION. 455 * Test IComposerClient::Command::SET_LAYER_CURSOR_POSITION.
465 */ 456 */
466TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_CURSOR_POSITION) { 457TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_CURSOR_POSITION) {
467 Layer layer; 458 Layer layer;
468 ASSERT_NO_FATAL_FAILURE( 459 ASSERT_NO_FATAL_FAILURE(layer =
469 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 460 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
470 461
471 mWriter->selectDisplay(mPrimaryDisplay); 462 mWriter->selectDisplay(mPrimaryDisplay);
472 mWriter->selectLayer(layer); 463 mWriter->selectLayer(layer);
473 mWriter->setLayerCursorPosition(1, 1); 464 mWriter->setLayerCursorPosition(1, 1);
474 mWriter->setLayerCursorPosition(0, 0); 465 mWriter->setLayerCursorPosition(0, 0);
475 execute(); 466 execute();
476} 467}
477 468
478/** 469/**
479 * Test IComposerClient::Command::SET_LAYER_BUFFER. 470 * Test IComposerClient::Command::SET_LAYER_BUFFER.
480 */ 471 */
481TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER) { 472TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER) {
482 auto handle = allocate(); 473 auto handle = allocate();
483 ASSERT_NE(nullptr, handle); 474 ASSERT_NE(nullptr, handle);
484 475
485 Layer layer; 476 Layer layer;
486 ASSERT_NO_FATAL_FAILURE( 477 ASSERT_NO_FATAL_FAILURE(layer =
487 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 478 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
488 479
489 mWriter->selectDisplay(mPrimaryDisplay); 480 mWriter->selectDisplay(mPrimaryDisplay);
490 mWriter->selectLayer(layer); 481 mWriter->selectLayer(layer);
491 mWriter->setLayerBuffer(0, handle, -1); 482 mWriter->setLayerBuffer(0, handle, -1);
492 execute(); 483 execute();
493} 484}
494 485
495/** 486/**
496 * Test IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE. 487 * Test IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE.
497 */ 488 */
498TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_SURFACE_DAMAGE) { 489TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_SURFACE_DAMAGE) {
499 Layer layer; 490 Layer layer;
500 ASSERT_NO_FATAL_FAILURE( 491 ASSERT_NO_FATAL_FAILURE(layer =
501 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 492 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
502 493
503 IComposerClient::Rect empty{0, 0, 0, 0}; 494 IComposerClient::Rect empty{0, 0, 0, 0};
504 IComposerClient::Rect unit{0, 0, 1, 1}; 495 IComposerClient::Rect unit{0, 0, 1, 1};
505 496
506 mWriter->selectDisplay(mPrimaryDisplay); 497 mWriter->selectDisplay(mPrimaryDisplay);
507 mWriter->selectLayer(layer); 498 mWriter->selectLayer(layer);
508 mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, empty)); 499 mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, empty));
509 mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, unit)); 500 mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, unit));
510 mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>()); 501 mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>());
511 execute(); 502 execute();
512} 503}
513 504
514/** 505/**
515 * Test IComposerClient::Command::SET_LAYER_BLEND_MODE. 506 * Test IComposerClient::Command::SET_LAYER_BLEND_MODE.
516 */ 507 */
517TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_BLEND_MODE) { 508TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_BLEND_MODE) {
518 Layer layer; 509 Layer layer;
519 ASSERT_NO_FATAL_FAILURE( 510 ASSERT_NO_FATAL_FAILURE(layer =
520 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 511 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
521 512
522 mWriter->selectDisplay(mPrimaryDisplay); 513 mWriter->selectDisplay(mPrimaryDisplay);
523 mWriter->selectLayer(layer); 514 mWriter->selectLayer(layer);
524 mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE); 515 mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE);
525 mWriter->setLayerBlendMode(IComposerClient::BlendMode::PREMULTIPLIED); 516 mWriter->setLayerBlendMode(IComposerClient::BlendMode::PREMULTIPLIED);
526 mWriter->setLayerBlendMode(IComposerClient::BlendMode::COVERAGE); 517 mWriter->setLayerBlendMode(IComposerClient::BlendMode::COVERAGE);
527 execute(); 518 execute();
528} 519}
529 520
530/** 521/**
531 * Test IComposerClient::Command::SET_LAYER_COLOR. 522 * Test IComposerClient::Command::SET_LAYER_COLOR.
532 */ 523 */
533TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_COLOR) { 524TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_COLOR) {
534 Layer layer; 525 Layer layer;
535 ASSERT_NO_FATAL_FAILURE( 526 ASSERT_NO_FATAL_FAILURE(layer =
536 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 527 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
537 528
538 mWriter->selectDisplay(mPrimaryDisplay); 529 mWriter->selectDisplay(mPrimaryDisplay);
539 mWriter->selectLayer(layer); 530 mWriter->selectLayer(layer);
540 mWriter->setLayerColor(IComposerClient::Color{0xff, 0xff, 0xff, 0xff}); 531 mWriter->setLayerColor(IComposerClient::Color{0xff, 0xff, 0xff, 0xff});
541 mWriter->setLayerColor(IComposerClient::Color{0, 0, 0, 0}); 532 mWriter->setLayerColor(IComposerClient::Color{0, 0, 0, 0});
542 execute(); 533 execute();
543} 534}
544 535
545/** 536/**
546 * Test IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE. 537 * Test IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE.
547 */ 538 */
548TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_COMPOSITION_TYPE) { 539TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_COMPOSITION_TYPE) {
549 Layer layer; 540 Layer layer;
550 ASSERT_NO_FATAL_FAILURE( 541 ASSERT_NO_FATAL_FAILURE(layer =
551 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 542 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
552 543
553 mWriter->selectDisplay(mPrimaryDisplay); 544 mWriter->selectDisplay(mPrimaryDisplay);
554 mWriter->selectLayer(layer); 545 mWriter->selectLayer(layer);
555 mWriter->setLayerCompositionType(IComposerClient::Composition::CLIENT); 546 mWriter->setLayerCompositionType(IComposerClient::Composition::CLIENT);
556 mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE); 547 mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
557 mWriter->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR); 548 mWriter->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
558 mWriter->setLayerCompositionType(IComposerClient::Composition::CURSOR); 549 mWriter->setLayerCompositionType(IComposerClient::Composition::CURSOR);
559 execute(); 550 execute();
560} 551}
561 552
562/** 553/**
563 * Test IComposerClient::Command::SET_LAYER_DATASPACE. 554 * Test IComposerClient::Command::SET_LAYER_DATASPACE.
564 */ 555 */
565TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_DATASPACE) { 556TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_DATASPACE) {
566 Layer layer; 557 Layer layer;
567 ASSERT_NO_FATAL_FAILURE( 558 ASSERT_NO_FATAL_FAILURE(layer =
568 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 559 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
569 560
570 mWriter->selectDisplay(mPrimaryDisplay); 561 mWriter->selectDisplay(mPrimaryDisplay);
571 mWriter->selectLayer(layer); 562 mWriter->selectLayer(layer);
572 mWriter->setLayerDataspace(Dataspace::UNKNOWN); 563 mWriter->setLayerDataspace(Dataspace::UNKNOWN);
573 execute(); 564 execute();
574} 565}
575 566
576/** 567/**
577 * Test IComposerClient::Command::SET_LAYER_DISPLAY_FRAME. 568 * Test IComposerClient::Command::SET_LAYER_DISPLAY_FRAME.
578 */ 569 */
579TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_DISPLAY_FRAME) { 570TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_DISPLAY_FRAME) {
580 Layer layer; 571 Layer layer;
581 ASSERT_NO_FATAL_FAILURE( 572 ASSERT_NO_FATAL_FAILURE(layer =
582 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 573 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
583 574
584 mWriter->selectDisplay(mPrimaryDisplay); 575 mWriter->selectDisplay(mPrimaryDisplay);
585 mWriter->selectLayer(layer); 576 mWriter->selectLayer(layer);
586 mWriter->setLayerDisplayFrame(IComposerClient::Rect{0, 0, 1, 1}); 577 mWriter->setLayerDisplayFrame(IComposerClient::Rect{0, 0, 1, 1});
587 execute(); 578 execute();
588} 579}
589 580
590/** 581/**
591 * Test IComposerClient::Command::SET_LAYER_PLANE_ALPHA. 582 * Test IComposerClient::Command::SET_LAYER_PLANE_ALPHA.
592 */ 583 */
593TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PLANE_ALPHA) { 584TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PLANE_ALPHA) {
594 Layer layer; 585 Layer layer;
595 ASSERT_NO_FATAL_FAILURE( 586 ASSERT_NO_FATAL_FAILURE(layer =
596 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 587 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
597 588
598 mWriter->selectDisplay(mPrimaryDisplay); 589 mWriter->selectDisplay(mPrimaryDisplay);
599 mWriter->selectLayer(layer); 590 mWriter->selectLayer(layer);
600 mWriter->setLayerPlaneAlpha(0.0f); 591 mWriter->setLayerPlaneAlpha(0.0f);
601 mWriter->setLayerPlaneAlpha(1.0f); 592 mWriter->setLayerPlaneAlpha(1.0f);
602 execute(); 593 execute();
603} 594}
604 595
605/** 596/**
606 * Test IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM. 597 * Test IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM.
607 */ 598 */
608TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_SIDEBAND_STREAM) { 599TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_SIDEBAND_STREAM) {
609 if (!mComposer->hasCapability(IComposer::Capability::SIDEBAND_STREAM)) { 600 if (!mComposer->hasCapability(IComposer::Capability::SIDEBAND_STREAM)) {
610 GTEST_SUCCEED() << "no sideband stream support"; 601 GTEST_SUCCEED() << "no sideband stream support";
611 return; 602 return;
612 } 603 }
613 604
614 auto handle = allocate(); 605 auto handle = allocate();
615 ASSERT_NE(nullptr, handle); 606 ASSERT_NE(nullptr, handle);
616 607
617 Layer layer; 608 Layer layer;
618 ASSERT_NO_FATAL_FAILURE( 609 ASSERT_NO_FATAL_FAILURE(layer =
619 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 610 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
620 611
621 mWriter->selectDisplay(mPrimaryDisplay); 612 mWriter->selectDisplay(mPrimaryDisplay);
622 mWriter->selectLayer(layer); 613 mWriter->selectLayer(layer);
623 mWriter->setLayerSidebandStream(handle); 614 mWriter->setLayerSidebandStream(handle);
624 execute(); 615 execute();
625} 616}
626 617
627/** 618/**
628 * Test IComposerClient::Command::SET_LAYER_SOURCE_CROP. 619 * Test IComposerClient::Command::SET_LAYER_SOURCE_CROP.
629 */ 620 */
630TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_SOURCE_CROP) { 621TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_SOURCE_CROP) {
631 Layer layer; 622 Layer layer;
632 ASSERT_NO_FATAL_FAILURE( 623 ASSERT_NO_FATAL_FAILURE(layer =
633 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 624 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
634 625
635 mWriter->selectDisplay(mPrimaryDisplay); 626 mWriter->selectDisplay(mPrimaryDisplay);
636 mWriter->selectLayer(layer); 627 mWriter->selectLayer(layer);
637 mWriter->setLayerSourceCrop(IComposerClient::FRect{0.0f, 0.0f, 1.0f, 1.0f}); 628 mWriter->setLayerSourceCrop(IComposerClient::FRect{0.0f, 0.0f, 1.0f, 1.0f});
638 execute(); 629 execute();
639} 630}
640 631
641/** 632/**
642 * Test IComposerClient::Command::SET_LAYER_TRANSFORM. 633 * Test IComposerClient::Command::SET_LAYER_TRANSFORM.
643 */ 634 */
644TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_TRANSFORM) { 635TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_TRANSFORM) {
645 Layer layer; 636 Layer layer;
646 ASSERT_NO_FATAL_FAILURE( 637 ASSERT_NO_FATAL_FAILURE(layer =
647 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 638 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
648 639
649 mWriter->selectDisplay(mPrimaryDisplay); 640 mWriter->selectDisplay(mPrimaryDisplay);
650 mWriter->selectLayer(layer); 641 mWriter->selectLayer(layer);
651 mWriter->setLayerTransform(static_cast<Transform>(0)); 642 mWriter->setLayerTransform(static_cast<Transform>(0));
652 mWriter->setLayerTransform(Transform::FLIP_H); 643 mWriter->setLayerTransform(Transform::FLIP_H);
653 mWriter->setLayerTransform(Transform::FLIP_V); 644 mWriter->setLayerTransform(Transform::FLIP_V);
654 mWriter->setLayerTransform(Transform::ROT_90); 645 mWriter->setLayerTransform(Transform::ROT_90);
655 mWriter->setLayerTransform(Transform::ROT_180); 646 mWriter->setLayerTransform(Transform::ROT_180);
656 mWriter->setLayerTransform(Transform::ROT_270); 647 mWriter->setLayerTransform(Transform::ROT_270);
657 mWriter->setLayerTransform( 648 mWriter->setLayerTransform(static_cast<Transform>(Transform::FLIP_H | Transform::ROT_90));
658 static_cast<Transform>(Transform::FLIP_H | Transform::ROT_90)); 649 mWriter->setLayerTransform(static_cast<Transform>(Transform::FLIP_V | Transform::ROT_90));
659 mWriter->setLayerTransform( 650 execute();
660 static_cast<Transform>(Transform::FLIP_V | Transform::ROT_90));
661 execute();
662} 651}
663 652
664/** 653/**
665 * Test IComposerClient::Command::SET_LAYER_VISIBLE_REGION. 654 * Test IComposerClient::Command::SET_LAYER_VISIBLE_REGION.
666 */ 655 */
667TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_VISIBLE_REGION) { 656TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_VISIBLE_REGION) {
668 Layer layer; 657 Layer layer;
669 ASSERT_NO_FATAL_FAILURE( 658 ASSERT_NO_FATAL_FAILURE(layer =
670 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 659 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
671 660
672 IComposerClient::Rect empty{0, 0, 0, 0}; 661 IComposerClient::Rect empty{0, 0, 0, 0};
673 IComposerClient::Rect unit{0, 0, 1, 1}; 662 IComposerClient::Rect unit{0, 0, 1, 1};
674 663
675 mWriter->selectDisplay(mPrimaryDisplay); 664 mWriter->selectDisplay(mPrimaryDisplay);
676 mWriter->selectLayer(layer); 665 mWriter->selectLayer(layer);
677 mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, empty)); 666 mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, empty));
678 mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, unit)); 667 mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, unit));
679 mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>()); 668 mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>());
680 execute(); 669 execute();
681} 670}
682 671
683/** 672/**
684 * Test IComposerClient::Command::SET_LAYER_Z_ORDER. 673 * Test IComposerClient::Command::SET_LAYER_Z_ORDER.
685 */ 674 */
686TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_Z_ORDER) { 675TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_Z_ORDER) {
687 Layer layer; 676 Layer layer;
688 ASSERT_NO_FATAL_FAILURE( 677 ASSERT_NO_FATAL_FAILURE(layer =
689 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); 678 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
690 679
691 mWriter->selectDisplay(mPrimaryDisplay); 680 mWriter->selectDisplay(mPrimaryDisplay);
692 mWriter->selectLayer(layer); 681 mWriter->selectLayer(layer);
693 mWriter->setLayerZOrder(10); 682 mWriter->setLayerZOrder(10);
694 mWriter->setLayerZOrder(0); 683 mWriter->setLayerZOrder(0);
695 execute(); 684 execute();
696} 685}
697 686
698} // namespace anonymous 687} // namespace
699} // namespace tests 688} // namespace vts
700} // namespace V2_1 689} // namespace V2_1
701} // namespace composer 690} // namespace composer
702} // namespace graphics 691} // namespace graphics
@@ -704,7 +693,7 @@ TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_Z_ORDER) {
704} // namespace android 693} // namespace android
705 694
706int main(int argc, char** argv) { 695int main(int argc, char** argv) {
707 using android::hardware::graphics::composer::V2_1::tests::GraphicsComposerHidlEnvironment; 696 using android::hardware::graphics::composer::V2_1::vts::GraphicsComposerHidlEnvironment;
708 ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance()); 697 ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance());
709 ::testing::InitGoogleTest(&argc, argv); 698 ::testing::InitGoogleTest(&argc, argv);
710 GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv); 699 GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv);
diff --git a/graphics/composer/2.2/default/Android.bp b/graphics/composer/2.2/default/Android.bp
new file mode 100644
index 00000000..906479e6
--- /dev/null
+++ b/graphics/composer/2.2/default/Android.bp
@@ -0,0 +1,31 @@
1cc_binary {
2 name: "android.hardware.graphics.composer@2.2-service",
3 defaults: ["hidl_defaults"],
4 vendor: true,
5 relative_install_path: "hw",
6 srcs: ["service.cpp"],
7 init_rc: ["android.hardware.graphics.composer@2.2-service.rc"],
8 header_libs: [
9 "android.hardware.graphics.composer@2.2-passthrough",
10 ],
11 shared_libs: [
12 "android.hardware.graphics.composer@2.1",
13 "android.hardware.graphics.composer@2.2",
14 "android.hardware.graphics.mapper@2.0",
15 "libbase",
16 "libbinder",
17 "libcutils",
18 "libfmq",
19 "libhardware",
20 "libhidlbase",
21 "libhidltransport",
22 "libhwc2on1adapter",
23 "libhwc2onfbadapter",
24 "liblog",
25 "libsync",
26 "libutils",
27 ],
28 cflags: [
29 "-DLOG_TAG=\"ComposerHal\""
30 ],
31}
diff --git a/graphics/composer/2.2/default/OWNERS b/graphics/composer/2.2/default/OWNERS
new file mode 100644
index 00000000..4714be2d
--- /dev/null
+++ b/graphics/composer/2.2/default/OWNERS
@@ -0,0 +1,5 @@
1# Graphics team
2courtneygo@google.com
3jessehall@google.com
4olv@google.com
5stoza@google.com
diff --git a/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
new file mode 100644
index 00000000..a41d902c
--- /dev/null
+++ b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc
@@ -0,0 +1,6 @@
1service vendor.hwcomposer-2-2 /vendor/bin/hw/android.hardware.graphics.composer@2.2-service
2 class hal animation
3 user system
4 group graphics drmrpc
5 capabilities SYS_NICE
6 onrestart restart surfaceflinger
diff --git a/graphics/composer/2.2/default/service.cpp b/graphics/composer/2.2/default/service.cpp
new file mode 100644
index 00000000..8c5ef189
--- /dev/null
+++ b/graphics/composer/2.2/default/service.cpp
@@ -0,0 +1,55 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <sched.h>
18
19#include <android/hardware/graphics/composer/2.2/IComposer.h>
20#include <binder/ProcessState.h>
21#include <composer-passthrough/2.2/HwcLoader.h>
22#include <hidl/HidlTransportSupport.h>
23
24using android::hardware::graphics::composer::V2_2::IComposer;
25using android::hardware::graphics::composer::V2_2::passthrough::HwcLoader;
26
27int main() {
28 // the conventional HAL might start binder services
29 android::ProcessState::initWithDriver("/dev/vndbinder");
30 android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
31 android::ProcessState::self()->startThreadPool();
32
33 // same as SF main thread
34 struct sched_param param = {0};
35 param.sched_priority = 2;
36 if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
37 ALOGE("Couldn't set SCHED_FIFO: %d", errno);
38 }
39
40 android::hardware::configureRpcThreadpool(4, true /* will join */);
41
42 android::sp<IComposer> composer = HwcLoader::load();
43 if (composer == nullptr) {
44 return 1;
45 }
46 if (composer->registerAsService() != android::NO_ERROR) {
47 ALOGE("failed to register service");
48 return 1;
49 }
50
51 android::hardware::joinRpcThreadpool();
52
53 ALOGE("service is terminating");
54 return 1;
55}
diff --git a/graphics/composer/2.2/utils/hal/Android.bp b/graphics/composer/2.2/utils/hal/Android.bp
new file mode 100644
index 00000000..10dcae4d
--- /dev/null
+++ b/graphics/composer/2.2/utils/hal/Android.bp
@@ -0,0 +1,35 @@
1//
2// Copyright (C) 2018 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16cc_library_headers {
17 name: "android.hardware.graphics.composer@2.2-hal",
18 defaults: ["hidl_defaults"],
19 vendor_available: true,
20 shared_libs: [
21 "android.hardware.graphics.composer@2.2",
22 ],
23 export_shared_lib_headers: [
24 "android.hardware.graphics.composer@2.2",
25 ],
26 header_libs: [
27 "android.hardware.graphics.composer@2.2-command-buffer",
28 "android.hardware.graphics.composer@2.1-hal",
29 ],
30 export_header_lib_headers: [
31 "android.hardware.graphics.composer@2.2-command-buffer",
32 "android.hardware.graphics.composer@2.1-hal",
33 ],
34 export_include_dirs: ["include"],
35}
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/Composer.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/Composer.h
new file mode 100644
index 00000000..58bbaa57
--- /dev/null
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/Composer.h
@@ -0,0 +1,74 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "Composer.h included without LOG_TAG"
21#endif
22
23#include <android/hardware/graphics/composer/2.2/IComposer.h>
24#include <composer-hal/2.1/Composer.h>
25#include <composer-hal/2.2/ComposerClient.h>
26
27namespace android {
28namespace hardware {
29namespace graphics {
30namespace composer {
31namespace V2_2 {
32namespace hal {
33
34namespace detail {
35
36// ComposerImpl implements V2_*::IComposer on top of V2_*::ComposerHal
37template <typename Interface, typename Hal>
38class ComposerImpl : public V2_1::hal::detail::ComposerImpl<Interface, Hal> {
39 public:
40 static std::unique_ptr<ComposerImpl> create(std::unique_ptr<Hal> hal) {
41 return std::make_unique<ComposerImpl>(std::move(hal));
42 }
43
44 ComposerImpl(std::unique_ptr<Hal> hal) : BaseType2_1(std::move(hal)) {}
45
46 protected:
47 V2_1::IComposerClient* createClient() override {
48 auto client = ComposerClient::create(mHal.get());
49 if (!client) {
50 return nullptr;
51 }
52
53 auto clientDestroyed = [this]() { onClientDestroyed(); };
54 client->setOnClientDestroyed(clientDestroyed);
55
56 return client.release();
57 }
58
59 private:
60 using BaseType2_1 = V2_1::hal::detail::ComposerImpl<Interface, Hal>;
61 using BaseType2_1::mHal;
62 using BaseType2_1::onClientDestroyed;
63};
64
65} // namespace detail
66
67using Composer = detail::ComposerImpl<IComposer, ComposerHal>;
68
69} // namespace hal
70} // namespace V2_2
71} // namespace composer
72} // namespace graphics
73} // namespace hardware
74} // namespace android
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h
new file mode 100644
index 00000000..d550f834
--- /dev/null
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h
@@ -0,0 +1,162 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "ComposerClient.h included without LOG_TAG"
21#endif
22
23#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
24#include <composer-hal/2.1/ComposerClient.h>
25#include <composer-hal/2.2/ComposerCommandEngine.h>
26#include <composer-hal/2.2/ComposerHal.h>
27#include <composer-hal/2.2/ComposerResources.h>
28
29namespace android {
30namespace hardware {
31namespace graphics {
32namespace composer {
33namespace V2_2 {
34namespace hal {
35
36namespace detail {
37
38// ComposerClientImpl implements V2_*::IComposerClient on top of V2_*::ComposerHal
39template <typename Interface, typename Hal>
40class ComposerClientImpl : public V2_1::hal::detail::ComposerClientImpl<Interface, Hal> {
41 public:
42 static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {
43 auto client = std::make_unique<ComposerClientImpl>(hal);
44 return client->init() ? std::move(client) : nullptr;
45 }
46
47 ComposerClientImpl(Hal* hal) : BaseType2_1(hal) {}
48
49 // IComposerClient 2.2 interface
50
51 Return<void> getPerFrameMetadataKeys(
52 Display display, IComposerClient::getPerFrameMetadataKeys_cb hidl_cb) override {
53 std::vector<IComposerClient::PerFrameMetadataKey> keys;
54 Error error = mHal->getPerFrameMetadataKeys(display, &keys);
55 hidl_cb(error, keys);
56 return Void();
57 }
58
59 Return<void> getReadbackBufferAttributes(
60 Display display, IComposerClient::getReadbackBufferAttributes_cb hidl_cb) override {
61 PixelFormat format = static_cast<PixelFormat>(0);
62 Dataspace dataspace = Dataspace::UNKNOWN;
63 Error error = mHal->getReadbackBufferAttributes(display, &format, &dataspace);
64 hidl_cb(error, format, dataspace);
65 return Void();
66 }
67
68 Return<void> getReadbackBufferFence(
69 Display display, IComposerClient::getReadbackBufferFence_cb hidl_cb) override {
70 base::unique_fd fenceFd;
71 Error error = mHal->getReadbackBufferFence(display, &fenceFd);
72 if (error != Error::NONE) {
73 hidl_cb(error, nullptr);
74 return Void();
75 }
76
77 NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
78 hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
79 return Void();
80 }
81
82 Return<Error> setReadbackBuffer(Display display, const hidl_handle& buffer,
83 const hidl_handle& releaseFence) override {
84 base::unique_fd fenceFd;
85 Error error = getFenceFd(releaseFence, &fenceFd);
86 if (error != Error::NONE) {
87 return error;
88 }
89
90 auto resources = static_cast<ComposerResources*>(mResources.get());
91 const native_handle_t* readbackBuffer;
92 ComposerResources::ReplacedBufferHandle replacedReadbackBuffer;
93 error = resources->getDisplayReadbackBuffer(display, buffer.getNativeHandle(),
94 &readbackBuffer, &replacedReadbackBuffer);
95 if (error != Error::NONE) {
96 return error;
97 }
98
99 return mHal->setReadbackBuffer(display, readbackBuffer, std::move(fenceFd));
100 }
101
102 Return<Error> setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override {
103 return mHal->setPowerMode_2_2(display, mode);
104 }
105
106 protected:
107 std::unique_ptr<V2_1::hal::ComposerResources> createResources() override {
108 return ComposerResources::create();
109 }
110
111 std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
112 return std::make_unique<ComposerCommandEngine>(
113 mHal, static_cast<ComposerResources*>(mResources.get()));
114 }
115
116 // convert fenceFd to or from hidl_handle
117 static Error getFenceFd(const hidl_handle& fenceHandle, base::unique_fd* outFenceFd) {
118 auto handle = fenceHandle.getNativeHandle();
119 if (handle && handle->numFds > 1) {
120 ALOGE("invalid fence handle with %d fds", handle->numFds);
121 return Error::BAD_PARAMETER;
122 }
123
124 int fenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
125 if (fenceFd >= 0) {
126 fenceFd = dup(fenceFd);
127 if (fenceFd < 0) {
128 return Error::NO_RESOURCES;
129 }
130 }
131
132 outFenceFd->reset(fenceFd);
133
134 return Error::NONE;
135 }
136
137 static hidl_handle getFenceHandle(const base::unique_fd& fenceFd, char* handleStorage) {
138 native_handle_t* handle = nullptr;
139 if (fenceFd >= 0) {
140 handle = native_handle_init(handleStorage, 1, 0);
141 handle->data[0] = fenceFd;
142 }
143
144 return hidl_handle(handle);
145 }
146
147 private:
148 using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
149 using BaseType2_1::mHal;
150 using BaseType2_1::mResources;
151};
152
153} // namespace detail
154
155using ComposerClient = detail::ComposerClientImpl<IComposerClient, ComposerHal>;
156
157} // namespace hal
158} // namespace V2_2
159} // namespace composer
160} // namespace graphics
161} // namespace hardware
162} // namespace android
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h
new file mode 100644
index 00000000..adcac463
--- /dev/null
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h
@@ -0,0 +1,103 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "ComposerCommandEngine.h included without LOG_TAG"
21#endif
22
23#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
24#include <composer-hal/2.1/ComposerCommandEngine.h>
25#include <composer-hal/2.2/ComposerHal.h>
26#include <composer-hal/2.2/ComposerResources.h>
27
28namespace android {
29namespace hardware {
30namespace graphics {
31namespace composer {
32namespace V2_2 {
33namespace hal {
34
35class ComposerCommandEngine : public V2_1::hal::ComposerCommandEngine {
36 public:
37 ComposerCommandEngine(ComposerHal* hal, ComposerResources* resources)
38 : BaseType2_1(hal, resources), mHal(hal) {}
39
40 protected:
41 bool executeCommand(V2_1::IComposerClient::Command command, uint16_t length) override {
42 switch (static_cast<IComposerClient::Command>(command)) {
43 case IComposerClient::Command::SET_PER_FRAME_METADATA:
44 return executeSetPerFrameMetadata(length);
45 case IComposerClient::Command::SET_LAYER_FLOAT_COLOR:
46 return executeSetLayerFloatColor(length);
47 default:
48 return BaseType2_1::executeCommand(command, length);
49 }
50 }
51
52 bool executeSetPerFrameMetadata(uint16_t length) {
53 // (key, value) pairs
54 if (length % 2 != 0) {
55 return false;
56 }
57
58 std::vector<IComposerClient::PerFrameMetadata> metadata;
59 metadata.reserve(length / 2);
60 while (length > 0) {
61 metadata.emplace_back(IComposerClient::PerFrameMetadata{
62 static_cast<IComposerClient::PerFrameMetadataKey>(readSigned()), readFloat()});
63 length -= 2;
64 }
65
66 auto err = mHal->setPerFrameMetadata(mCurrentDisplay, metadata);
67 if (err != Error::NONE) {
68 mWriter.setError(getCommandLoc(), err);
69 }
70
71 return true;
72 }
73
74 bool executeSetLayerFloatColor(uint16_t length) {
75 if (length != CommandWriterBase::kSetLayerFloatColorLength) {
76 return false;
77 }
78
79 auto err = mHal->setLayerFloatColor(mCurrentDisplay, mCurrentLayer, readFloatColor());
80 if (err != Error::NONE) {
81 mWriter.setError(getCommandLoc(), err);
82 }
83
84 return true;
85 }
86
87 IComposerClient::FloatColor readFloatColor() {
88 return IComposerClient::FloatColor{readFloat(), readFloat(), readFloat(), readFloat()};
89 }
90
91 private:
92 using BaseType2_1 = V2_1::hal::ComposerCommandEngine;
93 using BaseType2_1::mWriter;
94
95 ComposerHal* mHal;
96};
97
98} // namespace hal
99} // namespace V2_2
100} // namespace composer
101} // namespace graphics
102} // namespace hardware
103} // namespace android
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h
new file mode 100644
index 00000000..30b36439
--- /dev/null
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <android-base/unique_fd.h>
20#include <android/hardware/graphics/composer/2.2/IComposer.h>
21#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
22#include <composer-hal/2.1/ComposerHal.h>
23
24namespace android {
25namespace hardware {
26namespace graphics {
27namespace composer {
28namespace V2_2 {
29namespace hal {
30
31using common::V1_0::Dataspace;
32using common::V1_0::PixelFormat;
33using V2_1::Display;
34using V2_1::Error;
35using V2_1::Layer;
36
37class ComposerHal : public V2_1::hal::ComposerHal {
38 public:
39 // superceded by setPowerMode_2_2
40 Error setPowerMode(Display display, V2_1::IComposerClient::PowerMode mode) override {
41 return setPowerMode_2_2(display, static_cast<IComposerClient::PowerMode>(mode));
42 }
43
44 virtual Error getPerFrameMetadataKeys(
45 Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
46 virtual Error setPerFrameMetadata(
47 Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
48
49 virtual Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
50 Dataspace* outDataspace) = 0;
51 virtual Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle,
52 base::unique_fd fenceFd) = 0;
53 virtual Error getReadbackBufferFence(Display display, base::unique_fd* outFenceFd) = 0;
54
55 virtual Error setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) = 0;
56
57 virtual Error setLayerFloatColor(Display display, Layer layer,
58 IComposerClient::FloatColor color) = 0;
59};
60
61} // namespace hal
62} // namespace V2_2
63} // namespace composer
64} // namespace graphics
65} // namespace hardware
66} // namespace android
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerResources.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerResources.h
new file mode 100644
index 00000000..85b66517
--- /dev/null
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerResources.h
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "ComposerResources.h included without LOG_TAG"
21#endif
22
23#include <composer-hal/2.1/ComposerResources.h>
24
25namespace android {
26namespace hardware {
27namespace graphics {
28namespace composer {
29namespace V2_2 {
30namespace hal {
31
32using V2_1::hal::ComposerHandleCache;
33using V2_1::hal::ComposerHandleImporter;
34
35class ComposerDisplayResource : public V2_1::hal::ComposerDisplayResource {
36 public:
37 ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
38 uint32_t outputBufferCacheSize)
39 : V2_1::hal::ComposerDisplayResource(type, importer, outputBufferCacheSize),
40 mReadbackBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, 1) {}
41
42 Error getReadbackBuffer(const native_handle_t* inHandle, const native_handle_t** outHandle,
43 const native_handle** outReplacedHandle) {
44 const uint32_t slot = 0;
45 const bool fromCache = false;
46 return mReadbackBufferCache.getHandle(slot, fromCache, inHandle, outHandle,
47 outReplacedHandle);
48 }
49
50 protected:
51 ComposerHandleCache mReadbackBufferCache;
52};
53
54class ComposerResources : public V2_1::hal::ComposerResources {
55 public:
56 static std::unique_ptr<ComposerResources> create() {
57 auto resources = std::make_unique<ComposerResources>();
58 return resources->init() ? std::move(resources) : nullptr;
59 }
60
61 Error getDisplayReadbackBuffer(Display display, const native_handle_t* rawHandle,
62 const native_handle_t** outHandle,
63 ReplacedBufferHandle* outReplacedHandle) {
64 // import buffer
65 const native_handle_t* importedHandle;
66 Error error = mImporter.importBuffer(rawHandle, &importedHandle);
67 if (error != Error::NONE) {
68 return error;
69 }
70
71 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
72
73 auto iter = mDisplayResources.find(display);
74 if (iter == mDisplayResources.end()) {
75 mImporter.freeBuffer(importedHandle);
76 return Error::BAD_DISPLAY;
77 }
78 ComposerDisplayResource& displayResource =
79 *static_cast<ComposerDisplayResource*>(iter->second.get());
80
81 // update cache
82 const native_handle_t* replacedHandle;
83 error = displayResource.getReadbackBuffer(importedHandle, outHandle, &replacedHandle);
84 if (error != Error::NONE) {
85 mImporter.freeBuffer(importedHandle);
86 return error;
87 }
88
89 outReplacedHandle->reset(&mImporter, replacedHandle);
90 return Error::NONE;
91 }
92
93 protected:
94 std::unique_ptr<V2_1::hal::ComposerDisplayResource> createDisplayResource(
95 ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) override {
96 return std::make_unique<ComposerDisplayResource>(type, mImporter, outputBufferCacheSize);
97 }
98};
99
100} // namespace hal
101} // namespace V2_2
102} // namespace composer
103} // namespace graphics
104} // namespace hardware
105} // namespace android
diff --git a/graphics/composer/2.2/utils/passthrough/Android.bp b/graphics/composer/2.2/utils/passthrough/Android.bp
new file mode 100644
index 00000000..318ce914
--- /dev/null
+++ b/graphics/composer/2.2/utils/passthrough/Android.bp
@@ -0,0 +1,14 @@
1cc_library_headers {
2 name: "android.hardware.graphics.composer@2.2-passthrough",
3 defaults: ["hidl_defaults"],
4 vendor: true,
5 header_libs: [
6 "android.hardware.graphics.composer@2.1-passthrough",
7 "android.hardware.graphics.composer@2.2-hal",
8 ],
9 export_header_lib_headers: [
10 "android.hardware.graphics.composer@2.1-passthrough",
11 "android.hardware.graphics.composer@2.2-hal",
12 ],
13 export_include_dirs: ["include"],
14}
diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
new file mode 100644
index 00000000..b251351f
--- /dev/null
+++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
@@ -0,0 +1,208 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "HwcHal.h included without LOG_TAG"
21#endif
22
23#include <type_traits>
24
25#include <composer-hal/2.2/ComposerHal.h>
26#include <composer-passthrough/2.1/HwcHal.h>
27
28namespace android {
29namespace hardware {
30namespace graphics {
31namespace composer {
32namespace V2_2 {
33namespace passthrough {
34
35namespace detail {
36
37using common::V1_0::Dataspace;
38using common::V1_0::PixelFormat;
39using V2_1::Display;
40using V2_1::Error;
41using V2_1::Layer;
42
43// HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
44template <typename Hal>
45class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal> {
46 public:
47 // XXX when can we return Error::UNSUPPORTED?
48
49 Error getPerFrameMetadataKeys(
50 Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override {
51 if (!mDispatch.getPerFrameMetadataKeys) {
52 return Error::UNSUPPORTED;
53 }
54
55 uint32_t count = 0;
56 int32_t error = mDispatch.getPerFrameMetadataKeys(mDevice, display, &count, nullptr);
57 if (error != HWC2_ERROR_NONE) {
58 return static_cast<Error>(error);
59 }
60
61 std::vector<IComposerClient::PerFrameMetadataKey> keys(count);
62 error = mDispatch.getPerFrameMetadataKeys(
63 mDevice, display, &count,
64 reinterpret_cast<std::underlying_type<IComposerClient::PerFrameMetadataKey>::type*>(
65 keys.data()));
66 if (error != HWC2_ERROR_NONE) {
67 return static_cast<Error>(error);
68 }
69
70 keys.resize(count);
71 *outKeys = std::move(keys);
72 return Error::NONE;
73 }
74
75 Error setPerFrameMetadata(
76 Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
77 if (!mDispatch.setPerFrameMetadata) {
78 return Error::UNSUPPORTED;
79 }
80
81 std::vector<int32_t> keys;
82 std::vector<float> values;
83 keys.reserve(metadata.size());
84 values.reserve(metadata.size());
85 for (const auto& m : metadata) {
86 keys.push_back(static_cast<int32_t>(m.key));
87 values.push_back(m.value);
88 }
89
90 int32_t error = mDispatch.setPerFrameMetadata(mDevice, display, metadata.size(),
91 keys.data(), values.data());
92 return static_cast<Error>(error);
93 }
94
95 Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
96 Dataspace* outDataspace) override {
97 if (!mDispatch.getReadbackBufferAttributes) {
98 return Error::UNSUPPORTED;
99 }
100
101 int32_t format = 0;
102 int32_t dataspace = 0;
103 int32_t error =
104 mDispatch.getReadbackBufferAttributes(mDevice, display, &format, &dataspace);
105 if (error == HWC2_ERROR_NONE) {
106 *outFormat = static_cast<PixelFormat>(format);
107 *outDataspace = static_cast<Dataspace>(dataspace);
108 }
109 return static_cast<Error>(error);
110 }
111
112 Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle,
113 base::unique_fd fenceFd) override {
114 if (!mDispatch.setReadbackBuffer) {
115 return Error::UNSUPPORTED;
116 }
117
118 int32_t error =
119 mDispatch.setReadbackBuffer(mDevice, display, bufferHandle, fenceFd.release());
120 return static_cast<Error>(error);
121 }
122
123 Error getReadbackBufferFence(Display display, base::unique_fd* outFenceFd) override {
124 if (!mDispatch.getReadbackBufferFence) {
125 return Error::UNSUPPORTED;
126 }
127
128 int32_t fenceFd = -1;
129 int32_t error = mDispatch.getReadbackBufferFence(mDevice, display, &fenceFd);
130 outFenceFd->reset(fenceFd);
131 return static_cast<Error>(error);
132 }
133
134 Error setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override {
135 if (mode == IComposerClient::PowerMode::ON_SUSPEND) {
136 return Error::UNSUPPORTED;
137 }
138 return setPowerMode(display, static_cast<V2_1::IComposerClient::PowerMode>(mode));
139 }
140
141 Error setLayerFloatColor(Display display, Layer layer,
142 IComposerClient::FloatColor color) override {
143 if (!mDispatch.setLayerFloatColor) {
144 return Error::UNSUPPORTED;
145 }
146
147 int32_t error = mDispatch.setLayerFloatColor(
148 mDevice, display, layer, hwc_float_color{color.r, color.g, color.b, color.a});
149 return static_cast<Error>(error);
150 }
151
152 protected:
153 template <typename T>
154 bool initOptionalDispatch(hwc2_function_descriptor_t desc, T* outPfn) {
155 auto pfn = mDevice->getFunction(mDevice, desc);
156 if (pfn) {
157 *outPfn = reinterpret_cast<T>(pfn);
158 return true;
159 } else {
160 return false;
161 }
162 }
163
164 bool initDispatch() override {
165 if (!BaseType2_1::initDispatch()) {
166 return false;
167 }
168
169 initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, &mDispatch.setLayerFloatColor);
170
171 initOptionalDispatch(HWC2_FUNCTION_SET_PER_FRAME_METADATA, &mDispatch.setPerFrameMetadata);
172 initOptionalDispatch(HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS,
173 &mDispatch.getPerFrameMetadataKeys);
174
175 initOptionalDispatch(HWC2_FUNCTION_SET_READBACK_BUFFER, &mDispatch.setReadbackBuffer);
176 initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES,
177 &mDispatch.getReadbackBufferAttributes);
178 initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE,
179 &mDispatch.getReadbackBufferFence);
180
181 return true;
182 }
183
184 struct {
185 HWC2_PFN_SET_LAYER_FLOAT_COLOR setLayerFloatColor;
186 HWC2_PFN_SET_PER_FRAME_METADATA setPerFrameMetadata;
187 HWC2_PFN_GET_PER_FRAME_METADATA_KEYS getPerFrameMetadataKeys;
188 HWC2_PFN_SET_READBACK_BUFFER setReadbackBuffer;
189 HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES getReadbackBufferAttributes;
190 HWC2_PFN_GET_READBACK_BUFFER_FENCE getReadbackBufferFence;
191 } mDispatch = {};
192
193 private:
194 using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
195 using BaseType2_1::mDevice;
196 using BaseType2_1::setPowerMode;
197};
198
199} // namespace detail
200
201using HwcHal = detail::HwcHalImpl<hal::ComposerHal>;
202
203} // namespace passthrough
204} // namespace V2_2
205} // namespace composer
206} // namespace graphics
207} // namespace hardware
208} // namespace android
diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h
new file mode 100644
index 00000000..cb4a238f
--- /dev/null
+++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h
@@ -0,0 +1,79 @@
1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#ifndef LOG_TAG
20#warning "HwcLoader.h included without LOG_TAG"
21#endif
22
23#include <composer-hal/2.2/Composer.h>
24#include <composer-hal/2.2/ComposerHal.h>
25#include <composer-passthrough/2.1/HwcLoader.h>
26#include <composer-passthrough/2.2/HwcHal.h>
27
28namespace android {
29namespace hardware {
30namespace graphics {
31namespace composer {
32namespace V2_2 {
33namespace passthrough {
34
35class HwcLoader : public V2_1::passthrough::HwcLoader {
36 public:
37 static IComposer* load() {
38 const hw_module_t* module = loadModule();
39 if (!module) {
40 return nullptr;
41 }
42
43 auto hal = createHalWithAdapter(module);
44 if (!hal) {
45 return nullptr;
46 }
47
48 return createComposer(std::move(hal)).release();
49 }
50
51 // create a ComposerHal instance
52 static std::unique_ptr<hal::ComposerHal> createHal(const hw_module_t* module) {
53 auto hal = std::make_unique<HwcHal>();
54 return hal->initWithModule(module) ? std::move(hal) : nullptr;
55 }
56
57 // create a ComposerHal instance, insert an adapter if necessary
58 static std::unique_ptr<hal::ComposerHal> createHalWithAdapter(const hw_module_t* module) {
59 bool adapted;
60 hwc2_device_t* device = openDeviceWithAdapter(module, &adapted);
61 if (!device) {
62 return nullptr;
63 }
64 auto hal = std::make_unique<HwcHal>();
65 return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr;
66 }
67
68 // create an IComposer instance
69 static std::unique_ptr<IComposer> createComposer(std::unique_ptr<hal::ComposerHal> hal) {
70 return hal::Composer::create(std::move(hal));
71 }
72};
73
74} // namespace passthrough
75} // namespace V2_2
76} // namespace composer
77} // namespace graphics
78} // namespace hardware
79} // namespace android
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
new file mode 100644
index 00000000..641fdcb7
--- /dev/null
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -0,0 +1,39 @@
1//
2// Copyright (C) 2018 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17cc_library_static {
18 name: "android.hardware.graphics.composer@2.2-vts",
19 defaults: ["hidl_defaults"],
20 srcs: [
21 "ComposerVts.cpp",
22 ],
23 static_libs: [
24 "VtsHalHidlTargetTestBase",
25 "android.hardware.graphics.composer@2.1",
26 "android.hardware.graphics.composer@2.1-vts",
27 "android.hardware.graphics.composer@2.2",
28 ],
29 header_libs: [
30 "android.hardware.graphics.composer@2.1-command-buffer",
31 "android.hardware.graphics.composer@2.2-command-buffer",
32 ],
33 cflags: [
34 "-O0",
35 "-g",
36 "-DLOG_TAG=\"ComposerVts\"",
37 ],
38 export_include_dirs: ["include"],
39}
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerTestUtils.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index 00946cef..b536f671 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -14,22 +14,22 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <VtsHalHidlTargetTestBase.h> 17#include <composer-vts/2.2/ComposerVts.h>
18#include <hidl/HidlTransportUtils.h>
19 18
19#include <VtsHalHidlTargetTestBase.h>
20#include <composer-command-buffer/2.2/ComposerCommandBuffer.h> 20#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
21#include "2.2/VtsHalGraphicsComposerTestUtils.h" 21#include <hidl/HidlTransportUtils.h>
22 22
23namespace android { 23namespace android {
24namespace hardware { 24namespace hardware {
25namespace graphics { 25namespace graphics {
26namespace composer { 26namespace composer {
27namespace V2_2 { 27namespace V2_2 {
28namespace tests { 28namespace vts {
29 29
30using android::hardware::graphics::composer::V2_2::IComposerClient;
31using android::hardware::details::getDescriptor;
32using android::hardware::details::canCastInterface; 30using android::hardware::details::canCastInterface;
31using android::hardware::details::getDescriptor;
32using android::hardware::graphics::composer::V2_2::IComposerClient;
33 33
34std::unique_ptr<ComposerClient_v2_2> Composer_v2_2::createClient_v2_2() { 34std::unique_ptr<ComposerClient_v2_2> Composer_v2_2::createClient_v2_2() {
35 std::unique_ptr<ComposerClient_v2_2> client; 35 std::unique_ptr<ComposerClient_v2_2> client;
@@ -56,7 +56,7 @@ std::vector<IComposerClient::PerFrameMetadataKey> ComposerClient_v2_2::getPerFra
56 return keys; 56 return keys;
57} 57}
58 58
59void ComposerClient_v2_2::execute_v2_2(V2_1::tests::TestCommandReader* reader, 59void ComposerClient_v2_2::execute_v2_2(V2_1::vts::TestCommandReader* reader,
60 V2_2::CommandWriterBase* writer) { 60 V2_2::CommandWriterBase* writer) {
61 bool queueChanged = false; 61 bool queueChanged = false;
62 uint32_t commandLength = 0; 62 uint32_t commandLength = 0;
@@ -119,7 +119,7 @@ void ComposerClient_v2_2::getReadbackBufferFence(Display display, int32_t* outFe
119 *outFence = 0; 119 *outFence = 0;
120} 120}
121 121
122} // namespace tests 122} // namespace vts
123} // namespace V2_2 123} // namespace V2_2
124} // namespace composer 124} // namespace composer
125} // namespace graphics 125} // namespace graphics
diff --git a/graphics/composer/2.2/vts/functional/include/2.2/VtsHalGraphicsComposerTestUtils.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
index c5756ed8..eced69f2 100644
--- a/graphics/composer/2.2/vts/functional/include/2.2/VtsHalGraphicsComposerTestUtils.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
@@ -22,11 +22,11 @@
22#include <unordered_set> 22#include <unordered_set>
23#include <vector> 23#include <vector>
24 24
25#include <VtsHalGraphicsComposerTestUtils.h>
26#include <VtsHalHidlTargetTestBase.h> 25#include <VtsHalHidlTargetTestBase.h>
27#include <android/hardware/graphics/composer/2.2/IComposer.h> 26#include <android/hardware/graphics/composer/2.2/IComposer.h>
28#include <android/hardware/graphics/composer/2.2/IComposerClient.h> 27#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
29#include <composer-command-buffer/2.2/ComposerCommandBuffer.h> 28#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
29#include <composer-vts/2.1/ComposerVts.h>
30#include <utils/StrongPointer.h> 30#include <utils/StrongPointer.h>
31 31
32namespace android { 32namespace android {
@@ -34,7 +34,7 @@ namespace hardware {
34namespace graphics { 34namespace graphics {
35namespace composer { 35namespace composer {
36namespace V2_2 { 36namespace V2_2 {
37namespace tests { 37namespace vts {
38 38
39using android::hardware::graphics::common::V1_0::ColorMode; 39using android::hardware::graphics::common::V1_0::ColorMode;
40using android::hardware::graphics::common::V1_0::Dataspace; 40using android::hardware::graphics::common::V1_0::Dataspace;
@@ -47,22 +47,22 @@ class ComposerClient_v2_2;
47 47
48// Only thing I need for Composer_v2_2 is to create a v2_2 ComposerClient 48// Only thing I need for Composer_v2_2 is to create a v2_2 ComposerClient
49// Everything else is the same 49// Everything else is the same
50class Composer_v2_2 : public V2_1::tests::Composer { 50class Composer_v2_2 : public V2_1::vts::Composer {
51 public: 51 public:
52 Composer_v2_2() : V2_1::tests::Composer(){}; 52 Composer_v2_2() : V2_1::vts::Composer(){};
53 explicit Composer_v2_2(const std::string& name) : V2_1::tests::Composer(name){}; 53 explicit Composer_v2_2(const std::string& name) : V2_1::vts::Composer(name){};
54 54
55 std::unique_ptr<ComposerClient_v2_2> createClient_v2_2(); 55 std::unique_ptr<ComposerClient_v2_2> createClient_v2_2();
56}; 56};
57 57
58// A wrapper to IComposerClient. 58// A wrapper to IComposerClient.
59class ComposerClient_v2_2 59class ComposerClient_v2_2
60 : public android::hardware::graphics::composer::V2_1::tests::ComposerClient { 60 : public android::hardware::graphics::composer::V2_1::vts::ComposerClient {
61 public: 61 public:
62 ComposerClient_v2_2(const sp<IComposerClient>& client) 62 ComposerClient_v2_2(const sp<IComposerClient>& client)
63 : V2_1::tests::ComposerClient(client), mClient_v2_2(client){}; 63 : V2_1::vts::ComposerClient(client), mClient_v2_2(client){};
64 64
65 void execute_v2_2(V2_1::tests::TestCommandReader* reader, V2_2::CommandWriterBase* writer); 65 void execute_v2_2(V2_1::vts::TestCommandReader* reader, V2_2::CommandWriterBase* writer);
66 66
67 std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys(Display display); 67 std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys(Display display);
68 68
@@ -76,7 +76,7 @@ class ComposerClient_v2_2
76 sp<V2_2::IComposerClient> mClient_v2_2; 76 sp<V2_2::IComposerClient> mClient_v2_2;
77}; 77};
78 78
79} // namespace tests 79} // namespace vts
80} // namespace V2_2 80} // namespace V2_2
81} // namespace composer 81} // namespace composer
82} // namespace graphics 82} // namespace graphics
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 78322a11..77479009 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -14,37 +14,6 @@
14// limitations under the License. 14// limitations under the License.
15// 15//
16 16
17cc_library_static {
18 name: "libVtsHalGraphicsComposerTestUtils@2.2",
19 defaults: ["hidl_defaults"],
20 srcs: [
21 "VtsHalGraphicsComposerTestUtils.cpp",
22 ],
23 shared_libs: [
24 "android.hardware.graphics.composer@2.1",
25 "android.hardware.graphics.composer@2.2",
26 "libfmq",
27 "libsync",
28 ],
29 static_libs: [
30 "libVtsHalGraphicsComposerTestUtils",
31 "VtsHalHidlTargetTestBase",
32 ],
33 header_libs: [
34 "android.hardware.graphics.composer@2.1-command-buffer",
35 "android.hardware.graphics.composer@2.2-command-buffer",
36 ],
37 cflags: [
38 "-Wall",
39 "-Wextra",
40 "-Werror",
41 "-O0",
42 "-g",
43 "-DLOG_TAG=\"GraphicsComposerTestUtils@2.2\"",
44 ],
45 export_include_dirs: ["include"],
46}
47
48cc_test { 17cc_test {
49 name: "VtsHalGraphicsComposerV2_2TargetTest", 18 name: "VtsHalGraphicsComposerV2_2TargetTest",
50 defaults: ["VtsHalTargetTestDefaults"], 19 defaults: ["VtsHalTargetTestDefaults"],
@@ -58,14 +27,13 @@ cc_test {
58 ], 27 ],
59 static_libs: [ 28 static_libs: [
60 "android.hardware.graphics.allocator@2.0", 29 "android.hardware.graphics.allocator@2.0",
61 "android.hardware.graphics.composer@2.2",
62 "android.hardware.graphics.composer@2.1", 30 "android.hardware.graphics.composer@2.1",
31 "android.hardware.graphics.composer@2.1-vts",
32 "android.hardware.graphics.composer@2.2",
33 "android.hardware.graphics.composer@2.2-vts",
63 "android.hardware.graphics.mapper@2.0", 34 "android.hardware.graphics.mapper@2.0",
64 "android.hardware.graphics.mapper@2.0-vts", 35 "android.hardware.graphics.mapper@2.0-vts",
65 "android.hardware.graphics.mapper@2.1", 36 "android.hardware.graphics.mapper@2.1",
66 "libVtsHalGraphicsComposerTestUtils",
67 "libVtsHalGraphicsComposerTestUtils@2.2",
68 "libnativehelper",
69 ], 37 ],
70 header_libs: [ 38 header_libs: [
71 "android.hardware.graphics.composer@2.1-command-buffer", 39 "android.hardware.graphics.composer@2.1-command-buffer",
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 6fbdd3c8..c4943296 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -16,23 +16,20 @@
16 16
17#define LOG_TAG "graphics_composer_hidl_hal_test@2.2" 17#define LOG_TAG "graphics_composer_hidl_hal_test@2.2"
18 18
19#include <VtsHalHidlTargetTestBase.h>
19#include <android-base/logging.h> 20#include <android-base/logging.h>
20#include <android/hardware/graphics/mapper/2.1/IMapper.h> 21#include <android/hardware/graphics/mapper/2.1/IMapper.h>
22#include <composer-vts/2.1/GraphicsComposerCallback.h>
23#include <composer-vts/2.1/TestCommandReader.h>
24#include <composer-vts/2.2/ComposerVts.h>
21#include <mapper-vts/2.0/MapperVts.h> 25#include <mapper-vts/2.0/MapperVts.h>
22#include <sync/sync.h>
23#include "2.2/VtsHalGraphicsComposerTestUtils.h"
24#include "GraphicsComposerCallback.h"
25#include "TestCommandReader.h"
26#include "VtsHalGraphicsComposerTestUtils.h"
27
28#include <VtsHalHidlTargetTestBase.h>
29 26
30namespace android { 27namespace android {
31namespace hardware { 28namespace hardware {
32namespace graphics { 29namespace graphics {
33namespace composer { 30namespace composer {
34namespace V2_2 { 31namespace V2_2 {
35namespace tests { 32namespace vts {
36namespace { 33namespace {
37 34
38using android::hardware::graphics::common::V1_0::BufferUsage; 35using android::hardware::graphics::common::V1_0::BufferUsage;
@@ -71,7 +68,7 @@ class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
71 GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>())); 68 GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
72 ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient_v2_2()); 69 ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient_v2_2());
73 70
74 mComposerCallback = new V2_1::tests::GraphicsComposerCallback; 71 mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
75 mComposerClient->registerCallback(mComposerCallback); 72 mComposerClient->registerCallback(mComposerCallback);
76 73
77 // assume the first display is primary and is never removed 74 // assume the first display is primary and is never removed
@@ -95,7 +92,7 @@ class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
95 92
96 std::unique_ptr<Composer_v2_2> mComposer; 93 std::unique_ptr<Composer_v2_2> mComposer;
97 std::unique_ptr<ComposerClient_v2_2> mComposerClient; 94 std::unique_ptr<ComposerClient_v2_2> mComposerClient;
98 sp<V2_1::tests::GraphicsComposerCallback> mComposerCallback; 95 sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
99 // the first display and is assumed never to be removed 96 // the first display and is assumed never to be removed
100 Display mPrimaryDisplay; 97 Display mPrimaryDisplay;
101 98
@@ -122,7 +119,7 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
122 ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>()); 119 ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
123 120
124 mWriter = std::make_unique<V2_2::CommandWriterBase>(1024); 121 mWriter = std::make_unique<V2_2::CommandWriterBase>(1024);
125 mReader = std::make_unique<V2_1::tests::TestCommandReader>(); 122 mReader = std::make_unique<V2_1::vts::TestCommandReader>();
126 } 123 }
127 124
128 void TearDown() override { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); } 125 void TearDown() override { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); }
@@ -142,7 +139,7 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
142 void execute() { mComposerClient->execute_v2_2(mReader.get(), mWriter.get()); } 139 void execute() { mComposerClient->execute_v2_2(mReader.get(), mWriter.get()); }
143 140
144 std::unique_ptr<V2_2::CommandWriterBase> mWriter; 141 std::unique_ptr<V2_2::CommandWriterBase> mWriter;
145 std::unique_ptr<V2_1::tests::TestCommandReader> mReader; 142 std::unique_ptr<V2_1::vts::TestCommandReader> mReader;
146 143
147 private: 144 private:
148 std::unique_ptr<Gralloc> mGralloc; 145 std::unique_ptr<Gralloc> mGralloc;
@@ -239,7 +236,7 @@ TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_FLOAT_COLOR) {
239} 236}
240 237
241} // namespace 238} // namespace
242} // namespace tests 239} // namespace vts
243} // namespace V2_2 240} // namespace V2_2
244} // namespace composer 241} // namespace composer
245} // namespace graphics 242} // namespace graphics
@@ -247,7 +244,7 @@ TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_FLOAT_COLOR) {
247} // namespace android 244} // namespace android
248 245
249int main(int argc, char** argv) { 246int main(int argc, char** argv) {
250 using android::hardware::graphics::composer::V2_2::tests::GraphicsComposerHidlEnvironment; 247 using android::hardware::graphics::composer::V2_2::vts::GraphicsComposerHidlEnvironment;
251 ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance()); 248 ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance());
252 ::testing::InitGoogleTest(&argc, argv); 249 ::testing::InitGoogleTest(&argc, argv);
253 GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv); 250 GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv);
diff --git a/neuralnetworks/1.1/types.hal b/neuralnetworks/1.1/types.hal
index 18863d3e..fae5dd0c 100644
--- a/neuralnetworks/1.1/types.hal
+++ b/neuralnetworks/1.1/types.hal
@@ -330,4 +330,12 @@ struct Model {
330 * equals OperandLifeTime::CONSTANT_REFERENCE. 330 * equals OperandLifeTime::CONSTANT_REFERENCE.
331 */ 331 */
332 vec<memory> pools; 332 vec<memory> pools;
333
334 /**
335 * 'true' indicates TENSOR_FLOAT32 may be calculated with range and/or
336 * precision as low as that of the IEEE 754 16-bit floating-point format.
337 * 'false' indicates TENSOR_FLOAT32 must be calculated using at least the
338 * range and precision of the IEEE 754 32-bit floating-point format.
339 */
340 bool relaxComputationFloat32toFloat16;
333}; 341};