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