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