blob: f898adad95f62a6937843914fd52dcce95d56b09 [file] [log] [blame]
Dan Stoza651bf312015-10-23 17:03:17 -07001/*
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// #define LOG_NDEBUG 0
18
19#undef LOG_TAG
20#define LOG_TAG "HWC2"
21#define ATRACE_TAG ATRACE_TAG_GRAPHICS
22
23#include "HWC2.h"
24
25#include "FloatRect.h"
26
27#include <ui/Fence.h>
28#include <ui/GraphicBuffer.h>
29#include <ui/Region.h>
30
31#include <android/configuration.h>
32
Dan Stoza09e7a272016-04-14 12:31:01 -070033#include <algorithm>
Dan Stoza651bf312015-10-23 17:03:17 -070034#include <inttypes.h>
35
36extern "C" {
37 static void hotplug_hook(hwc2_callback_data_t callbackData,
38 hwc2_display_t displayId, int32_t intConnected) {
39 auto device = static_cast<HWC2::Device*>(callbackData);
40 auto display = device->getDisplayById(displayId);
41 if (display) {
42 auto connected = static_cast<HWC2::Connection>(intConnected);
43 device->callHotplug(std::move(display), connected);
44 } else {
45 ALOGE("Hotplug callback called with unknown display %" PRIu64,
46 displayId);
47 }
48 }
49
50 static void refresh_hook(hwc2_callback_data_t callbackData,
51 hwc2_display_t displayId) {
52 auto device = static_cast<HWC2::Device*>(callbackData);
53 auto display = device->getDisplayById(displayId);
54 if (display) {
55 device->callRefresh(std::move(display));
56 } else {
57 ALOGE("Refresh callback called with unknown display %" PRIu64,
58 displayId);
59 }
60 }
61
62 static void vsync_hook(hwc2_callback_data_t callbackData,
63 hwc2_display_t displayId, int64_t timestamp) {
64 auto device = static_cast<HWC2::Device*>(callbackData);
65 auto display = device->getDisplayById(displayId);
66 if (display) {
67 device->callVsync(std::move(display), timestamp);
68 } else {
69 ALOGE("Vsync callback called with unknown display %" PRIu64,
70 displayId);
71 }
72 }
73}
74
75using android::Fence;
76using android::FloatRect;
77using android::GraphicBuffer;
Dan Stoza7d7ae732016-03-16 12:23:40 -070078using android::HdrCapabilities;
Dan Stoza651bf312015-10-23 17:03:17 -070079using android::Rect;
80using android::Region;
81using android::sp;
82
83namespace HWC2 {
84
85// Device methods
86
87Device::Device(hwc2_device_t* device)
88 : mHwcDevice(device),
89 mCreateVirtualDisplay(nullptr),
90 mDestroyVirtualDisplay(nullptr),
91 mDump(nullptr),
92 mGetMaxVirtualDisplayCount(nullptr),
93 mRegisterCallback(nullptr),
94 mAcceptDisplayChanges(nullptr),
95 mCreateLayer(nullptr),
96 mDestroyLayer(nullptr),
97 mGetActiveConfig(nullptr),
98 mGetChangedCompositionTypes(nullptr),
Dan Stoza076ac672016-03-14 10:47:53 -070099 mGetColorModes(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700100 mGetDisplayAttribute(nullptr),
101 mGetDisplayConfigs(nullptr),
102 mGetDisplayName(nullptr),
103 mGetDisplayRequests(nullptr),
104 mGetDisplayType(nullptr),
105 mGetDozeSupport(nullptr),
Dan Stoza7d7ae732016-03-16 12:23:40 -0700106 mGetHdrCapabilities(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700107 mGetReleaseFences(nullptr),
108 mPresentDisplay(nullptr),
109 mSetActiveConfig(nullptr),
110 mSetClientTarget(nullptr),
Dan Stoza076ac672016-03-14 10:47:53 -0700111 mSetColorMode(nullptr),
Dan Stoza5df2a862016-03-24 16:19:37 -0700112 mSetColorTransform(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700113 mSetOutputBuffer(nullptr),
114 mSetPowerMode(nullptr),
115 mSetVsyncEnabled(nullptr),
116 mValidateDisplay(nullptr),
117 mSetCursorPosition(nullptr),
118 mSetLayerBuffer(nullptr),
119 mSetLayerSurfaceDamage(nullptr),
120 mSetLayerBlendMode(nullptr),
121 mSetLayerColor(nullptr),
122 mSetLayerCompositionType(nullptr),
Dan Stoza5df2a862016-03-24 16:19:37 -0700123 mSetLayerDataspace(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700124 mSetLayerDisplayFrame(nullptr),
125 mSetLayerPlaneAlpha(nullptr),
126 mSetLayerSidebandStream(nullptr),
127 mSetLayerSourceCrop(nullptr),
128 mSetLayerTransform(nullptr),
129 mSetLayerVisibleRegion(nullptr),
130 mSetLayerZOrder(nullptr),
131 mCapabilities(),
132 mDisplays(),
133 mHotplug(),
134 mPendingHotplugs(),
135 mRefresh(),
136 mPendingRefreshes(),
137 mVsync(),
138 mPendingVsyncs()
139{
140 loadCapabilities();
141 loadFunctionPointers();
142 registerCallbacks();
143}
144
145Device::~Device()
146{
147 if (mHwcDevice == nullptr) {
148 return;
149 }
150
151 for (auto element : mDisplays) {
152 auto display = element.second;
153
154 DisplayType displayType = HWC2::DisplayType::Invalid;
155 auto error = display->getType(&displayType);
156 if (error != Error::None) {
157 ALOGE("~Device: Failed to determine type of display %" PRIu64
158 ": %s (%d)", display->getId(), to_string(error).c_str(),
159 static_cast<int32_t>(error));
160 continue;
161 }
162
163 if (displayType == HWC2::DisplayType::Physical) {
164 error = display->setVsyncEnabled(HWC2::Vsync::Disable);
165 if (error != Error::None) {
166 ALOGE("~Device: Failed to disable vsync for display %" PRIu64
167 ": %s (%d)", display->getId(), to_string(error).c_str(),
168 static_cast<int32_t>(error));
169 }
170 }
171 }
172
173 hwc2_close(mHwcDevice);
174}
175
176// Required by HWC2 device
177
178std::string Device::dump() const
179{
180 uint32_t numBytes = 0;
181 mDump(mHwcDevice, &numBytes, nullptr);
182
183 std::vector<char> buffer(numBytes);
184 mDump(mHwcDevice, &numBytes, buffer.data());
185
186 return std::string(buffer.data(), buffer.size());
187}
188
189uint32_t Device::getMaxVirtualDisplayCount() const
190{
191 return mGetMaxVirtualDisplayCount(mHwcDevice);
192}
193
194Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
195 std::shared_ptr<Display>* outDisplay)
196{
197 ALOGI("Creating virtual display");
198
199 hwc2_display_t displayId = 0;
200 int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height,
201 &displayId);
202 auto error = static_cast<Error>(intError);
203 if (error != Error::None) {
204 return error;
205 }
206
207 ALOGI("Created virtual display");
208 *outDisplay = getDisplayById(displayId);
209 (*outDisplay)->setVirtual();
210 return Error::None;
211}
212
213void Device::registerHotplugCallback(HotplugCallback hotplug)
214{
215 ALOGV("registerHotplugCallback");
216 mHotplug = hotplug;
217 for (auto& pending : mPendingHotplugs) {
218 auto& display = pending.first;
219 auto connected = pending.second;
220 ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(),
221 to_string(connected).c_str());
222 mHotplug(std::move(display), connected);
223 }
224}
225
226void Device::registerRefreshCallback(RefreshCallback refresh)
227{
228 mRefresh = refresh;
229 for (auto& pending : mPendingRefreshes) {
230 mRefresh(std::move(pending));
231 }
232}
233
234void Device::registerVsyncCallback(VsyncCallback vsync)
235{
236 mVsync = vsync;
237 for (auto& pending : mPendingVsyncs) {
238 auto& display = pending.first;
239 auto timestamp = pending.second;
240 mVsync(std::move(display), timestamp);
241 }
242}
243
244// For use by Device callbacks
245
246void Device::callHotplug(std::shared_ptr<Display> display, Connection connected)
247{
248 if (connected == Connection::Connected) {
249 if (!display->isConnected()) {
250 display->loadConfigs();
251 display->setConnected(true);
252 }
253 } else {
254 display->setConnected(false);
255 mDisplays.erase(display->getId());
256 }
257
258 if (mHotplug) {
259 mHotplug(std::move(display), connected);
260 } else {
261 ALOGV("callHotplug called, but no valid callback registered, storing");
262 mPendingHotplugs.emplace_back(std::move(display), connected);
263 }
264}
265
266void Device::callRefresh(std::shared_ptr<Display> display)
267{
268 if (mRefresh) {
269 mRefresh(std::move(display));
270 } else {
271 ALOGV("callRefresh called, but no valid callback registered, storing");
272 mPendingRefreshes.emplace_back(std::move(display));
273 }
274}
275
276void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp)
277{
278 if (mVsync) {
279 mVsync(std::move(display), timestamp);
280 } else {
281 ALOGV("callVsync called, but no valid callback registered, storing");
282 mPendingVsyncs.emplace_back(std::move(display), timestamp);
283 }
284}
285
286// Other Device methods
287
288std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
289 if (mDisplays.count(id) != 0) {
290 return mDisplays.at(id);
291 }
292
293 auto display = std::make_shared<Display>(*this, id);
294 mDisplays.emplace(id, display);
295 return display;
296}
297
298// Device initialization methods
299
300void Device::loadCapabilities()
301{
302 static_assert(sizeof(Capability) == sizeof(int32_t),
303 "Capability size has changed");
304 uint32_t numCapabilities = 0;
305 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr);
306 mCapabilities.resize(numCapabilities);
307 auto asInt = reinterpret_cast<int32_t*>(mCapabilities.data());
308 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt);
309}
310
Dan Stoza09e7a272016-04-14 12:31:01 -0700311bool Device::hasCapability(HWC2::Capability capability) const
312{
313 return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
314 capability) != mCapabilities.cend();
315}
316
Dan Stoza651bf312015-10-23 17:03:17 -0700317void Device::loadFunctionPointers()
318{
319 // For all of these early returns, we log an error message inside
320 // loadFunctionPointer specifying which function failed to load
321
322 // Display function pointers
Dan Stoza7d7ae732016-03-16 12:23:40 -0700323 if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700324 mCreateVirtualDisplay)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700325 if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700326 mDestroyVirtualDisplay)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700327 if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return;
328 if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount,
Dan Stoza651bf312015-10-23 17:03:17 -0700329 mGetMaxVirtualDisplayCount)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700330 if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback,
Dan Stoza651bf312015-10-23 17:03:17 -0700331 mRegisterCallback)) return;
332
333 // Device function pointers
Dan Stoza7d7ae732016-03-16 12:23:40 -0700334 if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges,
Dan Stoza651bf312015-10-23 17:03:17 -0700335 mAcceptDisplayChanges)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700336 if (!loadFunctionPointer(FunctionDescriptor::CreateLayer,
Dan Stoza651bf312015-10-23 17:03:17 -0700337 mCreateLayer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700338 if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer,
Dan Stoza651bf312015-10-23 17:03:17 -0700339 mDestroyLayer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700340 if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig,
Dan Stoza651bf312015-10-23 17:03:17 -0700341 mGetActiveConfig)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700342 if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes,
Dan Stoza651bf312015-10-23 17:03:17 -0700343 mGetChangedCompositionTypes)) return;
Dan Stoza076ac672016-03-14 10:47:53 -0700344 if (!loadFunctionPointer(FunctionDescriptor::GetColorModes,
345 mGetColorModes)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700346 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute,
Dan Stoza651bf312015-10-23 17:03:17 -0700347 mGetDisplayAttribute)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700348 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs,
Dan Stoza651bf312015-10-23 17:03:17 -0700349 mGetDisplayConfigs)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700350 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName,
Dan Stoza651bf312015-10-23 17:03:17 -0700351 mGetDisplayName)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700352 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests,
Dan Stoza651bf312015-10-23 17:03:17 -0700353 mGetDisplayRequests)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700354 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType,
Dan Stoza651bf312015-10-23 17:03:17 -0700355 mGetDisplayType)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700356 if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport,
Dan Stoza651bf312015-10-23 17:03:17 -0700357 mGetDozeSupport)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700358 if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities,
359 mGetHdrCapabilities)) return;
360 if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences,
Dan Stoza651bf312015-10-23 17:03:17 -0700361 mGetReleaseFences)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700362 if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700363 mPresentDisplay)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700364 if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig,
Dan Stoza651bf312015-10-23 17:03:17 -0700365 mSetActiveConfig)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700366 if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget,
Dan Stoza651bf312015-10-23 17:03:17 -0700367 mSetClientTarget)) return;
Dan Stoza076ac672016-03-14 10:47:53 -0700368 if (!loadFunctionPointer(FunctionDescriptor::SetColorMode,
369 mSetColorMode)) return;
Dan Stoza5df2a862016-03-24 16:19:37 -0700370 if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform,
371 mSetColorTransform)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700372 if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer,
Dan Stoza651bf312015-10-23 17:03:17 -0700373 mSetOutputBuffer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700374 if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode,
Dan Stoza651bf312015-10-23 17:03:17 -0700375 mSetPowerMode)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700376 if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled,
Dan Stoza651bf312015-10-23 17:03:17 -0700377 mSetVsyncEnabled)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700378 if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700379 mValidateDisplay)) return;
380
381 // Layer function pointers
Dan Stoza7d7ae732016-03-16 12:23:40 -0700382 if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition,
Dan Stoza651bf312015-10-23 17:03:17 -0700383 mSetCursorPosition)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700384 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer,
Dan Stoza651bf312015-10-23 17:03:17 -0700385 mSetLayerBuffer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700386 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage,
Dan Stoza651bf312015-10-23 17:03:17 -0700387 mSetLayerSurfaceDamage)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700388 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode,
Dan Stoza651bf312015-10-23 17:03:17 -0700389 mSetLayerBlendMode)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700390 if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor,
Dan Stoza651bf312015-10-23 17:03:17 -0700391 mSetLayerColor)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700392 if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType,
Dan Stoza651bf312015-10-23 17:03:17 -0700393 mSetLayerCompositionType)) return;
Dan Stoza5df2a862016-03-24 16:19:37 -0700394 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace,
395 mSetLayerDataspace)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700396 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame,
Dan Stoza651bf312015-10-23 17:03:17 -0700397 mSetLayerDisplayFrame)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700398 if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
Dan Stoza651bf312015-10-23 17:03:17 -0700399 mSetLayerPlaneAlpha)) return;
Dan Stoza09e7a272016-04-14 12:31:01 -0700400 if (hasCapability(Capability::SidebandStream)) {
401 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
402 mSetLayerSidebandStream)) return;
403 }
Dan Stoza7d7ae732016-03-16 12:23:40 -0700404 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
Dan Stoza651bf312015-10-23 17:03:17 -0700405 mSetLayerSourceCrop)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700406 if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
Dan Stoza651bf312015-10-23 17:03:17 -0700407 mSetLayerTransform)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700408 if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion,
Dan Stoza651bf312015-10-23 17:03:17 -0700409 mSetLayerVisibleRegion)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700410 if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder,
Dan Stoza651bf312015-10-23 17:03:17 -0700411 mSetLayerZOrder)) return;
412}
413
414void Device::registerCallbacks()
415{
416 registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook);
417 registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook);
418 registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook);
419}
420
421
422// For use by Display
423
424void Device::destroyVirtualDisplay(hwc2_display_t display)
425{
426 ALOGI("Destroying virtual display");
427 int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display);
428 auto error = static_cast<Error>(intError);
429 ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
430 " %s (%d)", display, to_string(error).c_str(), intError);
431}
432
433// Display methods
434
435Display::Display(Device& device, hwc2_display_t id)
436 : mDevice(device),
437 mId(id),
438 mIsConnected(false),
439 mIsVirtual(false)
440{
441 ALOGV("Created display %" PRIu64, id);
442}
443
444Display::~Display()
445{
446 ALOGV("Destroyed display %" PRIu64, mId);
447 if (mIsVirtual) {
448 mDevice.destroyVirtualDisplay(mId);
449 }
450}
451
452Display::Config::Config(Display& display, hwc2_config_t id)
453 : mDisplay(display),
454 mId(id),
455 mWidth(-1),
456 mHeight(-1),
457 mVsyncPeriod(-1),
458 mDpiX(-1),
459 mDpiY(-1) {}
460
461Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
462 : mConfig(new Config(display, id)) {}
463
464float Display::Config::Builder::getDefaultDensity() {
465 // Default density is based on TVs: 1080p displays get XHIGH density, lower-
466 // resolution displays get TV density. Maybe eventually we'll need to update
467 // it for 4k displays, though hopefully those will just report accurate DPI
468 // information to begin with. This is also used for virtual displays and
469 // older HWC implementations, so be careful about orientation.
470
471 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
472 if (longDimension >= 1080) {
473 return ACONFIGURATION_DENSITY_XHIGH;
474 } else {
475 return ACONFIGURATION_DENSITY_TV;
476 }
477}
478
479// Required by HWC2 display
480
481Error Display::acceptChanges()
482{
483 int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
484 return static_cast<Error>(intError);
485}
486
487Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
488{
489 hwc2_layer_t layerId = 0;
490 int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId);
491 auto error = static_cast<Error>(intError);
492 if (error != Error::None) {
493 return error;
494 }
495
496 auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
497 mLayers.emplace(layerId, layer);
498 *outLayer = std::move(layer);
499 return Error::None;
500}
501
502Error Display::getActiveConfig(
503 std::shared_ptr<const Display::Config>* outConfig) const
504{
505 ALOGV("[%" PRIu64 "] getActiveConfig", mId);
506 hwc2_config_t configId = 0;
507 int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId,
508 &configId);
509 auto error = static_cast<Error>(intError);
510
511 if (error != Error::None) {
512 return error;
513 }
514
515 if (mConfigs.count(configId) != 0) {
516 *outConfig = mConfigs.at(configId);
517 } else {
518 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
519 configId);
520 // Return no error, but the caller needs to check for a null pointer to
521 // detect this case
522 *outConfig = nullptr;
523 }
524
525 return Error::None;
526}
527
528Error Display::getChangedCompositionTypes(
529 std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
530{
531 uint32_t numElements = 0;
532 int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice,
533 mId, &numElements, nullptr, nullptr);
534 auto error = static_cast<Error>(intError);
535 if (error != Error::None) {
536 return error;
537 }
538
539 std::vector<hwc2_layer_t> layerIds(numElements);
540 std::vector<int32_t> types(numElements);
541 intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId,
542 &numElements, layerIds.data(), types.data());
543 error = static_cast<Error>(intError);
544 if (error != Error::None) {
545 return error;
546 }
547
548 outTypes->clear();
549 outTypes->reserve(numElements);
550 for (uint32_t element = 0; element < numElements; ++element) {
551 auto layer = getLayerById(layerIds[element]);
552 if (layer) {
553 auto type = static_cast<Composition>(types[element]);
554 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
555 layer->getId(), to_string(type).c_str());
556 outTypes->emplace(layer, type);
557 } else {
558 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
559 " on display %" PRIu64, layerIds[element], mId);
560 }
561 }
562
563 return Error::None;
564}
565
Dan Stoza076ac672016-03-14 10:47:53 -0700566Error Display::getColorModes(std::vector<int32_t>* outModes) const
567{
568 uint32_t numModes = 0;
569 int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
570 &numModes, nullptr);
571 auto error = static_cast<Error>(intError);
572 if (error != Error::None) {
573 return error;
574 }
575
576 std::vector<int32_t> modes(numModes);
577 intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes,
578 modes.data());
579 error = static_cast<Error>(intError);
580 if (error != Error::None) {
581 return error;
582 }
583
584 std::swap(*outModes, modes);
585 return Error::None;
586}
587
Dan Stoza651bf312015-10-23 17:03:17 -0700588std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
589{
590 std::vector<std::shared_ptr<const Config>> configs;
591 for (const auto& element : mConfigs) {
592 configs.emplace_back(element.second);
593 }
594 return configs;
595}
596
597Error Display::getName(std::string* outName) const
598{
599 uint32_t size;
600 int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
601 nullptr);
602 auto error = static_cast<Error>(intError);
603 if (error != Error::None) {
604 return error;
605 }
606
607 std::vector<char> rawName(size);
608 intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
609 rawName.data());
610 error = static_cast<Error>(intError);
611 if (error != Error::None) {
612 return error;
613 }
614
615 *outName = std::string(rawName.cbegin(), rawName.cend());
616 return Error::None;
617}
618
619Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
620 std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
621 outLayerRequests)
622{
623 int32_t intDisplayRequests = 0;
624 uint32_t numElements = 0;
625 int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
626 &intDisplayRequests, &numElements, nullptr, nullptr);
627 auto error = static_cast<Error>(intError);
628 if (error != Error::None) {
629 return error;
630 }
631
632 std::vector<hwc2_layer_t> layerIds(numElements);
633 std::vector<int32_t> layerRequests(numElements);
634 intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
635 &intDisplayRequests, &numElements, layerIds.data(),
636 layerRequests.data());
637 error = static_cast<Error>(intError);
638 if (error != Error::None) {
639 return error;
640 }
641
642 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
643 outLayerRequests->clear();
644 outLayerRequests->reserve(numElements);
645 for (uint32_t element = 0; element < numElements; ++element) {
646 auto layer = getLayerById(layerIds[element]);
647 if (layer) {
648 auto layerRequest =
649 static_cast<LayerRequest>(layerRequests[element]);
650 outLayerRequests->emplace(layer, layerRequest);
651 } else {
652 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
653 PRIu64, layerIds[element], mId);
654 }
655 }
656
657 return Error::None;
658}
659
660Error Display::getType(DisplayType* outType) const
661{
662 int32_t intType = 0;
663 int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
664 &intType);
665 auto error = static_cast<Error>(intError);
666 if (error != Error::None) {
667 return error;
668 }
669
670 *outType = static_cast<DisplayType>(intType);
671 return Error::None;
672}
673
674Error Display::supportsDoze(bool* outSupport) const
675{
676 int32_t intSupport = 0;
677 int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId,
678 &intSupport);
679 auto error = static_cast<Error>(intError);
680 if (error != Error::None) {
681 return error;
682 }
683 *outSupport = static_cast<bool>(intSupport);
684 return Error::None;
685}
686
Dan Stoza7d7ae732016-03-16 12:23:40 -0700687Error Display::getHdrCapabilities(
688 std::unique_ptr<HdrCapabilities>* outCapabilities) const
689{
690 uint32_t numTypes = 0;
691 float maxLuminance = -1.0f;
692 float maxAverageLuminance = -1.0f;
693 float minLuminance = -1.0f;
694 int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId,
695 &numTypes, nullptr, &maxLuminance, &maxAverageLuminance,
696 &minLuminance);
697 auto error = static_cast<HWC2::Error>(intError);
698 if (error != Error::None) {
699 return error;
700 }
701
702 std::vector<int32_t> types(numTypes);
703 intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes,
704 types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance);
705 error = static_cast<HWC2::Error>(intError);
706 if (error != Error::None) {
707 return error;
708 }
709
710 *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
711 maxLuminance, maxAverageLuminance, minLuminance);
712 return Error::None;
713}
714
Dan Stoza651bf312015-10-23 17:03:17 -0700715Error Display::getReleaseFences(
716 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
717{
718 uint32_t numElements = 0;
719 int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId,
720 &numElements, nullptr, nullptr);
721 auto error = static_cast<Error>(intError);
722 if (error != Error::None) {
723 return error;
724 }
725
726 std::vector<hwc2_layer_t> layerIds(numElements);
727 std::vector<int32_t> fenceFds(numElements);
728 intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements,
729 layerIds.data(), fenceFds.data());
730 error = static_cast<Error>(intError);
731 if (error != Error::None) {
732 return error;
733 }
734
735 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
736 releaseFences.reserve(numElements);
737 for (uint32_t element = 0; element < numElements; ++element) {
738 auto layer = getLayerById(layerIds[element]);
739 if (layer) {
740 sp<Fence> fence(new Fence(fenceFds[element]));
741 releaseFences.emplace(std::move(layer), fence);
742 } else {
743 ALOGE("getReleaseFences: invalid layer %" PRIu64
744 " found on display %" PRIu64, layerIds[element], mId);
745 return Error::BadLayer;
746 }
747 }
748
749 *outFences = std::move(releaseFences);
750 return Error::None;
751}
752
753Error Display::present(sp<Fence>* outRetireFence)
754{
755 int32_t retireFenceFd = 0;
756 int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId,
757 &retireFenceFd);
758 auto error = static_cast<Error>(intError);
759 if (error != Error::None) {
760 return error;
761 }
762
763 *outRetireFence = new Fence(retireFenceFd);
764 return Error::None;
765}
766
767Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
768{
769 if (config->getDisplayId() != mId) {
770 ALOGE("setActiveConfig received config %u for the wrong display %"
771 PRIu64 " (expected %" PRIu64 ")", config->getId(),
772 config->getDisplayId(), mId);
773 return Error::BadConfig;
774 }
775 int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId,
776 config->getId());
777 return static_cast<Error>(intError);
778}
779
780Error Display::setClientTarget(buffer_handle_t target,
781 const sp<Fence>& acquireFence, android_dataspace_t dataspace)
782{
783 int32_t fenceFd = acquireFence->dup();
784 int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
785 fenceFd, static_cast<int32_t>(dataspace));
786 return static_cast<Error>(intError);
787}
788
Dan Stoza076ac672016-03-14 10:47:53 -0700789Error Display::setColorMode(int32_t mode)
790{
791 int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
792 return static_cast<Error>(intError);
793}
794
Dan Stoza5df2a862016-03-24 16:19:37 -0700795Error Display::setColorTransform(const android::mat4& matrix,
796 android_color_transform_t hint)
797{
798 int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
799 matrix.asArray(), static_cast<int32_t>(hint));
800 return static_cast<Error>(intError);
801}
802
Dan Stoza651bf312015-10-23 17:03:17 -0700803Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
804 const sp<Fence>& releaseFence)
805{
806 int32_t fenceFd = releaseFence->dup();
807 auto handle = buffer->getNativeBuffer()->handle;
808 int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
809 fenceFd);
810 return static_cast<Error>(intError);
811}
812
813Error Display::setPowerMode(PowerMode mode)
814{
815 auto intMode = static_cast<int32_t>(mode);
816 int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode);
817 return static_cast<Error>(intError);
818}
819
820Error Display::setVsyncEnabled(Vsync enabled)
821{
822 auto intEnabled = static_cast<int32_t>(enabled);
823 int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId,
824 intEnabled);
825 return static_cast<Error>(intError);
826}
827
828Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
829{
830 uint32_t numTypes = 0;
831 uint32_t numRequests = 0;
832 int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId,
833 &numTypes, &numRequests);
834 auto error = static_cast<Error>(intError);
835 if (error != Error::None && error != Error::HasChanges) {
836 return error;
837 }
838
839 *outNumTypes = numTypes;
840 *outNumRequests = numRequests;
841 return error;
842}
843
844// For use by Device
845
846int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
847{
848 int32_t value = 0;
849 int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId,
850 configId, static_cast<int32_t>(attribute), &value);
851 auto error = static_cast<Error>(intError);
852 if (error != Error::None) {
853 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
854 configId, to_string(attribute).c_str(),
855 to_string(error).c_str(), intError);
856 return -1;
857 }
858 return value;
859}
860
861void Display::loadConfig(hwc2_config_t configId)
862{
863 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
864
865 auto config = Config::Builder(*this, configId)
866 .setWidth(getAttribute(configId, Attribute::Width))
867 .setHeight(getAttribute(configId, Attribute::Height))
868 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
869 .setDpiX(getAttribute(configId, Attribute::DpiX))
870 .setDpiY(getAttribute(configId, Attribute::DpiY))
871 .build();
872 mConfigs.emplace(configId, std::move(config));
873}
874
875void Display::loadConfigs()
876{
877 ALOGV("[%" PRIu64 "] loadConfigs", mId);
878
879 uint32_t numConfigs = 0;
880 int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId,
881 &numConfigs, nullptr);
882 auto error = static_cast<Error>(intError);
883 if (error != Error::None) {
884 ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId,
885 to_string(error).c_str(), intError);
886 return;
887 }
888
889 std::vector<hwc2_config_t> configIds(numConfigs);
890 intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs,
891 configIds.data());
892 error = static_cast<Error>(intError);
893 if (error != Error::None) {
894 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
895 to_string(error).c_str(), intError);
896 return;
897 }
898
899 for (auto configId : configIds) {
900 loadConfig(configId);
901 }
902}
903
904// For use by Layer
905
906void Display::destroyLayer(hwc2_layer_t layerId)
907{
908 int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId);
909 auto error = static_cast<Error>(intError);
910 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
911 " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
912 intError);
913 mLayers.erase(layerId);
914}
915
916// Other Display methods
917
918std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
919{
920 if (mLayers.count(id) == 0) {
921 return nullptr;
922 }
923
924 auto layer = mLayers.at(id).lock();
925 return layer;
926}
927
928// Layer methods
929
930Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
931 : mDisplay(display),
932 mDisplayId(display->getId()),
933 mDevice(display->getDevice()),
934 mId(id)
935{
936 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
937 display->getId());
938}
939
940Layer::~Layer()
941{
942 auto display = mDisplay.lock();
943 if (display) {
944 display->destroyLayer(mId);
945 }
946}
947
948Error Layer::setCursorPosition(int32_t x, int32_t y)
949{
950 int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice,
951 mDisplayId, mId, x, y);
952 return static_cast<Error>(intError);
953}
954
955Error Layer::setBuffer(buffer_handle_t buffer,
956 const sp<Fence>& acquireFence)
957{
958 int32_t fenceFd = acquireFence->dup();
959 int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
960 mId, buffer, fenceFd);
961 return static_cast<Error>(intError);
962}
963
964Error Layer::setSurfaceDamage(const Region& damage)
965{
966 // We encode default full-screen damage as INVALID_RECT upstream, but as 0
967 // rects for HWC
968 int32_t intError = 0;
969 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
970 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
971 mDisplayId, mId, {0, nullptr});
972 } else {
973 size_t rectCount = 0;
974 auto rectArray = damage.getArray(&rectCount);
975
976 std::vector<hwc_rect_t> hwcRects;
977 for (size_t rect = 0; rect < rectCount; ++rect) {
978 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
979 rectArray[rect].right, rectArray[rect].bottom});
980 }
981
982 hwc_region_t hwcRegion = {};
983 hwcRegion.numRects = rectCount;
984 hwcRegion.rects = hwcRects.data();
985
986 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
987 mDisplayId, mId, hwcRegion);
988 }
989
990 return static_cast<Error>(intError);
991}
992
993Error Layer::setBlendMode(BlendMode mode)
994{
995 auto intMode = static_cast<int32_t>(mode);
996 int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice,
997 mDisplayId, mId, intMode);
998 return static_cast<Error>(intError);
999}
1000
1001Error Layer::setColor(hwc_color_t color)
1002{
1003 int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId,
1004 mId, color);
1005 return static_cast<Error>(intError);
1006}
1007
1008Error Layer::setCompositionType(Composition type)
1009{
1010 auto intType = static_cast<int32_t>(type);
1011 int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice,
1012 mDisplayId, mId, intType);
1013 return static_cast<Error>(intError);
1014}
1015
Dan Stoza5df2a862016-03-24 16:19:37 -07001016Error Layer::setDataspace(android_dataspace_t dataspace)
1017{
1018 auto intDataspace = static_cast<int32_t>(dataspace);
1019 int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
1020 mDisplayId, mId, intDataspace);
1021 return static_cast<Error>(intError);
1022}
1023
Dan Stoza651bf312015-10-23 17:03:17 -07001024Error Layer::setDisplayFrame(const Rect& frame)
1025{
1026 hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
1027 int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice,
1028 mDisplayId, mId, hwcRect);
1029 return static_cast<Error>(intError);
1030}
1031
1032Error Layer::setPlaneAlpha(float alpha)
1033{
1034 int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice,
1035 mDisplayId, mId, alpha);
1036 return static_cast<Error>(intError);
1037}
1038
1039Error Layer::setSidebandStream(const native_handle_t* stream)
1040{
Dan Stoza09e7a272016-04-14 12:31:01 -07001041 if (!mDevice.hasCapability(Capability::SidebandStream)) {
1042 ALOGE("Attempted to call setSidebandStream without checking that the "
1043 "device supports sideband streams");
1044 return Error::Unsupported;
1045 }
Dan Stoza651bf312015-10-23 17:03:17 -07001046 int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
1047 mDisplayId, mId, stream);
1048 return static_cast<Error>(intError);
1049}
1050
1051Error Layer::setSourceCrop(const FloatRect& crop)
1052{
1053 hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom};
1054 int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice,
1055 mDisplayId, mId, hwcRect);
1056 return static_cast<Error>(intError);
1057}
1058
1059Error Layer::setTransform(Transform transform)
1060{
1061 auto intTransform = static_cast<int32_t>(transform);
1062 int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice,
1063 mDisplayId, mId, intTransform);
1064 return static_cast<Error>(intError);
1065}
1066
1067Error Layer::setVisibleRegion(const Region& region)
1068{
1069 size_t rectCount = 0;
1070 auto rectArray = region.getArray(&rectCount);
1071
1072 std::vector<hwc_rect_t> hwcRects;
1073 for (size_t rect = 0; rect < rectCount; ++rect) {
1074 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1075 rectArray[rect].right, rectArray[rect].bottom});
1076 }
1077
1078 hwc_region_t hwcRegion = {};
1079 hwcRegion.numRects = rectCount;
1080 hwcRegion.rects = hwcRects.data();
1081
1082 int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice,
1083 mDisplayId, mId, hwcRegion);
1084 return static_cast<Error>(intError);
1085}
1086
1087Error Layer::setZOrder(uint32_t z)
1088{
1089 int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId,
1090 mId, z);
1091 return static_cast<Error>(intError);
1092}
1093
1094} // namespace HWC2