• 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;
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 
dump() const178 std::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 
getMaxVirtualDisplayCount() const189 uint32_t Device::getMaxVirtualDisplayCount() const
190 {
191     return mGetMaxVirtualDisplayCount(mHwcDevice);
192 }
193 
createVirtualDisplay(uint32_t width,uint32_t height,android_pixel_format_t * format,std::shared_ptr<Display> * outDisplay)194 Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
195         android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay)
196 {
197     ALOGI("Creating virtual display");
198 
199     hwc2_display_t displayId = 0;
200     int32_t intFormat = static_cast<int32_t>(*format);
201     int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height,
202             &intFormat, &displayId);
203     auto error = static_cast<Error>(intError);
204     if (error != Error::None) {
205         return error;
206     }
207 
208     ALOGI("Created virtual display");
209     *format = static_cast<android_pixel_format_t>(intFormat);
210     *outDisplay = getDisplayById(displayId);
211     (*outDisplay)->setVirtual();
212     return Error::None;
213 }
214 
registerHotplugCallback(HotplugCallback hotplug)215 void 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 
registerRefreshCallback(RefreshCallback refresh)228 void Device::registerRefreshCallback(RefreshCallback refresh)
229 {
230     mRefresh = refresh;
231     for (auto& pending : mPendingRefreshes) {
232         mRefresh(std::move(pending));
233     }
234 }
235 
registerVsyncCallback(VsyncCallback vsync)236 void 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 
callHotplug(std::shared_ptr<Display> display,Connection connected)248 void 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 
callRefresh(std::shared_ptr<Display> display)268 void 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 
callVsync(std::shared_ptr<Display> display,nsecs_t timestamp)278 void 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 
getDisplayById(hwc2_display_t id)290 std::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 
loadCapabilities()302 void 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 
hasCapability(HWC2::Capability capability) const313 bool Device::hasCapability(HWC2::Capability capability) const
314 {
315     return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
316             capability) != mCapabilities.cend();
317 }
318 
loadFunctionPointers()319 void 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
325     if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay,
326             mCreateVirtualDisplay)) return;
327     if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay,
328             mDestroyVirtualDisplay)) return;
329     if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return;
330     if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount,
331             mGetMaxVirtualDisplayCount)) return;
332     if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback,
333             mRegisterCallback)) return;
334 
335     // Device function pointers
336     if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges,
337             mAcceptDisplayChanges)) return;
338     if (!loadFunctionPointer(FunctionDescriptor::CreateLayer,
339             mCreateLayer)) return;
340     if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer,
341             mDestroyLayer)) return;
342     if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig,
343             mGetActiveConfig)) return;
344     if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes,
345             mGetChangedCompositionTypes)) return;
346     if (!loadFunctionPointer(FunctionDescriptor::GetColorModes,
347             mGetColorModes)) return;
348     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute,
349             mGetDisplayAttribute)) return;
350     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs,
351             mGetDisplayConfigs)) return;
352     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName,
353             mGetDisplayName)) return;
354     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests,
355             mGetDisplayRequests)) return;
356     if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType,
357             mGetDisplayType)) return;
358     if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport,
359             mGetDozeSupport)) return;
360     if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities,
361             mGetHdrCapabilities)) return;
362     if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences,
363             mGetReleaseFences)) return;
364     if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay,
365             mPresentDisplay)) return;
366     if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig,
367             mSetActiveConfig)) return;
368     if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget,
369             mSetClientTarget)) return;
370     if (!loadFunctionPointer(FunctionDescriptor::SetColorMode,
371             mSetColorMode)) return;
372     if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform,
373             mSetColorTransform)) return;
374     if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer,
375             mSetOutputBuffer)) return;
376     if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode,
377             mSetPowerMode)) return;
378     if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled,
379             mSetVsyncEnabled)) return;
380     if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay,
381             mValidateDisplay)) return;
382 
383     // Layer function pointers
384     if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition,
385             mSetCursorPosition)) return;
386     if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer,
387             mSetLayerBuffer)) return;
388     if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage,
389             mSetLayerSurfaceDamage)) return;
390     if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode,
391             mSetLayerBlendMode)) return;
392     if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor,
393             mSetLayerColor)) return;
394     if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType,
395             mSetLayerCompositionType)) return;
396     if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace,
397             mSetLayerDataspace)) return;
398     if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame,
399             mSetLayerDisplayFrame)) return;
400     if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
401             mSetLayerPlaneAlpha)) return;
402     if (hasCapability(Capability::SidebandStream)) {
403         if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
404                 mSetLayerSidebandStream)) return;
405     }
406     if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
407             mSetLayerSourceCrop)) return;
408     if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
409             mSetLayerTransform)) return;
410     if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion,
411             mSetLayerVisibleRegion)) return;
412     if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder,
413             mSetLayerZOrder)) return;
414 }
415 
registerCallbacks()416 void 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 
destroyVirtualDisplay(hwc2_display_t display)426 void 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 
Display(Device & device,hwc2_display_t id)437 Display::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 
~Display()446 Display::~Display()
447 {
448     ALOGV("Destroyed display %" PRIu64, mId);
449     if (mIsVirtual) {
450         mDevice.destroyVirtualDisplay(mId);
451     }
452 }
453 
Config(Display & display,hwc2_config_t id)454 Display::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 
Builder(Display & display,hwc2_config_t id)463 Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
464   : mConfig(new Config(display, id)) {}
465 
getDefaultDensity()466 float 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 
acceptChanges()483 Error Display::acceptChanges()
484 {
485     int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
486     return static_cast<Error>(intError);
487 }
488 
createLayer(std::shared_ptr<Layer> * outLayer)489 Error 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 
getActiveConfig(std::shared_ptr<const Display::Config> * outConfig) const504 Error 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 
getChangedCompositionTypes(std::unordered_map<std::shared_ptr<Layer>,Composition> * outTypes)530 Error 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 
getColorModes(std::vector<int32_t> * outModes) const568 Error 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 
getConfigs() const590 std::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 
getName(std::string * outName) const599 Error 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 
getRequests(HWC2::DisplayRequest * outDisplayRequests,std::unordered_map<std::shared_ptr<Layer>,LayerRequest> * outLayerRequests)621 Error 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 
getType(DisplayType * outType) const662 Error 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 
supportsDoze(bool * outSupport) const676 Error 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 
getHdrCapabilities(std::unique_ptr<HdrCapabilities> * outCapabilities) const689 Error 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 
getReleaseFences(std::unordered_map<std::shared_ptr<Layer>,sp<Fence>> * outFences) const717 Error 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 
present(sp<Fence> * outRetireFence)755 Error 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 
setActiveConfig(const std::shared_ptr<const Config> & config)769 Error 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 
setClientTarget(buffer_handle_t target,const sp<Fence> & acquireFence,android_dataspace_t dataspace)782 Error Display::setClientTarget(buffer_handle_t target,
783         const sp<Fence>& acquireFence, android_dataspace_t dataspace)
784 {
785     // TODO: Properly encode client target surface damage
786     int32_t fenceFd = acquireFence->dup();
787     int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
788             fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
789     return static_cast<Error>(intError);
790 }
791 
setColorMode(int32_t mode)792 Error Display::setColorMode(int32_t mode)
793 {
794     int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
795     return static_cast<Error>(intError);
796 }
797 
setColorTransform(const android::mat4 & matrix,android_color_transform_t hint)798 Error 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 
setOutputBuffer(const sp<GraphicBuffer> & buffer,const sp<Fence> & releaseFence)806 Error 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 
setPowerMode(PowerMode mode)816 Error 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 
setVsyncEnabled(Vsync enabled)823 Error 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 
validate(uint32_t * outNumTypes,uint32_t * outNumRequests)831 Error 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 
getAttribute(hwc2_config_t configId,Attribute attribute)849 int32_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 
loadConfig(hwc2_config_t configId)864 void 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 
loadConfigs()878 void 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 
destroyLayer(hwc2_layer_t layerId)909 void 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 
getLayerById(hwc2_layer_t id) const921 std::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 
Layer(const std::shared_ptr<Display> & display,hwc2_layer_t id)933 Layer::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 
~Layer()943 Layer::~Layer()
944 {
945     auto display = mDisplay.lock();
946     if (display) {
947         display->destroyLayer(mId);
948     }
949 }
950 
setCursorPosition(int32_t x,int32_t y)951 Error 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 
setBuffer(buffer_handle_t buffer,const sp<Fence> & acquireFence)958 Error 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 
setSurfaceDamage(const Region & damage)967 Error 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 
setBlendMode(BlendMode mode)996 Error 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 
setColor(hwc_color_t color)1004 Error 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 
setCompositionType(Composition type)1011 Error 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 
setDataspace(android_dataspace_t dataspace)1019 Error 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 
setDisplayFrame(const Rect & frame)1027 Error 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 
setPlaneAlpha(float alpha)1035 Error 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 
setSidebandStream(const native_handle_t * stream)1042 Error Layer::setSidebandStream(const native_handle_t* stream)
1043 {
1044     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     }
1049     int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
1050             mDisplayId, mId, stream);
1051     return static_cast<Error>(intError);
1052 }
1053 
setSourceCrop(const FloatRect & crop)1054 Error 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 
setTransform(Transform transform)1062 Error 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 
setVisibleRegion(const Region & region)1070 Error 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 
setZOrder(uint32_t z)1090 Error 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
1098