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