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