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