• 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 #include "ComposerHal.h"
25 
26 #include <ui/Fence.h>
27 #include <ui/FloatRect.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 using android::hardware::Return;
83 using android::hardware::Void;
84 
85 namespace HWC2 {
86 
87 namespace Hwc2 = android::Hwc2;
88 
89 // Device methods
90 
Device(bool useVrComposer)91 Device::Device(bool useVrComposer)
92   : mComposer(std::make_unique<Hwc2::Composer>(useVrComposer)),
93     mCapabilities(),
94     mDisplays(),
95     mHotplug(),
96     mPendingHotplugs(),
97     mRefresh(),
98     mPendingRefreshes(),
99     mVsync(),
100     mPendingVsyncs()
101 {
102     loadCapabilities();
103     registerCallbacks();
104 }
105 
~Device()106 Device::~Device()
107 {
108     for (auto element : mDisplays) {
109         auto display = element.second.lock();
110         if (!display) {
111             ALOGE("~Device: Found a display (%" PRId64 " that has already been"
112                     " destroyed", element.first);
113             continue;
114         }
115 
116         DisplayType displayType = HWC2::DisplayType::Invalid;
117         auto error = display->getType(&displayType);
118         if (error != Error::None) {
119             ALOGE("~Device: Failed to determine type of display %" PRIu64
120                     ": %s (%d)", display->getId(), to_string(error).c_str(),
121                     static_cast<int32_t>(error));
122             continue;
123         }
124 
125         if (displayType == HWC2::DisplayType::Physical) {
126             error = display->setVsyncEnabled(HWC2::Vsync::Disable);
127             if (error != Error::None) {
128                 ALOGE("~Device: Failed to disable vsync for display %" PRIu64
129                         ": %s (%d)", display->getId(), to_string(error).c_str(),
130                         static_cast<int32_t>(error));
131             }
132         }
133     }
134 }
135 
136 // Required by HWC2 device
137 
dump() const138 std::string Device::dump() const
139 {
140     return mComposer->dumpDebugInfo();
141 }
142 
getMaxVirtualDisplayCount() const143 uint32_t Device::getMaxVirtualDisplayCount() const
144 {
145     return mComposer->getMaxVirtualDisplayCount();
146 }
147 
createVirtualDisplay(uint32_t width,uint32_t height,android_pixel_format_t * format,std::shared_ptr<Display> * outDisplay)148 Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
149         android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay)
150 {
151     ALOGI("Creating virtual display");
152 
153     hwc2_display_t displayId = 0;
154     auto intFormat = static_cast<Hwc2::PixelFormat>(*format);
155     auto intError = mComposer->createVirtualDisplay(width, height,
156             &intFormat, &displayId);
157     auto error = static_cast<Error>(intError);
158     if (error != Error::None) {
159         return error;
160     }
161 
162     ALOGI("Created virtual display");
163     *format = static_cast<android_pixel_format_t>(intFormat);
164     *outDisplay = getDisplayById(displayId);
165     if (!*outDisplay) {
166         ALOGE("Failed to get display by id");
167         return Error::BadDisplay;
168     }
169     (*outDisplay)->setConnected(true);
170     return Error::None;
171 }
172 
registerHotplugCallback(HotplugCallback hotplug)173 void Device::registerHotplugCallback(HotplugCallback hotplug)
174 {
175     ALOGV("registerHotplugCallback");
176     mHotplug = hotplug;
177     for (auto& pending : mPendingHotplugs) {
178         auto& display = pending.first;
179         auto connected = pending.second;
180         ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(),
181                 to_string(connected).c_str());
182         mHotplug(std::move(display), connected);
183     }
184 }
185 
registerRefreshCallback(RefreshCallback refresh)186 void Device::registerRefreshCallback(RefreshCallback refresh)
187 {
188     mRefresh = refresh;
189     for (auto& pending : mPendingRefreshes) {
190         mRefresh(std::move(pending));
191     }
192 }
193 
registerVsyncCallback(VsyncCallback vsync)194 void Device::registerVsyncCallback(VsyncCallback vsync)
195 {
196     mVsync = vsync;
197     for (auto& pending : mPendingVsyncs) {
198         auto& display = pending.first;
199         auto timestamp = pending.second;
200         mVsync(std::move(display), timestamp);
201     }
202 }
203 
204 // For use by Device callbacks
205 
callHotplug(std::shared_ptr<Display> display,Connection connected)206 void Device::callHotplug(std::shared_ptr<Display> display, Connection connected)
207 {
208     if (connected == Connection::Connected) {
209         if (!display->isConnected()) {
210             mComposer->setClientTargetSlotCount(display->getId());
211             display->loadConfigs();
212             display->setConnected(true);
213         }
214     } else {
215         display->setConnected(false);
216         mDisplays.erase(display->getId());
217     }
218 
219     if (mHotplug) {
220         mHotplug(std::move(display), connected);
221     } else {
222         ALOGV("callHotplug called, but no valid callback registered, storing");
223         mPendingHotplugs.emplace_back(std::move(display), connected);
224     }
225 }
226 
callRefresh(std::shared_ptr<Display> display)227 void Device::callRefresh(std::shared_ptr<Display> display)
228 {
229     if (mRefresh) {
230         mRefresh(std::move(display));
231     } else {
232         ALOGV("callRefresh called, but no valid callback registered, storing");
233         mPendingRefreshes.emplace_back(std::move(display));
234     }
235 }
236 
callVsync(std::shared_ptr<Display> display,nsecs_t timestamp)237 void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp)
238 {
239     if (mVsync) {
240         mVsync(std::move(display), timestamp);
241     } else {
242         ALOGV("callVsync called, but no valid callback registered, storing");
243         mPendingVsyncs.emplace_back(std::move(display), timestamp);
244     }
245 }
246 
247 // Other Device methods
248 
getDisplayById(hwc2_display_t id)249 std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
250     if (mDisplays.count(id) != 0) {
251         auto strongDisplay = mDisplays[id].lock();
252         ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no"
253                 " longer alive", id);
254         return strongDisplay;
255     }
256 
257     auto display = std::make_shared<Display>(*this, id);
258     mDisplays.emplace(id, display);
259     return display;
260 }
261 
262 // Device initialization methods
263 
loadCapabilities()264 void Device::loadCapabilities()
265 {
266     static_assert(sizeof(Capability) == sizeof(int32_t),
267             "Capability size has changed");
268     auto capabilities = mComposer->getCapabilities();
269     for (auto capability : capabilities) {
270         mCapabilities.emplace(static_cast<Capability>(capability));
271     }
272 }
273 
hasCapability(HWC2::Capability capability) const274 bool Device::hasCapability(HWC2::Capability capability) const
275 {
276     return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
277             capability) != mCapabilities.cend();
278 }
279 
280 namespace {
281 class ComposerCallback : public Hwc2::IComposerCallback {
282 public:
ComposerCallback(Device * device)283     ComposerCallback(Device* device) : mDevice(device) {}
284 
onHotplug(Hwc2::Display display,Connection connected)285     Return<void> onHotplug(Hwc2::Display display,
286             Connection connected) override
287     {
288         hotplug_hook(mDevice, display, static_cast<int32_t>(connected));
289         return Void();
290     }
291 
onRefresh(Hwc2::Display display)292     Return<void> onRefresh(Hwc2::Display display) override
293     {
294         refresh_hook(mDevice, display);
295         return Void();
296     }
297 
onVsync(Hwc2::Display display,int64_t timestamp)298     Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
299     {
300         vsync_hook(mDevice, display, timestamp);
301         return Void();
302     }
303 
304 private:
305     Device* mDevice;
306 };
307 } // namespace anonymous
308 
registerCallbacks()309 void Device::registerCallbacks()
310 {
311     sp<ComposerCallback> callback = new ComposerCallback(this);
312     mComposer->registerCallback(callback);
313 }
314 
315 
316 // For use by Display
317 
destroyVirtualDisplay(hwc2_display_t display)318 void Device::destroyVirtualDisplay(hwc2_display_t display)
319 {
320     ALOGI("Destroying virtual display");
321     auto intError = mComposer->destroyVirtualDisplay(display);
322     auto error = static_cast<Error>(intError);
323     ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
324             " %s (%d)", display, to_string(error).c_str(), intError);
325     mDisplays.erase(display);
326 }
327 
328 // Display methods
329 
Display(Device & device,hwc2_display_t id)330 Display::Display(Device& device, hwc2_display_t id)
331   : mDevice(device),
332     mId(id),
333     mIsConnected(false),
334     mType(DisplayType::Invalid)
335 {
336     ALOGV("Created display %" PRIu64, id);
337 
338     auto intError = mDevice.mComposer->getDisplayType(mId,
339             reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(&mType));
340     auto error = static_cast<Error>(intError);
341     if (error != Error::None) {
342         ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d)",
343               id, to_string(error).c_str(), intError);
344     }
345 }
346 
~Display()347 Display::~Display()
348 {
349     ALOGV("Destroyed display %" PRIu64, mId);
350     if (mType == DisplayType::Virtual) {
351         mDevice.destroyVirtualDisplay(mId);
352     }
353 }
354 
Config(Display & display,hwc2_config_t id)355 Display::Config::Config(Display& display, hwc2_config_t id)
356   : mDisplay(display),
357     mId(id),
358     mWidth(-1),
359     mHeight(-1),
360     mVsyncPeriod(-1),
361     mDpiX(-1),
362     mDpiY(-1) {}
363 
Builder(Display & display,hwc2_config_t id)364 Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
365   : mConfig(new Config(display, id)) {}
366 
getDefaultDensity()367 float Display::Config::Builder::getDefaultDensity() {
368     // Default density is based on TVs: 1080p displays get XHIGH density, lower-
369     // resolution displays get TV density. Maybe eventually we'll need to update
370     // it for 4k displays, though hopefully those will just report accurate DPI
371     // information to begin with. This is also used for virtual displays and
372     // older HWC implementations, so be careful about orientation.
373 
374     auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
375     if (longDimension >= 1080) {
376         return ACONFIGURATION_DENSITY_XHIGH;
377     } else {
378         return ACONFIGURATION_DENSITY_TV;
379     }
380 }
381 
382 // Required by HWC2 display
383 
acceptChanges()384 Error Display::acceptChanges()
385 {
386     auto intError = mDevice.mComposer->acceptDisplayChanges(mId);
387     return static_cast<Error>(intError);
388 }
389 
createLayer(std::shared_ptr<Layer> * outLayer)390 Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
391 {
392     hwc2_layer_t layerId = 0;
393     auto intError = mDevice.mComposer->createLayer(mId, &layerId);
394     auto error = static_cast<Error>(intError);
395     if (error != Error::None) {
396         return error;
397     }
398 
399     auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
400     mLayers.emplace(layerId, layer);
401     *outLayer = std::move(layer);
402     return Error::None;
403 }
404 
getActiveConfig(std::shared_ptr<const Display::Config> * outConfig) const405 Error Display::getActiveConfig(
406         std::shared_ptr<const Display::Config>* outConfig) const
407 {
408     ALOGV("[%" PRIu64 "] getActiveConfig", mId);
409     hwc2_config_t configId = 0;
410     auto intError = mDevice.mComposer->getActiveConfig(mId, &configId);
411     auto error = static_cast<Error>(intError);
412 
413     if (error != Error::None) {
414         ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
415         *outConfig = nullptr;
416         return error;
417     }
418 
419     if (mConfigs.count(configId) != 0) {
420         *outConfig = mConfigs.at(configId);
421     } else {
422         ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
423                 configId);
424         // Return no error, but the caller needs to check for a null pointer to
425         // detect this case
426         *outConfig = nullptr;
427     }
428 
429     return Error::None;
430 }
431 
getChangedCompositionTypes(std::unordered_map<std::shared_ptr<Layer>,Composition> * outTypes)432 Error Display::getChangedCompositionTypes(
433         std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
434 {
435     std::vector<Hwc2::Layer> layerIds;
436     std::vector<Hwc2::IComposerClient::Composition> types;
437     auto intError = mDevice.mComposer->getChangedCompositionTypes(mId,
438             &layerIds, &types);
439     uint32_t numElements = layerIds.size();
440     auto error = static_cast<Error>(intError);
441     error = static_cast<Error>(intError);
442     if (error != Error::None) {
443         return error;
444     }
445 
446     outTypes->clear();
447     outTypes->reserve(numElements);
448     for (uint32_t element = 0; element < numElements; ++element) {
449         auto layer = getLayerById(layerIds[element]);
450         if (layer) {
451             auto type = static_cast<Composition>(types[element]);
452             ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
453                     layer->getId(), to_string(type).c_str());
454             outTypes->emplace(layer, type);
455         } else {
456             ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
457                     " on display %" PRIu64, layerIds[element], mId);
458         }
459     }
460 
461     return Error::None;
462 }
463 
getColorModes(std::vector<android_color_mode_t> * outModes) const464 Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
465 {
466     std::vector<Hwc2::ColorMode> modes;
467     auto intError = mDevice.mComposer->getColorModes(mId, &modes);
468     uint32_t numModes = modes.size();
469     auto error = static_cast<Error>(intError);
470     if (error != Error::None) {
471         return error;
472     }
473 
474     outModes->resize(numModes);
475     for (size_t i = 0; i < numModes; i++) {
476         (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
477     }
478     return Error::None;
479 }
480 
getConfigs() const481 std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
482 {
483     std::vector<std::shared_ptr<const Config>> configs;
484     for (const auto& element : mConfigs) {
485         configs.emplace_back(element.second);
486     }
487     return configs;
488 }
489 
getName(std::string * outName) const490 Error Display::getName(std::string* outName) const
491 {
492     auto intError = mDevice.mComposer->getDisplayName(mId, outName);
493     return static_cast<Error>(intError);
494 }
495 
getRequests(HWC2::DisplayRequest * outDisplayRequests,std::unordered_map<std::shared_ptr<Layer>,LayerRequest> * outLayerRequests)496 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
497         std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
498                 outLayerRequests)
499 {
500     uint32_t intDisplayRequests;
501     std::vector<Hwc2::Layer> layerIds;
502     std::vector<uint32_t> layerRequests;
503     auto intError = mDevice.mComposer->getDisplayRequests(mId,
504             &intDisplayRequests, &layerIds, &layerRequests);
505     uint32_t numElements = layerIds.size();
506     auto error = static_cast<Error>(intError);
507     if (error != Error::None) {
508         return error;
509     }
510 
511     *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
512     outLayerRequests->clear();
513     outLayerRequests->reserve(numElements);
514     for (uint32_t element = 0; element < numElements; ++element) {
515         auto layer = getLayerById(layerIds[element]);
516         if (layer) {
517             auto layerRequest =
518                     static_cast<LayerRequest>(layerRequests[element]);
519             outLayerRequests->emplace(layer, layerRequest);
520         } else {
521             ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
522                     PRIu64, layerIds[element], mId);
523         }
524     }
525 
526     return Error::None;
527 }
528 
getType(DisplayType * outType) const529 Error Display::getType(DisplayType* outType) const
530 {
531     *outType = mType;
532     return Error::None;
533 }
534 
supportsDoze(bool * outSupport) const535 Error Display::supportsDoze(bool* outSupport) const
536 {
537     bool intSupport = false;
538     auto intError = mDevice.mComposer->getDozeSupport(mId, &intSupport);
539     auto error = static_cast<Error>(intError);
540     if (error != Error::None) {
541         return error;
542     }
543     *outSupport = static_cast<bool>(intSupport);
544     return Error::None;
545 }
546 
getHdrCapabilities(std::unique_ptr<HdrCapabilities> * outCapabilities) const547 Error Display::getHdrCapabilities(
548         std::unique_ptr<HdrCapabilities>* outCapabilities) const
549 {
550     uint32_t numTypes = 0;
551     float maxLuminance = -1.0f;
552     float maxAverageLuminance = -1.0f;
553     float minLuminance = -1.0f;
554     std::vector<Hwc2::Hdr> intTypes;
555     auto intError = mDevice.mComposer->getHdrCapabilities(mId, &intTypes,
556             &maxLuminance, &maxAverageLuminance, &minLuminance);
557     auto error = static_cast<HWC2::Error>(intError);
558 
559     std::vector<int32_t> types;
560     for (auto type : intTypes) {
561         types.push_back(static_cast<int32_t>(type));
562     }
563     numTypes = types.size();
564     if (error != Error::None) {
565         return error;
566     }
567 
568     *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
569             maxLuminance, maxAverageLuminance, minLuminance);
570     return Error::None;
571 }
572 
getReleaseFences(std::unordered_map<std::shared_ptr<Layer>,sp<Fence>> * outFences) const573 Error Display::getReleaseFences(
574         std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
575 {
576     std::vector<Hwc2::Layer> layerIds;
577     std::vector<int> fenceFds;
578     auto intError = mDevice.mComposer->getReleaseFences(mId,
579             &layerIds, &fenceFds);
580     auto error = static_cast<Error>(intError);
581     uint32_t numElements = layerIds.size();
582     if (error != Error::None) {
583         return error;
584     }
585 
586     std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
587     releaseFences.reserve(numElements);
588     for (uint32_t element = 0; element < numElements; ++element) {
589         auto layer = getLayerById(layerIds[element]);
590         if (layer) {
591             sp<Fence> fence(new Fence(fenceFds[element]));
592             releaseFences.emplace(std::move(layer), fence);
593         } else {
594             ALOGE("getReleaseFences: invalid layer %" PRIu64
595                     " found on display %" PRIu64, layerIds[element], mId);
596             for (; element < numElements; ++element) {
597                 close(fenceFds[element]);
598             }
599             return Error::BadLayer;
600         }
601     }
602 
603     *outFences = std::move(releaseFences);
604     return Error::None;
605 }
606 
present(sp<Fence> * outPresentFence)607 Error Display::present(sp<Fence>* outPresentFence)
608 {
609     int32_t presentFenceFd = -1;
610     auto intError = mDevice.mComposer->presentDisplay(mId, &presentFenceFd);
611     auto error = static_cast<Error>(intError);
612     if (error != Error::None) {
613         return error;
614     }
615 
616     *outPresentFence = new Fence(presentFenceFd);
617     return Error::None;
618 }
619 
setActiveConfig(const std::shared_ptr<const Config> & config)620 Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
621 {
622     if (config->getDisplayId() != mId) {
623         ALOGE("setActiveConfig received config %u for the wrong display %"
624                 PRIu64 " (expected %" PRIu64 ")", config->getId(),
625                 config->getDisplayId(), mId);
626         return Error::BadConfig;
627     }
628     auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId());
629     return static_cast<Error>(intError);
630 }
631 
setClientTarget(uint32_t slot,const sp<GraphicBuffer> & target,const sp<Fence> & acquireFence,android_dataspace_t dataspace)632 Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target,
633         const sp<Fence>& acquireFence, android_dataspace_t dataspace)
634 {
635     // TODO: Properly encode client target surface damage
636     int32_t fenceFd = acquireFence->dup();
637     auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
638             fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
639             std::vector<Hwc2::IComposerClient::Rect>());
640     return static_cast<Error>(intError);
641 }
642 
setColorMode(android_color_mode_t mode)643 Error Display::setColorMode(android_color_mode_t mode)
644 {
645     auto intError = mDevice.mComposer->setColorMode(mId,
646             static_cast<Hwc2::ColorMode>(mode));
647     return static_cast<Error>(intError);
648 }
649 
setColorTransform(const android::mat4 & matrix,android_color_transform_t hint)650 Error Display::setColorTransform(const android::mat4& matrix,
651         android_color_transform_t hint)
652 {
653     auto intError = mDevice.mComposer->setColorTransform(mId,
654             matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
655     return static_cast<Error>(intError);
656 }
657 
setOutputBuffer(const sp<GraphicBuffer> & buffer,const sp<Fence> & releaseFence)658 Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
659         const sp<Fence>& releaseFence)
660 {
661     int32_t fenceFd = releaseFence->dup();
662     auto handle = buffer->getNativeBuffer()->handle;
663     auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd);
664     close(fenceFd);
665     return static_cast<Error>(intError);
666 }
667 
setPowerMode(PowerMode mode)668 Error Display::setPowerMode(PowerMode mode)
669 {
670     auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
671     auto intError = mDevice.mComposer->setPowerMode(mId, intMode);
672     return static_cast<Error>(intError);
673 }
674 
setVsyncEnabled(Vsync enabled)675 Error Display::setVsyncEnabled(Vsync enabled)
676 {
677     auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
678     auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled);
679     return static_cast<Error>(intError);
680 }
681 
validate(uint32_t * outNumTypes,uint32_t * outNumRequests)682 Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
683 {
684     uint32_t numTypes = 0;
685     uint32_t numRequests = 0;
686     auto intError = mDevice.mComposer->validateDisplay(mId,
687             &numTypes, &numRequests);
688     auto error = static_cast<Error>(intError);
689     if (error != Error::None && error != Error::HasChanges) {
690         return error;
691     }
692 
693     *outNumTypes = numTypes;
694     *outNumRequests = numRequests;
695     return error;
696 }
697 
presentOrValidate(uint32_t * outNumTypes,uint32_t * outNumRequests,sp<android::Fence> * outPresentFence,uint32_t * state)698 Error Display::presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
699                                  sp<android::Fence>* outPresentFence, uint32_t* state) {
700 
701     uint32_t numTypes = 0;
702     uint32_t numRequests = 0;
703     int32_t presentFenceFd = -1;
704     auto intError = mDevice.mComposer->presentOrValidateDisplay(mId, &numTypes, &numRequests, &presentFenceFd, state);
705     auto error = static_cast<Error>(intError);
706     if (error != Error::None && error != Error::HasChanges) {
707         return error;
708     }
709 
710     if (*state == 1) {
711         *outPresentFence = new Fence(presentFenceFd);
712     }
713 
714     if (*state == 0) {
715         *outNumTypes = numTypes;
716         *outNumRequests = numRequests;
717     }
718     return error;
719 }
720 
discardCommands()721 void Display::discardCommands()
722 {
723     mDevice.mComposer->resetCommands();
724 }
725 
726 // For use by Device
727 
getAttribute(hwc2_config_t configId,Attribute attribute)728 int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
729 {
730     int32_t value = 0;
731     auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId,
732             static_cast<Hwc2::IComposerClient::Attribute>(attribute),
733             &value);
734     auto error = static_cast<Error>(intError);
735     if (error != Error::None) {
736         ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
737                 configId, to_string(attribute).c_str(),
738                 to_string(error).c_str(), intError);
739         return -1;
740     }
741     return value;
742 }
743 
loadConfig(hwc2_config_t configId)744 void Display::loadConfig(hwc2_config_t configId)
745 {
746     ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
747 
748     auto config = Config::Builder(*this, configId)
749             .setWidth(getAttribute(configId, Attribute::Width))
750             .setHeight(getAttribute(configId, Attribute::Height))
751             .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
752             .setDpiX(getAttribute(configId, Attribute::DpiX))
753             .setDpiY(getAttribute(configId, Attribute::DpiY))
754             .build();
755     mConfigs.emplace(configId, std::move(config));
756 }
757 
loadConfigs()758 void Display::loadConfigs()
759 {
760     ALOGV("[%" PRIu64 "] loadConfigs", mId);
761 
762     std::vector<Hwc2::Config> configIds;
763     auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds);
764     auto error = static_cast<Error>(intError);
765     if (error != Error::None) {
766         ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
767                 to_string(error).c_str(), intError);
768         return;
769     }
770 
771     for (auto configId : configIds) {
772         loadConfig(configId);
773     }
774 }
775 
776 // For use by Layer
777 
destroyLayer(hwc2_layer_t layerId)778 void Display::destroyLayer(hwc2_layer_t layerId)
779 {
780     auto intError =mDevice.mComposer->destroyLayer(mId, layerId);
781     auto error = static_cast<Error>(intError);
782     ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
783             " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
784             intError);
785     mLayers.erase(layerId);
786 }
787 
788 // Other Display methods
789 
getLayerById(hwc2_layer_t id) const790 std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
791 {
792     if (mLayers.count(id) == 0) {
793         return nullptr;
794     }
795 
796     auto layer = mLayers.at(id).lock();
797     return layer;
798 }
799 
800 // Layer methods
801 
Layer(const std::shared_ptr<Display> & display,hwc2_layer_t id)802 Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
803   : mDisplay(display),
804     mDisplayId(display->getId()),
805     mDevice(display->getDevice()),
806     mId(id)
807 {
808     ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
809             display->getId());
810 }
811 
~Layer()812 Layer::~Layer()
813 {
814     auto display = mDisplay.lock();
815     if (display) {
816         display->destroyLayer(mId);
817     }
818 }
819 
setCursorPosition(int32_t x,int32_t y)820 Error Layer::setCursorPosition(int32_t x, int32_t y)
821 {
822     auto intError = mDevice.mComposer->setCursorPosition(mDisplayId,
823             mId, x, y);
824     return static_cast<Error>(intError);
825 }
826 
setBuffer(uint32_t slot,const sp<GraphicBuffer> & buffer,const sp<Fence> & acquireFence)827 Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
828         const sp<Fence>& acquireFence)
829 {
830     int32_t fenceFd = acquireFence->dup();
831     auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
832             mId, slot, buffer, fenceFd);
833     return static_cast<Error>(intError);
834 }
835 
setSurfaceDamage(const Region & damage)836 Error Layer::setSurfaceDamage(const Region& damage)
837 {
838     // We encode default full-screen damage as INVALID_RECT upstream, but as 0
839     // rects for HWC
840     Hwc2::Error intError = Hwc2::Error::NONE;
841     if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
842         intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
843                 mId, std::vector<Hwc2::IComposerClient::Rect>());
844     } else {
845         size_t rectCount = 0;
846         auto rectArray = damage.getArray(&rectCount);
847 
848         std::vector<Hwc2::IComposerClient::Rect> hwcRects;
849         for (size_t rect = 0; rect < rectCount; ++rect) {
850             hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
851                     rectArray[rect].right, rectArray[rect].bottom});
852         }
853 
854         intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
855                 mId, hwcRects);
856     }
857 
858     return static_cast<Error>(intError);
859 }
860 
setBlendMode(BlendMode mode)861 Error Layer::setBlendMode(BlendMode mode)
862 {
863     auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
864     auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId,
865             mId, intMode);
866     return static_cast<Error>(intError);
867 }
868 
setColor(hwc_color_t color)869 Error Layer::setColor(hwc_color_t color)
870 {
871     Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
872     auto intError = mDevice.mComposer->setLayerColor(mDisplayId,
873             mId, hwcColor);
874     return static_cast<Error>(intError);
875 }
876 
setCompositionType(Composition type)877 Error Layer::setCompositionType(Composition type)
878 {
879     auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
880     auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId,
881             mId, intType);
882     return static_cast<Error>(intError);
883 }
884 
setDataspace(android_dataspace_t dataspace)885 Error Layer::setDataspace(android_dataspace_t dataspace)
886 {
887     auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
888     auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId,
889             mId, intDataspace);
890     return static_cast<Error>(intError);
891 }
892 
setDisplayFrame(const Rect & frame)893 Error Layer::setDisplayFrame(const Rect& frame)
894 {
895     Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
896         frame.right, frame.bottom};
897     auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId,
898             mId, hwcRect);
899     return static_cast<Error>(intError);
900 }
901 
setPlaneAlpha(float alpha)902 Error Layer::setPlaneAlpha(float alpha)
903 {
904     auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId,
905             mId, alpha);
906     return static_cast<Error>(intError);
907 }
908 
setSidebandStream(const native_handle_t * stream)909 Error Layer::setSidebandStream(const native_handle_t* stream)
910 {
911     if (!mDevice.hasCapability(Capability::SidebandStream)) {
912         ALOGE("Attempted to call setSidebandStream without checking that the "
913                 "device supports sideband streams");
914         return Error::Unsupported;
915     }
916     auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId,
917             mId, stream);
918     return static_cast<Error>(intError);
919 }
920 
setSourceCrop(const FloatRect & crop)921 Error Layer::setSourceCrop(const FloatRect& crop)
922 {
923     Hwc2::IComposerClient::FRect hwcRect{
924         crop.left, crop.top, crop.right, crop.bottom};
925     auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId,
926             mId, hwcRect);
927     return static_cast<Error>(intError);
928 }
929 
setTransform(Transform transform)930 Error Layer::setTransform(Transform transform)
931 {
932     auto intTransform = static_cast<Hwc2::Transform>(transform);
933     auto intError = mDevice.mComposer->setLayerTransform(mDisplayId,
934             mId, intTransform);
935     return static_cast<Error>(intError);
936 }
937 
setVisibleRegion(const Region & region)938 Error Layer::setVisibleRegion(const Region& region)
939 {
940     size_t rectCount = 0;
941     auto rectArray = region.getArray(&rectCount);
942 
943     std::vector<Hwc2::IComposerClient::Rect> hwcRects;
944     for (size_t rect = 0; rect < rectCount; ++rect) {
945         hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
946                 rectArray[rect].right, rectArray[rect].bottom});
947     }
948 
949     auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId,
950             mId, hwcRects);
951     return static_cast<Error>(intError);
952 }
953 
setZOrder(uint32_t z)954 Error Layer::setZOrder(uint32_t z)
955 {
956     auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z);
957     return static_cast<Error>(intError);
958 }
959 
setInfo(uint32_t type,uint32_t appId)960 Error Layer::setInfo(uint32_t type, uint32_t appId)
961 {
962   auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId);
963   return static_cast<Error>(intError);
964 }
965 
966 } // namespace HWC2
967