• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 <algorithm>
34 #include <inttypes.h>
35 
36 extern "C" {
hotplug_hook(hwc2_callback_data_t callbackData,hwc2_display_t displayId,int32_t intConnected)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 
refresh_hook(hwc2_callback_data_t callbackData,hwc2_display_t displayId)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 
vsync_hook(hwc2_callback_data_t callbackData,hwc2_display_t displayId,int64_t timestamp)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 
75 using android::Fence;
76 using android::FloatRect;
77 using android::GraphicBuffer;
78 using android::HdrCapabilities;
79 using android::Rect;
80 using android::Region;
81 using android::sp;
82 
83 namespace HWC2 {
84 
85 // Device methods
86 
Device(hwc2_device_t * device)87 Device::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     mGetColorModes(nullptr),
100     mGetDisplayAttribute(nullptr),
101     mGetDisplayConfigs(nullptr),
102     mGetDisplayName(nullptr),
103     mGetDisplayRequests(nullptr),
104     mGetDisplayType(nullptr),
105     mGetDozeSupport(nullptr),
106     mGetHdrCapabilities(nullptr),
107     mGetReleaseFences(nullptr),
108     mPresentDisplay(nullptr),
109     mSetActiveConfig(nullptr),
110     mSetClientTarget(nullptr),
111     mSetColorMode(nullptr),
112     mSetColorTransform(nullptr),
113     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),
123     mSetLayerDataspace(nullptr),
124     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 
~Device()145 Device::~Device()
146 {
147     if (mHwcDevice == nullptr) {
148         return;
149     }
150 
151     for (auto element : mDisplays) {
152         auto display = element.second.lock();
153         if (!display) {
154             ALOGE("~Device: Found a display (%" PRId64 " that has already been"
155                     " destroyed", element.first);
156             continue;
157         }
158 
159         DisplayType displayType = HWC2::DisplayType::Invalid;
160         auto error = display->getType(&displayType);
161         if (error != Error::None) {
162             ALOGE("~Device: Failed to determine type of display %" PRIu64
163                     ": %s (%d)", display->getId(), to_string(error).c_str(),
164                     static_cast<int32_t>(error));
165             continue;
166         }
167 
168         if (displayType == HWC2::DisplayType::Physical) {
169             error = display->setVsyncEnabled(HWC2::Vsync::Disable);
170             if (error != Error::None) {
171                 ALOGE("~Device: Failed to disable vsync for display %" PRIu64
172                         ": %s (%d)", display->getId(), to_string(error).c_str(),
173                         static_cast<int32_t>(error));
174             }
175         }
176     }
177 
178     hwc2_close(mHwcDevice);
179 }
180 
181 // Required by HWC2 device
182 
dump() const183 std::string Device::dump() const
184 {
185     uint32_t numBytes = 0;
186     mDump(mHwcDevice, &numBytes, nullptr);
187 
188     std::vector<char> buffer(numBytes);
189     mDump(mHwcDevice, &numBytes, buffer.data());
190 
191     return std::string(buffer.data(), buffer.size());
192 }
193 
getMaxVirtualDisplayCount() const194 uint32_t Device::getMaxVirtualDisplayCount() const
195 {
196     return mGetMaxVirtualDisplayCount(mHwcDevice);
197 }
198 
createVirtualDisplay(uint32_t width,uint32_t height,android_pixel_format_t * format,std::shared_ptr<Display> * outDisplay)199 Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
200         android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay)
201 {
202     ALOGI("Creating virtual display");
203 
204     hwc2_display_t displayId = 0;
205     int32_t intFormat = static_cast<int32_t>(*format);
206     int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height,
207             &intFormat, &displayId);
208     auto error = static_cast<Error>(intError);
209     if (error != Error::None) {
210         return error;
211     }
212 
213     ALOGI("Created virtual display");
214     *format = static_cast<android_pixel_format_t>(intFormat);
215     *outDisplay = getDisplayById(displayId);
216     if (!*outDisplay) {
217         ALOGE("Failed to get display by id");
218         return Error::BadDisplay;
219     }
220     (*outDisplay)->setVirtual();
221     return Error::None;
222 }
223 
registerHotplugCallback(HotplugCallback hotplug)224 void Device::registerHotplugCallback(HotplugCallback hotplug)
225 {
226     ALOGV("registerHotplugCallback");
227     mHotplug = hotplug;
228     for (auto& pending : mPendingHotplugs) {
229         auto& display = pending.first;
230         auto connected = pending.second;
231         ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(),
232                 to_string(connected).c_str());
233         mHotplug(std::move(display), connected);
234     }
235 }
236 
registerRefreshCallback(RefreshCallback refresh)237 void Device::registerRefreshCallback(RefreshCallback refresh)
238 {
239     mRefresh = refresh;
240     for (auto& pending : mPendingRefreshes) {
241         mRefresh(std::move(pending));
242     }
243 }
244 
registerVsyncCallback(VsyncCallback vsync)245 void Device::registerVsyncCallback(VsyncCallback vsync)
246 {
247     mVsync = vsync;
248     for (auto& pending : mPendingVsyncs) {
249         auto& display = pending.first;
250         auto timestamp = pending.second;
251         mVsync(std::move(display), timestamp);
252     }
253 }
254 
255 // For use by Device callbacks
256 
callHotplug(std::shared_ptr<Display> display,Connection connected)257 void Device::callHotplug(std::shared_ptr<Display> display, Connection connected)
258 {
259     if (connected == Connection::Connected) {
260         if (!display->isConnected()) {
261             display->loadConfigs();
262             display->setConnected(true);
263         }
264     } else {
265         display->setConnected(false);
266         mDisplays.erase(display->getId());
267     }
268 
269     if (mHotplug) {
270         mHotplug(std::move(display), connected);
271     } else {
272         ALOGV("callHotplug called, but no valid callback registered, storing");
273         mPendingHotplugs.emplace_back(std::move(display), connected);
274     }
275 }
276 
callRefresh(std::shared_ptr<Display> display)277 void Device::callRefresh(std::shared_ptr<Display> display)
278 {
279     if (mRefresh) {
280         mRefresh(std::move(display));
281     } else {
282         ALOGV("callRefresh called, but no valid callback registered, storing");
283         mPendingRefreshes.emplace_back(std::move(display));
284     }
285 }
286 
callVsync(std::shared_ptr<Display> display,nsecs_t timestamp)287 void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp)
288 {
289     if (mVsync) {
290         mVsync(std::move(display), timestamp);
291     } else {
292         ALOGV("callVsync called, but no valid callback registered, storing");
293         mPendingVsyncs.emplace_back(std::move(display), timestamp);
294     }
295 }
296 
297 // Other Device methods
298 
getDisplayById(hwc2_display_t id)299 std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
300     if (mDisplays.count(id) != 0) {
301         auto strongDisplay = mDisplays[id].lock();
302         ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no"
303                 " longer alive", id);
304         return strongDisplay;
305     }
306 
307     auto display = std::make_shared<Display>(*this, id);
308     mDisplays.emplace(id, display);
309     return display;
310 }
311 
312 // Device initialization methods
313 
loadCapabilities()314 void Device::loadCapabilities()
315 {
316     static_assert(sizeof(Capability) == sizeof(int32_t),
317             "Capability size has changed");
318     uint32_t numCapabilities = 0;
319     mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr);
320     std::vector<Capability> capabilities(numCapabilities);
321     auto asInt = reinterpret_cast<int32_t*>(capabilities.data());
322     mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt);
323     for (auto capability : capabilities) {
324         mCapabilities.emplace(capability);
325     }
326 }
327 
hasCapability(HWC2::Capability capability) const328 bool Device::hasCapability(HWC2::Capability capability) const
329 {
330     return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
331             capability) != mCapabilities.cend();
332 }
333 
loadFunctionPointers()334 void Device::loadFunctionPointers()
335 {
336     // For all of these early returns, we log an error message inside
337     // loadFunctionPointer specifying which function failed to load
338 
339     // Display function pointers
340     if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay,
341             mCreateVirtualDisplay)) return;
342     if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay,
343             mDestroyVirtualDisplay)) return;
344     if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return;
345     if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount,
346             mGetMaxVirtualDisplayCount)) return;
347     if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback,
348             mRegisterCallback)) return;
349 
350     // Device function pointers
351     if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges,
352             mAcceptDisplayChanges)) return;
353     if (!loadFunctionPointer(FunctionDescriptor::CreateLayer,
354             mCreateLayer)) return;
355     if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer,
356             mDestroyLayer)) return;
357     if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig,
358             mGetActiveConfig)) return;
359     if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes,
360             mGetChangedCompositionTypes)) return;
361     if (!loadFunctionPointer(FunctionDescriptor::GetColorModes,
362             mGetColorModes)) return;
363     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute,
364             mGetDisplayAttribute)) return;
365     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs,
366             mGetDisplayConfigs)) return;
367     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName,
368             mGetDisplayName)) return;
369     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests,
370             mGetDisplayRequests)) return;
371     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType,
372             mGetDisplayType)) return;
373     if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport,
374             mGetDozeSupport)) return;
375     if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities,
376             mGetHdrCapabilities)) return;
377     if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences,
378             mGetReleaseFences)) return;
379     if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay,
380             mPresentDisplay)) return;
381     if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig,
382             mSetActiveConfig)) return;
383     if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget,
384             mSetClientTarget)) return;
385     if (!loadFunctionPointer(FunctionDescriptor::SetColorMode,
386             mSetColorMode)) return;
387     if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform,
388             mSetColorTransform)) return;
389     if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer,
390             mSetOutputBuffer)) return;
391     if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode,
392             mSetPowerMode)) return;
393     if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled,
394             mSetVsyncEnabled)) return;
395     if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay,
396             mValidateDisplay)) return;
397 
398     // Layer function pointers
399     if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition,
400             mSetCursorPosition)) return;
401     if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer,
402             mSetLayerBuffer)) return;
403     if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage,
404             mSetLayerSurfaceDamage)) return;
405     if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode,
406             mSetLayerBlendMode)) return;
407     if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor,
408             mSetLayerColor)) return;
409     if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType,
410             mSetLayerCompositionType)) return;
411     if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace,
412             mSetLayerDataspace)) return;
413     if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame,
414             mSetLayerDisplayFrame)) return;
415     if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
416             mSetLayerPlaneAlpha)) return;
417     if (hasCapability(Capability::SidebandStream)) {
418         if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
419                 mSetLayerSidebandStream)) return;
420     }
421     if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
422             mSetLayerSourceCrop)) return;
423     if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
424             mSetLayerTransform)) return;
425     if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion,
426             mSetLayerVisibleRegion)) return;
427     if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder,
428             mSetLayerZOrder)) return;
429 }
430 
registerCallbacks()431 void Device::registerCallbacks()
432 {
433     registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook);
434     registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook);
435     registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook);
436 }
437 
438 
439 // For use by Display
440 
destroyVirtualDisplay(hwc2_display_t display)441 void Device::destroyVirtualDisplay(hwc2_display_t display)
442 {
443     ALOGI("Destroying virtual display");
444     int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display);
445     auto error = static_cast<Error>(intError);
446     ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
447             " %s (%d)", display, to_string(error).c_str(), intError);
448     mDisplays.erase(display);
449 }
450 
451 // Display methods
452 
Display(Device & device,hwc2_display_t id)453 Display::Display(Device& device, hwc2_display_t id)
454   : mDevice(device),
455     mId(id),
456     mIsConnected(false),
457     mIsVirtual(false)
458 {
459     ALOGV("Created display %" PRIu64, id);
460 }
461 
~Display()462 Display::~Display()
463 {
464     ALOGV("Destroyed display %" PRIu64, mId);
465     if (mIsVirtual) {
466         mDevice.destroyVirtualDisplay(mId);
467     }
468 }
469 
Config(Display & display,hwc2_config_t id)470 Display::Config::Config(Display& display, hwc2_config_t id)
471   : mDisplay(display),
472     mId(id),
473     mWidth(-1),
474     mHeight(-1),
475     mVsyncPeriod(-1),
476     mDpiX(-1),
477     mDpiY(-1) {}
478 
Builder(Display & display,hwc2_config_t id)479 Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
480   : mConfig(new Config(display, id)) {}
481 
getDefaultDensity()482 float Display::Config::Builder::getDefaultDensity() {
483     // Default density is based on TVs: 1080p displays get XHIGH density, lower-
484     // resolution displays get TV density. Maybe eventually we'll need to update
485     // it for 4k displays, though hopefully those will just report accurate DPI
486     // information to begin with. This is also used for virtual displays and
487     // older HWC implementations, so be careful about orientation.
488 
489     auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
490     if (longDimension >= 1080) {
491         return ACONFIGURATION_DENSITY_XHIGH;
492     } else {
493         return ACONFIGURATION_DENSITY_TV;
494     }
495 }
496 
497 // Required by HWC2 display
498 
acceptChanges()499 Error Display::acceptChanges()
500 {
501     int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
502     return static_cast<Error>(intError);
503 }
504 
createLayer(std::shared_ptr<Layer> * outLayer)505 Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
506 {
507     hwc2_layer_t layerId = 0;
508     int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId);
509     auto error = static_cast<Error>(intError);
510     if (error != Error::None) {
511         return error;
512     }
513 
514     auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
515     mLayers.emplace(layerId, layer);
516     *outLayer = std::move(layer);
517     return Error::None;
518 }
519 
getActiveConfig(std::shared_ptr<const Display::Config> * outConfig) const520 Error Display::getActiveConfig(
521         std::shared_ptr<const Display::Config>* outConfig) const
522 {
523     ALOGV("[%" PRIu64 "] getActiveConfig", mId);
524     hwc2_config_t configId = 0;
525     int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId,
526             &configId);
527     auto error = static_cast<Error>(intError);
528 
529     if (error != Error::None) {
530         return error;
531     }
532 
533     if (mConfigs.count(configId) != 0) {
534         *outConfig = mConfigs.at(configId);
535     } else {
536         ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
537                 configId);
538         // Return no error, but the caller needs to check for a null pointer to
539         // detect this case
540         *outConfig = nullptr;
541     }
542 
543     return Error::None;
544 }
545 
getChangedCompositionTypes(std::unordered_map<std::shared_ptr<Layer>,Composition> * outTypes)546 Error Display::getChangedCompositionTypes(
547         std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
548 {
549     uint32_t numElements = 0;
550     int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice,
551             mId, &numElements, nullptr, nullptr);
552     auto error = static_cast<Error>(intError);
553     if (error != Error::None) {
554         return error;
555     }
556 
557     std::vector<hwc2_layer_t> layerIds(numElements);
558     std::vector<int32_t> types(numElements);
559     intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId,
560             &numElements, layerIds.data(), types.data());
561     error = static_cast<Error>(intError);
562     if (error != Error::None) {
563         return error;
564     }
565 
566     outTypes->clear();
567     outTypes->reserve(numElements);
568     for (uint32_t element = 0; element < numElements; ++element) {
569         auto layer = getLayerById(layerIds[element]);
570         if (layer) {
571             auto type = static_cast<Composition>(types[element]);
572             ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
573                     layer->getId(), to_string(type).c_str());
574             outTypes->emplace(layer, type);
575         } else {
576             ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
577                     " on display %" PRIu64, layerIds[element], mId);
578         }
579     }
580 
581     return Error::None;
582 }
583 
getColorModes(std::vector<android_color_mode_t> * outModes) const584 Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
585 {
586     uint32_t numModes = 0;
587     int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
588             &numModes, nullptr);
589     auto error = static_cast<Error>(intError);
590     if (error != Error::None)  {
591         return error;
592     }
593 
594     std::vector<int32_t> modes(numModes);
595     intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes,
596             modes.data());
597     error = static_cast<Error>(intError);
598     if (error != Error::None) {
599         return error;
600     }
601 
602     outModes->resize(numModes);
603     for (size_t i = 0; i < numModes; i++) {
604         (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
605     }
606     return Error::None;
607 }
608 
getConfigs() const609 std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
610 {
611     std::vector<std::shared_ptr<const Config>> configs;
612     for (const auto& element : mConfigs) {
613         configs.emplace_back(element.second);
614     }
615     return configs;
616 }
617 
getName(std::string * outName) const618 Error Display::getName(std::string* outName) const
619 {
620     uint32_t size;
621     int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
622             nullptr);
623     auto error = static_cast<Error>(intError);
624     if (error != Error::None) {
625         return error;
626     }
627 
628     std::vector<char> rawName(size);
629     intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
630             rawName.data());
631     error = static_cast<Error>(intError);
632     if (error != Error::None) {
633         return error;
634     }
635 
636     *outName = std::string(rawName.cbegin(), rawName.cend());
637     return Error::None;
638 }
639 
getRequests(HWC2::DisplayRequest * outDisplayRequests,std::unordered_map<std::shared_ptr<Layer>,LayerRequest> * outLayerRequests)640 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
641         std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
642                 outLayerRequests)
643 {
644     int32_t intDisplayRequests = 0;
645     uint32_t numElements = 0;
646     int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
647             &intDisplayRequests, &numElements, nullptr, nullptr);
648     auto error = static_cast<Error>(intError);
649     if (error != Error::None) {
650         return error;
651     }
652 
653     std::vector<hwc2_layer_t> layerIds(numElements);
654     std::vector<int32_t> layerRequests(numElements);
655     intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
656             &intDisplayRequests, &numElements, layerIds.data(),
657             layerRequests.data());
658     error = static_cast<Error>(intError);
659     if (error != Error::None) {
660         return error;
661     }
662 
663     *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
664     outLayerRequests->clear();
665     outLayerRequests->reserve(numElements);
666     for (uint32_t element = 0; element < numElements; ++element) {
667         auto layer = getLayerById(layerIds[element]);
668         if (layer) {
669             auto layerRequest =
670                     static_cast<LayerRequest>(layerRequests[element]);
671             outLayerRequests->emplace(layer, layerRequest);
672         } else {
673             ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
674                     PRIu64, layerIds[element], mId);
675         }
676     }
677 
678     return Error::None;
679 }
680 
getType(DisplayType * outType) const681 Error Display::getType(DisplayType* outType) const
682 {
683     int32_t intType = 0;
684     int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
685             &intType);
686     auto error = static_cast<Error>(intError);
687     if (error != Error::None) {
688         return error;
689     }
690 
691     *outType = static_cast<DisplayType>(intType);
692     return Error::None;
693 }
694 
supportsDoze(bool * outSupport) const695 Error Display::supportsDoze(bool* outSupport) const
696 {
697     int32_t intSupport = 0;
698     int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId,
699             &intSupport);
700     auto error = static_cast<Error>(intError);
701     if (error != Error::None) {
702         return error;
703     }
704     *outSupport = static_cast<bool>(intSupport);
705     return Error::None;
706 }
707 
getHdrCapabilities(std::unique_ptr<HdrCapabilities> * outCapabilities) const708 Error Display::getHdrCapabilities(
709         std::unique_ptr<HdrCapabilities>* outCapabilities) const
710 {
711     uint32_t numTypes = 0;
712     float maxLuminance = -1.0f;
713     float maxAverageLuminance = -1.0f;
714     float minLuminance = -1.0f;
715     int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId,
716             &numTypes, nullptr, &maxLuminance, &maxAverageLuminance,
717             &minLuminance);
718     auto error = static_cast<HWC2::Error>(intError);
719     if (error != Error::None) {
720         return error;
721     }
722 
723     std::vector<int32_t> types(numTypes);
724     intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes,
725             types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance);
726     error = static_cast<HWC2::Error>(intError);
727     if (error != Error::None) {
728         return error;
729     }
730 
731     *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
732             maxLuminance, maxAverageLuminance, minLuminance);
733     return Error::None;
734 }
735 
getReleaseFences(std::unordered_map<std::shared_ptr<Layer>,sp<Fence>> * outFences) const736 Error Display::getReleaseFences(
737         std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
738 {
739     uint32_t numElements = 0;
740     int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId,
741             &numElements, nullptr, nullptr);
742     auto error = static_cast<Error>(intError);
743     if (error != Error::None) {
744         return error;
745     }
746 
747     std::vector<hwc2_layer_t> layerIds(numElements);
748     std::vector<int32_t> fenceFds(numElements);
749     intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements,
750             layerIds.data(), fenceFds.data());
751     error = static_cast<Error>(intError);
752     if (error != Error::None) {
753         return error;
754     }
755 
756     std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
757     releaseFences.reserve(numElements);
758     for (uint32_t element = 0; element < numElements; ++element) {
759         auto layer = getLayerById(layerIds[element]);
760         if (layer) {
761             sp<Fence> fence(new Fence(fenceFds[element]));
762             releaseFences.emplace(std::move(layer), fence);
763         } else {
764             ALOGE("getReleaseFences: invalid layer %" PRIu64
765                     " found on display %" PRIu64, layerIds[element], mId);
766             return Error::BadLayer;
767         }
768     }
769 
770     *outFences = std::move(releaseFences);
771     return Error::None;
772 }
773 
present(sp<Fence> * outRetireFence)774 Error Display::present(sp<Fence>* outRetireFence)
775 {
776     int32_t retireFenceFd = 0;
777     int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId,
778             &retireFenceFd);
779     auto error = static_cast<Error>(intError);
780     if (error != Error::None) {
781         return error;
782     }
783 
784     *outRetireFence = new Fence(retireFenceFd);
785     return Error::None;
786 }
787 
setActiveConfig(const std::shared_ptr<const Config> & config)788 Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
789 {
790     if (config->getDisplayId() != mId) {
791         ALOGE("setActiveConfig received config %u for the wrong display %"
792                 PRIu64 " (expected %" PRIu64 ")", config->getId(),
793                 config->getDisplayId(), mId);
794         return Error::BadConfig;
795     }
796     int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId,
797             config->getId());
798     return static_cast<Error>(intError);
799 }
800 
setClientTarget(buffer_handle_t target,const sp<Fence> & acquireFence,android_dataspace_t dataspace)801 Error Display::setClientTarget(buffer_handle_t target,
802         const sp<Fence>& acquireFence, android_dataspace_t dataspace)
803 {
804     // TODO: Properly encode client target surface damage
805     int32_t fenceFd = acquireFence->dup();
806     int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
807             fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
808     return static_cast<Error>(intError);
809 }
810 
setColorMode(android_color_mode_t mode)811 Error Display::setColorMode(android_color_mode_t mode)
812 {
813     int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
814     return static_cast<Error>(intError);
815 }
816 
setColorTransform(const android::mat4 & matrix,android_color_transform_t hint)817 Error Display::setColorTransform(const android::mat4& matrix,
818         android_color_transform_t hint)
819 {
820     int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
821             matrix.asArray(), static_cast<int32_t>(hint));
822     return static_cast<Error>(intError);
823 }
824 
setOutputBuffer(const sp<GraphicBuffer> & buffer,const sp<Fence> & releaseFence)825 Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
826         const sp<Fence>& releaseFence)
827 {
828     int32_t fenceFd = releaseFence->dup();
829     auto handle = buffer->getNativeBuffer()->handle;
830     int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
831             fenceFd);
832     close(fenceFd);
833     return static_cast<Error>(intError);
834 }
835 
setPowerMode(PowerMode mode)836 Error Display::setPowerMode(PowerMode mode)
837 {
838     auto intMode = static_cast<int32_t>(mode);
839     int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode);
840     return static_cast<Error>(intError);
841 }
842 
setVsyncEnabled(Vsync enabled)843 Error Display::setVsyncEnabled(Vsync enabled)
844 {
845     auto intEnabled = static_cast<int32_t>(enabled);
846     int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId,
847             intEnabled);
848     return static_cast<Error>(intError);
849 }
850 
validate(uint32_t * outNumTypes,uint32_t * outNumRequests)851 Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
852 {
853     uint32_t numTypes = 0;
854     uint32_t numRequests = 0;
855     int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId,
856             &numTypes, &numRequests);
857     auto error = static_cast<Error>(intError);
858     if (error != Error::None && error != Error::HasChanges) {
859         return error;
860     }
861 
862     *outNumTypes = numTypes;
863     *outNumRequests = numRequests;
864     return error;
865 }
866 
867 // For use by Device
868 
getAttribute(hwc2_config_t configId,Attribute attribute)869 int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
870 {
871     int32_t value = 0;
872     int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId,
873             configId, static_cast<int32_t>(attribute), &value);
874     auto error = static_cast<Error>(intError);
875     if (error != Error::None) {
876         ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
877                 configId, to_string(attribute).c_str(),
878                 to_string(error).c_str(), intError);
879         return -1;
880     }
881     return value;
882 }
883 
loadConfig(hwc2_config_t configId)884 void Display::loadConfig(hwc2_config_t configId)
885 {
886     ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
887 
888     auto config = Config::Builder(*this, configId)
889             .setWidth(getAttribute(configId, Attribute::Width))
890             .setHeight(getAttribute(configId, Attribute::Height))
891             .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
892             .setDpiX(getAttribute(configId, Attribute::DpiX))
893             .setDpiY(getAttribute(configId, Attribute::DpiY))
894             .build();
895     mConfigs.emplace(configId, std::move(config));
896 }
897 
loadConfigs()898 void Display::loadConfigs()
899 {
900     ALOGV("[%" PRIu64 "] loadConfigs", mId);
901 
902     uint32_t numConfigs = 0;
903     int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId,
904             &numConfigs, nullptr);
905     auto error = static_cast<Error>(intError);
906     if (error != Error::None) {
907         ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId,
908                 to_string(error).c_str(), intError);
909         return;
910     }
911 
912     std::vector<hwc2_config_t> configIds(numConfigs);
913     intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs,
914             configIds.data());
915     error = static_cast<Error>(intError);
916     if (error != Error::None) {
917         ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
918                 to_string(error).c_str(), intError);
919         return;
920     }
921 
922     for (auto configId : configIds) {
923         loadConfig(configId);
924     }
925 }
926 
927 // For use by Layer
928 
destroyLayer(hwc2_layer_t layerId)929 void Display::destroyLayer(hwc2_layer_t layerId)
930 {
931     int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId);
932     auto error = static_cast<Error>(intError);
933     ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
934             " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
935             intError);
936     mLayers.erase(layerId);
937 }
938 
939 // Other Display methods
940 
getLayerById(hwc2_layer_t id) const941 std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
942 {
943     if (mLayers.count(id) == 0) {
944         return nullptr;
945     }
946 
947     auto layer = mLayers.at(id).lock();
948     return layer;
949 }
950 
951 // Layer methods
952 
Layer(const std::shared_ptr<Display> & display,hwc2_layer_t id)953 Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
954   : mDisplay(display),
955     mDisplayId(display->getId()),
956     mDevice(display->getDevice()),
957     mId(id)
958 {
959     ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
960             display->getId());
961 }
962 
~Layer()963 Layer::~Layer()
964 {
965     auto display = mDisplay.lock();
966     if (display) {
967         display->destroyLayer(mId);
968     }
969 }
970 
setCursorPosition(int32_t x,int32_t y)971 Error Layer::setCursorPosition(int32_t x, int32_t y)
972 {
973     int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice,
974             mDisplayId, mId, x, y);
975     return static_cast<Error>(intError);
976 }
977 
setBuffer(buffer_handle_t buffer,const sp<Fence> & acquireFence)978 Error Layer::setBuffer(buffer_handle_t buffer,
979         const sp<Fence>& acquireFence)
980 {
981     int32_t fenceFd = acquireFence->dup();
982     int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
983             mId, buffer, fenceFd);
984     return static_cast<Error>(intError);
985 }
986 
setSurfaceDamage(const Region & damage)987 Error Layer::setSurfaceDamage(const Region& damage)
988 {
989     // We encode default full-screen damage as INVALID_RECT upstream, but as 0
990     // rects for HWC
991     int32_t intError = 0;
992     if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
993         intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
994                 mDisplayId, mId, {0, nullptr});
995     } else {
996         size_t rectCount = 0;
997         auto rectArray = damage.getArray(&rectCount);
998 
999         std::vector<hwc_rect_t> hwcRects;
1000         for (size_t rect = 0; rect < rectCount; ++rect) {
1001             hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1002                     rectArray[rect].right, rectArray[rect].bottom});
1003         }
1004 
1005         hwc_region_t hwcRegion = {};
1006         hwcRegion.numRects = rectCount;
1007         hwcRegion.rects = hwcRects.data();
1008 
1009         intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1010                 mDisplayId, mId, hwcRegion);
1011     }
1012 
1013     return static_cast<Error>(intError);
1014 }
1015 
setBlendMode(BlendMode mode)1016 Error Layer::setBlendMode(BlendMode mode)
1017 {
1018     auto intMode = static_cast<int32_t>(mode);
1019     int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice,
1020             mDisplayId, mId, intMode);
1021     return static_cast<Error>(intError);
1022 }
1023 
setColor(hwc_color_t color)1024 Error Layer::setColor(hwc_color_t color)
1025 {
1026     int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId,
1027             mId, color);
1028     return static_cast<Error>(intError);
1029 }
1030 
setCompositionType(Composition type)1031 Error Layer::setCompositionType(Composition type)
1032 {
1033     auto intType = static_cast<int32_t>(type);
1034     int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice,
1035             mDisplayId, mId, intType);
1036     return static_cast<Error>(intError);
1037 }
1038 
setDataspace(android_dataspace_t dataspace)1039 Error Layer::setDataspace(android_dataspace_t dataspace)
1040 {
1041     auto intDataspace = static_cast<int32_t>(dataspace);
1042     int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
1043             mDisplayId, mId, intDataspace);
1044     return static_cast<Error>(intError);
1045 }
1046 
setDisplayFrame(const Rect & frame)1047 Error Layer::setDisplayFrame(const Rect& frame)
1048 {
1049     hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
1050     int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice,
1051             mDisplayId, mId, hwcRect);
1052     return static_cast<Error>(intError);
1053 }
1054 
setPlaneAlpha(float alpha)1055 Error Layer::setPlaneAlpha(float alpha)
1056 {
1057     int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice,
1058             mDisplayId, mId, alpha);
1059     return static_cast<Error>(intError);
1060 }
1061 
setSidebandStream(const native_handle_t * stream)1062 Error Layer::setSidebandStream(const native_handle_t* stream)
1063 {
1064     if (!mDevice.hasCapability(Capability::SidebandStream)) {
1065         ALOGE("Attempted to call setSidebandStream without checking that the "
1066                 "device supports sideband streams");
1067         return Error::Unsupported;
1068     }
1069     int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
1070             mDisplayId, mId, stream);
1071     return static_cast<Error>(intError);
1072 }
1073 
setSourceCrop(const FloatRect & crop)1074 Error Layer::setSourceCrop(const FloatRect& crop)
1075 {
1076     hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom};
1077     int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice,
1078             mDisplayId, mId, hwcRect);
1079     return static_cast<Error>(intError);
1080 }
1081 
setTransform(Transform transform)1082 Error Layer::setTransform(Transform transform)
1083 {
1084     auto intTransform = static_cast<int32_t>(transform);
1085     int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice,
1086             mDisplayId, mId, intTransform);
1087     return static_cast<Error>(intError);
1088 }
1089 
setVisibleRegion(const Region & region)1090 Error Layer::setVisibleRegion(const Region& region)
1091 {
1092     size_t rectCount = 0;
1093     auto rectArray = region.getArray(&rectCount);
1094 
1095     std::vector<hwc_rect_t> hwcRects;
1096     for (size_t rect = 0; rect < rectCount; ++rect) {
1097         hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1098                 rectArray[rect].right, rectArray[rect].bottom});
1099     }
1100 
1101     hwc_region_t hwcRegion = {};
1102     hwcRegion.numRects = rectCount;
1103     hwcRegion.rects = hwcRects.data();
1104 
1105     int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice,
1106             mDisplayId, mId, hwcRegion);
1107     return static_cast<Error>(intError);
1108 }
1109 
setZOrder(uint32_t z)1110 Error Layer::setZOrder(uint32_t z)
1111 {
1112     int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId,
1113             mId, z);
1114     return static_cast<Error>(intError);
1115 }
1116 
1117 } // namespace HWC2
1118