• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 "HWComposer"
21 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
22 
23 #include <inttypes.h>
24 #include <math.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/types.h>
30 
31 #include <utils/Errors.h>
32 #include <utils/misc.h>
33 #include <utils/NativeHandle.h>
34 #include <utils/String8.h>
35 #include <utils/Thread.h>
36 #include <utils/Trace.h>
37 #include <utils/Vector.h>
38 
39 #include <ui/GraphicBuffer.h>
40 
41 #include <hardware/hardware.h>
42 #include <hardware/hwcomposer.h>
43 
44 #include <android/configuration.h>
45 
46 #include <cutils/log.h>
47 #include <cutils/properties.h>
48 
49 #include "HWComposer.h"
50 #include "HWC2On1Adapter.h"
51 #include "HWC2.h"
52 
53 #include "../Layer.h"           // needed only for debugging
54 #include "../SurfaceFlinger.h"
55 
56 namespace android {
57 
58 #define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION
59 
60 // ---------------------------------------------------------------------------
61 
HWComposer(const sp<SurfaceFlinger> & flinger)62 HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
63     : mFlinger(flinger),
64       mAdapter(),
65       mHwcDevice(),
66       mDisplayData(2),
67       mFreeDisplaySlots(),
68       mHwcDisplaySlots(),
69       mCBContext(),
70       mEventHandler(nullptr),
71       mVSyncCounts(),
72       mRemainingHwcVirtualDisplays(0)
73 {
74     for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
75         mLastHwVSync[i] = 0;
76         mVSyncCounts[i] = 0;
77     }
78 
79     loadHwcModule();
80 }
81 
~HWComposer()82 HWComposer::~HWComposer() {}
83 
setEventHandler(EventHandler * handler)84 void HWComposer::setEventHandler(EventHandler* handler)
85 {
86     if (handler == nullptr) {
87         ALOGE("setEventHandler: Rejected attempt to clear handler");
88         return;
89     }
90 
91     bool wasNull = (mEventHandler == nullptr);
92     mEventHandler = handler;
93 
94     if (wasNull) {
95         auto hotplugHook = std::bind(&HWComposer::hotplug, this,
96                 std::placeholders::_1, std::placeholders::_2);
97         mHwcDevice->registerHotplugCallback(hotplugHook);
98         auto invalidateHook = std::bind(&HWComposer::invalidate, this,
99                 std::placeholders::_1);
100         mHwcDevice->registerRefreshCallback(invalidateHook);
101         auto vsyncHook = std::bind(&HWComposer::vsync, this,
102                 std::placeholders::_1, std::placeholders::_2);
103         mHwcDevice->registerVsyncCallback(vsyncHook);
104     }
105 }
106 
107 // Load and prepare the hardware composer module.  Sets mHwc.
loadHwcModule()108 void HWComposer::loadHwcModule()
109 {
110     ALOGV("loadHwcModule");
111 
112     hw_module_t const* module;
113 
114     if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
115         ALOGE("%s module not found, aborting", HWC_HARDWARE_MODULE_ID);
116         abort();
117     }
118 
119     hw_device_t* device = nullptr;
120     int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
121     if (error != 0) {
122         ALOGE("Failed to open HWC device (%s), aborting", strerror(-error));
123         abort();
124     }
125 
126     uint32_t majorVersion = (device->version >> 24) & 0xF;
127     if (majorVersion == 2) {
128         mHwcDevice = std::make_unique<HWC2::Device>(
129                 reinterpret_cast<hwc2_device_t*>(device));
130     } else {
131         mAdapter = std::make_unique<HWC2On1Adapter>(
132                 reinterpret_cast<hwc_composer_device_1_t*>(device));
133         uint8_t minorVersion = mAdapter->getHwc1MinorVersion();
134         if (minorVersion < 1) {
135             ALOGE("Cannot adapt to HWC version %d.%d",
136                     static_cast<int32_t>((minorVersion >> 8) & 0xF),
137                     static_cast<int32_t>(minorVersion & 0xF));
138             abort();
139         }
140         mHwcDevice = std::make_unique<HWC2::Device>(
141                 static_cast<hwc2_device_t*>(mAdapter.get()));
142     }
143 
144     mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
145 }
146 
hasCapability(HWC2::Capability capability) const147 bool HWComposer::hasCapability(HWC2::Capability capability) const
148 {
149     return mHwcDevice->getCapabilities().count(capability) > 0;
150 }
151 
isValidDisplay(int32_t displayId) const152 bool HWComposer::isValidDisplay(int32_t displayId) const {
153     return static_cast<size_t>(displayId) < mDisplayData.size() &&
154             mDisplayData[displayId].hwcDisplay;
155 }
156 
validateChange(HWC2::Composition from,HWC2::Composition to)157 void HWComposer::validateChange(HWC2::Composition from, HWC2::Composition to) {
158     bool valid = true;
159     switch (from) {
160         case HWC2::Composition::Client:
161             valid = false;
162             break;
163         case HWC2::Composition::Device:
164         case HWC2::Composition::SolidColor:
165             valid = (to == HWC2::Composition::Client);
166             break;
167         case HWC2::Composition::Cursor:
168         case HWC2::Composition::Sideband:
169             valid = (to == HWC2::Composition::Client ||
170                     to == HWC2::Composition::Device);
171             break;
172         default:
173             break;
174     }
175 
176     if (!valid) {
177         ALOGE("Invalid layer type change: %s --> %s", to_string(from).c_str(),
178                 to_string(to).c_str());
179     }
180 }
181 
hotplug(const std::shared_ptr<HWC2::Display> & display,HWC2::Connection connected)182 void HWComposer::hotplug(const std::shared_ptr<HWC2::Display>& display,
183         HWC2::Connection connected) {
184     ALOGV("hotplug: %" PRIu64 ", %s", display->getId(),
185             to_string(connected).c_str());
186     int32_t disp = 0;
187     if (!mDisplayData[0].hwcDisplay) {
188         ALOGE_IF(connected != HWC2::Connection::Connected, "Assumed primary"
189                 " display would be connected");
190         mDisplayData[0].hwcDisplay = display;
191         mHwcDisplaySlots[display->getId()] = 0;
192         disp = DisplayDevice::DISPLAY_PRIMARY;
193     } else {
194         // Disconnect is handled through HWComposer::disconnectDisplay via
195         // SurfaceFlinger's onHotplugReceived callback handling
196         if (connected == HWC2::Connection::Connected) {
197             mDisplayData[1].hwcDisplay = display;
198             mHwcDisplaySlots[display->getId()] = 1;
199         }
200         disp = DisplayDevice::DISPLAY_EXTERNAL;
201     }
202     mEventHandler->onHotplugReceived(disp,
203             connected == HWC2::Connection::Connected);
204 }
205 
invalidate(const std::shared_ptr<HWC2::Display> &)206 void HWComposer::invalidate(const std::shared_ptr<HWC2::Display>& /*display*/) {
207     mFlinger->repaintEverything();
208 }
209 
vsync(const std::shared_ptr<HWC2::Display> & display,int64_t timestamp)210 void HWComposer::vsync(const std::shared_ptr<HWC2::Display>& display,
211         int64_t timestamp) {
212     auto displayType = HWC2::DisplayType::Invalid;
213     auto error = display->getType(&displayType);
214     if (error != HWC2::Error::None) {
215         ALOGE("vsync: Failed to determine type of display %" PRIu64,
216                 display->getId());
217         return;
218     }
219 
220     if (displayType == HWC2::DisplayType::Virtual) {
221         ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
222                 display->getId());
223         return;
224     }
225 
226     if (mHwcDisplaySlots.count(display->getId()) == 0) {
227         ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
228                 display->getId());
229         return;
230     }
231 
232     int32_t disp = mHwcDisplaySlots[display->getId()];
233     {
234         Mutex::Autolock _l(mLock);
235 
236         // There have been reports of HWCs that signal several vsync events
237         // with the same timestamp when turning the display off and on. This
238         // is a bug in the HWC implementation, but filter the extra events
239         // out here so they don't cause havoc downstream.
240         if (timestamp == mLastHwVSync[disp]) {
241             ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
242                     timestamp);
243             return;
244         }
245 
246         mLastHwVSync[disp] = timestamp;
247     }
248 
249     char tag[16];
250     snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
251     ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
252 
253     mEventHandler->onVSyncReceived(disp, timestamp);
254 }
255 
allocateVirtualDisplay(uint32_t width,uint32_t height,android_pixel_format_t * format,int32_t * outId)256 status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
257         android_pixel_format_t* format, int32_t *outId) {
258     if (mRemainingHwcVirtualDisplays == 0) {
259         ALOGE("allocateVirtualDisplay: No remaining virtual displays");
260         return NO_MEMORY;
261     }
262 
263     std::shared_ptr<HWC2::Display> display;
264     auto error = mHwcDevice->createVirtualDisplay(width, height, format,
265             &display);
266     if (error != HWC2::Error::None) {
267         ALOGE("allocateVirtualDisplay: Failed to create HWC virtual display");
268         return NO_MEMORY;
269     }
270 
271     size_t displaySlot = 0;
272     if (!mFreeDisplaySlots.empty()) {
273         displaySlot = *mFreeDisplaySlots.begin();
274         mFreeDisplaySlots.erase(displaySlot);
275     } else if (mDisplayData.size() < INT32_MAX) {
276         // Don't bother allocating a slot larger than we can return
277         displaySlot = mDisplayData.size();
278         mDisplayData.resize(displaySlot + 1);
279     } else {
280         ALOGE("allocateVirtualDisplay: Unable to allocate a display slot");
281         return NO_MEMORY;
282     }
283 
284     mDisplayData[displaySlot].hwcDisplay = display;
285 
286     --mRemainingHwcVirtualDisplays;
287     *outId = static_cast<int32_t>(displaySlot);
288 
289     return NO_ERROR;
290 }
291 
createLayer(int32_t displayId)292 std::shared_ptr<HWC2::Layer> HWComposer::createLayer(int32_t displayId) {
293     if (!isValidDisplay(displayId)) {
294         ALOGE("Failed to create layer on invalid display %d", displayId);
295         return nullptr;
296     }
297     auto display = mDisplayData[displayId].hwcDisplay;
298     std::shared_ptr<HWC2::Layer> layer;
299     auto error = display->createLayer(&layer);
300     if (error != HWC2::Error::None) {
301         ALOGE("Failed to create layer on display %d: %s (%d)", displayId,
302                 to_string(error).c_str(), static_cast<int32_t>(error));
303         return nullptr;
304     }
305     return layer;
306 }
307 
getRefreshTimestamp(int32_t disp) const308 nsecs_t HWComposer::getRefreshTimestamp(int32_t disp) const {
309     // this returns the last refresh timestamp.
310     // if the last one is not available, we estimate it based on
311     // the refresh period and whatever closest timestamp we have.
312     Mutex::Autolock _l(mLock);
313     nsecs_t now = systemTime(CLOCK_MONOTONIC);
314     auto vsyncPeriod = getActiveConfig(disp)->getVsyncPeriod();
315     return now - ((now - mLastHwVSync[disp]) % vsyncPeriod);
316 }
317 
isConnected(int32_t disp) const318 bool HWComposer::isConnected(int32_t disp) const {
319     if (!isValidDisplay(disp)) {
320         ALOGE("isConnected: Attempted to access invalid display %d", disp);
321         return false;
322     }
323     return mDisplayData[disp].hwcDisplay->isConnected();
324 }
325 
326 std::vector<std::shared_ptr<const HWC2::Display::Config>>
getConfigs(int32_t displayId) const327         HWComposer::getConfigs(int32_t displayId) const {
328     if (!isValidDisplay(displayId)) {
329         ALOGE("getConfigs: Attempted to access invalid display %d", displayId);
330         return {};
331     }
332     auto& displayData = mDisplayData[displayId];
333     auto configs = mDisplayData[displayId].hwcDisplay->getConfigs();
334     if (displayData.configMap.empty()) {
335         for (size_t i = 0; i < configs.size(); ++i) {
336             displayData.configMap[i] = configs[i];
337         }
338     }
339     return configs;
340 }
341 
342 std::shared_ptr<const HWC2::Display::Config>
getActiveConfig(int32_t displayId) const343         HWComposer::getActiveConfig(int32_t displayId) const {
344     if (!isValidDisplay(displayId)) {
345         ALOGE("getActiveConfigs: Attempted to access invalid display %d",
346                 displayId);
347         return nullptr;
348     }
349     std::shared_ptr<const HWC2::Display::Config> config;
350     auto error = mDisplayData[displayId].hwcDisplay->getActiveConfig(&config);
351     if (error == HWC2::Error::BadConfig) {
352         ALOGV("getActiveConfig: No config active, returning null");
353         return nullptr;
354     } else if (error != HWC2::Error::None) {
355         ALOGE("getActiveConfig failed for display %d: %s (%d)", displayId,
356                 to_string(error).c_str(), static_cast<int32_t>(error));
357         return nullptr;
358     } else if (!config) {
359         ALOGE("getActiveConfig returned an unknown config for display %d",
360                 displayId);
361         return nullptr;
362     }
363 
364     return config;
365 }
366 
getColorModes(int32_t displayId) const367 std::vector<android_color_mode_t> HWComposer::getColorModes(int32_t displayId) const {
368     std::vector<android_color_mode_t> modes;
369 
370     if (!isValidDisplay(displayId)) {
371         ALOGE("getColorModes: Attempted to access invalid display %d",
372                 displayId);
373         return modes;
374     }
375     const std::shared_ptr<HWC2::Display>& hwcDisplay =
376             mDisplayData[displayId].hwcDisplay;
377 
378     auto error = hwcDisplay->getColorModes(&modes);
379     if (error != HWC2::Error::None) {
380         ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
381                 to_string(error).c_str(), static_cast<int32_t>(error));
382         return std::vector<android_color_mode_t>();
383     }
384 
385     return modes;
386 }
387 
setActiveColorMode(int32_t displayId,android_color_mode_t mode)388 status_t HWComposer::setActiveColorMode(int32_t displayId, android_color_mode_t mode) {
389     if (!isValidDisplay(displayId)) {
390         ALOGE("setActiveColorMode: Display %d is not valid", displayId);
391         return BAD_INDEX;
392     }
393 
394     auto& displayData = mDisplayData[displayId];
395     auto error = displayData.hwcDisplay->setColorMode(mode);
396     if (error != HWC2::Error::None) {
397         ALOGE("setActiveConfig: Failed to set color mode %d on display %d: "
398                 "%s (%d)", mode, displayId, to_string(error).c_str(),
399                 static_cast<int32_t>(error));
400         return UNKNOWN_ERROR;
401     }
402 
403     return NO_ERROR;
404 }
405 
406 
setVsyncEnabled(int32_t disp,HWC2::Vsync enabled)407 void HWComposer::setVsyncEnabled(int32_t disp, HWC2::Vsync enabled) {
408     if (disp < 0 || disp >= HWC_DISPLAY_VIRTUAL) {
409         ALOGD("setVsyncEnabled: Ignoring for virtual display %d", disp);
410         return;
411     }
412 
413     if (!isValidDisplay(disp)) {
414         ALOGE("setVsyncEnabled: Attempted to access invalid display %d", disp);
415         return;
416     }
417 
418     // NOTE: we use our own internal lock here because we have to call
419     // into the HWC with the lock held, and we want to make sure
420     // that even if HWC blocks (which it shouldn't), it won't
421     // affect other threads.
422     Mutex::Autolock _l(mVsyncLock);
423     auto& displayData = mDisplayData[disp];
424     if (enabled != displayData.vsyncEnabled) {
425         ATRACE_CALL();
426         auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
427         if (error == HWC2::Error::None) {
428             displayData.vsyncEnabled = enabled;
429 
430             char tag[16];
431             snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", disp);
432             ATRACE_INT(tag, enabled == HWC2::Vsync::Enable ? 1 : 0);
433         } else {
434             ALOGE("setVsyncEnabled: Failed to set vsync to %s on %d/%" PRIu64
435                     ": %s (%d)", to_string(enabled).c_str(), disp,
436                     mDisplayData[disp].hwcDisplay->getId(),
437                     to_string(error).c_str(), static_cast<int32_t>(error));
438         }
439     }
440 }
441 
setClientTarget(int32_t displayId,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & target,android_dataspace_t dataspace)442 status_t HWComposer::setClientTarget(int32_t displayId,
443         const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
444         android_dataspace_t dataspace) {
445     if (!isValidDisplay(displayId)) {
446         return BAD_INDEX;
447     }
448 
449     ALOGV("setClientTarget for display %d", displayId);
450     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
451     buffer_handle_t handle = nullptr;
452     if ((target != nullptr) && target->getNativeBuffer()) {
453         handle = target->getNativeBuffer()->handle;
454     }
455     auto error = hwcDisplay->setClientTarget(handle, acquireFence, dataspace);
456     if (error != HWC2::Error::None) {
457         ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
458                 to_string(error).c_str(), static_cast<int32_t>(error));
459         return BAD_VALUE;
460     }
461 
462     return NO_ERROR;
463 }
464 
prepare(DisplayDevice & displayDevice)465 status_t HWComposer::prepare(DisplayDevice& displayDevice) {
466     ATRACE_CALL();
467 
468     Mutex::Autolock _l(mDisplayLock);
469     auto displayId = displayDevice.getHwcDisplayId();
470     if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
471         ALOGV("Skipping HWComposer prepare for non-HWC display");
472         return NO_ERROR;
473     }
474     if (!isValidDisplay(displayId)) {
475         return BAD_INDEX;
476     }
477 
478     auto& displayData = mDisplayData[displayId];
479     auto& hwcDisplay = displayData.hwcDisplay;
480     if (!hwcDisplay->isConnected()) {
481         return NO_ERROR;
482     }
483 
484     uint32_t numTypes = 0;
485     uint32_t numRequests = 0;
486     auto error = hwcDisplay->validate(&numTypes, &numRequests);
487     if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
488         ALOGE("prepare: validate failed for display %d: %s (%d)", displayId,
489                 to_string(error).c_str(), static_cast<int32_t>(error));
490         return BAD_INDEX;
491     }
492 
493     std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::Composition>
494         changedTypes;
495     changedTypes.reserve(numTypes);
496     error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
497     if (error != HWC2::Error::None) {
498         ALOGE("prepare: getChangedCompositionTypes failed on display %d: "
499                 "%s (%d)", displayId, to_string(error).c_str(),
500                 static_cast<int32_t>(error));
501         return BAD_INDEX;
502     }
503 
504 
505     displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
506     std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::LayerRequest>
507         layerRequests;
508     layerRequests.reserve(numRequests);
509     error = hwcDisplay->getRequests(&displayData.displayRequests,
510             &layerRequests);
511     if (error != HWC2::Error::None) {
512         ALOGE("prepare: getRequests failed on display %d: %s (%d)", displayId,
513                 to_string(error).c_str(), static_cast<int32_t>(error));
514         return BAD_INDEX;
515     }
516 
517     displayData.hasClientComposition = false;
518     displayData.hasDeviceComposition = false;
519     for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) {
520         auto hwcLayer = layer->getHwcLayer(displayId);
521 
522         if (changedTypes.count(hwcLayer) != 0) {
523             // We pass false so we only update our state and don't call back
524             // into the HWC device
525             validateChange(layer->getCompositionType(displayId),
526                     changedTypes[hwcLayer]);
527             layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
528         }
529 
530         switch (layer->getCompositionType(displayId)) {
531             case HWC2::Composition::Client:
532                 displayData.hasClientComposition = true;
533                 break;
534             case HWC2::Composition::Device:
535             case HWC2::Composition::SolidColor:
536             case HWC2::Composition::Cursor:
537             case HWC2::Composition::Sideband:
538                 displayData.hasDeviceComposition = true;
539                 break;
540             default:
541                 break;
542         }
543 
544         if (layerRequests.count(hwcLayer) != 0 &&
545                 layerRequests[hwcLayer] ==
546                         HWC2::LayerRequest::ClearClientTarget) {
547             layer->setClearClientTarget(displayId, true);
548         } else {
549             if (layerRequests.count(hwcLayer) != 0) {
550                 ALOGE("prepare: Unknown layer request: %s",
551                         to_string(layerRequests[hwcLayer]).c_str());
552             }
553             layer->setClearClientTarget(displayId, false);
554         }
555     }
556 
557     error = hwcDisplay->acceptChanges();
558     if (error != HWC2::Error::None) {
559         ALOGE("prepare: acceptChanges failed: %s", to_string(error).c_str());
560         return BAD_INDEX;
561     }
562 
563     return NO_ERROR;
564 }
565 
hasDeviceComposition(int32_t displayId) const566 bool HWComposer::hasDeviceComposition(int32_t displayId) const {
567     if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
568         // Displays without a corresponding HWC display are never composed by
569         // the device
570         return false;
571     }
572     if (!isValidDisplay(displayId)) {
573         ALOGE("hasDeviceComposition: Invalid display %d", displayId);
574         return false;
575     }
576     return mDisplayData[displayId].hasDeviceComposition;
577 }
578 
hasClientComposition(int32_t displayId) const579 bool HWComposer::hasClientComposition(int32_t displayId) const {
580     if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
581         // Displays without a corresponding HWC display are always composed by
582         // the client
583         return true;
584     }
585     if (!isValidDisplay(displayId)) {
586         ALOGE("hasClientComposition: Invalid display %d", displayId);
587         return true;
588     }
589     return mDisplayData[displayId].hasClientComposition;
590 }
591 
getRetireFence(int32_t displayId) const592 sp<Fence> HWComposer::getRetireFence(int32_t displayId) const {
593     if (!isValidDisplay(displayId)) {
594         ALOGE("getRetireFence failed for invalid display %d", displayId);
595         return Fence::NO_FENCE;
596     }
597     return mDisplayData[displayId].lastRetireFence;
598 }
599 
getLayerReleaseFence(int32_t displayId,const std::shared_ptr<HWC2::Layer> & layer) const600 sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
601         const std::shared_ptr<HWC2::Layer>& layer) const {
602     if (!isValidDisplay(displayId)) {
603         ALOGE("getLayerReleaseFence: Invalid display");
604         return Fence::NO_FENCE;
605     }
606     auto displayFences = mDisplayData[displayId].releaseFences;
607     if (displayFences.count(layer) == 0) {
608         ALOGV("getLayerReleaseFence: Release fence not found");
609         return Fence::NO_FENCE;
610     }
611     return displayFences[layer];
612 }
613 
commit(int32_t displayId)614 status_t HWComposer::commit(int32_t displayId) {
615     ATRACE_CALL();
616 
617     if (!isValidDisplay(displayId)) {
618         return BAD_INDEX;
619     }
620 
621     auto& displayData = mDisplayData[displayId];
622     auto& hwcDisplay = displayData.hwcDisplay;
623     auto error = hwcDisplay->present(&displayData.lastRetireFence);
624     if (error != HWC2::Error::None) {
625         ALOGE("commit: present failed for display %d: %s (%d)", displayId,
626                 to_string(error).c_str(), static_cast<int32_t>(error));
627         return UNKNOWN_ERROR;
628     }
629 
630     std::unordered_map<std::shared_ptr<HWC2::Layer>, sp<Fence>> releaseFences;
631     error = hwcDisplay->getReleaseFences(&releaseFences);
632     if (error != HWC2::Error::None) {
633         ALOGE("commit: Failed to get release fences for display %d: %s (%d)",
634                 displayId, to_string(error).c_str(),
635                 static_cast<int32_t>(error));
636         return UNKNOWN_ERROR;
637     }
638 
639     displayData.releaseFences = std::move(releaseFences);
640 
641     return NO_ERROR;
642 }
643 
setPowerMode(int32_t displayId,int32_t intMode)644 status_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) {
645     ALOGV("setPowerMode(%d, %d)", displayId, intMode);
646     if (!isValidDisplay(displayId)) {
647         ALOGE("setPowerMode: Bad display");
648         return BAD_INDEX;
649     }
650     if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
651         ALOGE("setPowerMode: Virtual display %d passed in, returning",
652                 displayId);
653         return BAD_INDEX;
654     }
655 
656     auto mode = static_cast<HWC2::PowerMode>(intMode);
657     if (mode == HWC2::PowerMode::Off) {
658         setVsyncEnabled(displayId, HWC2::Vsync::Disable);
659     }
660 
661     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
662     switch (mode) {
663         case HWC2::PowerMode::Off:
664         case HWC2::PowerMode::On:
665             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
666             {
667                 auto error = hwcDisplay->setPowerMode(mode);
668                 if (error != HWC2::Error::None) {
669                     ALOGE("setPowerMode: Unable to set power mode %s for "
670                             "display %d: %s (%d)", to_string(mode).c_str(),
671                             displayId, to_string(error).c_str(),
672                             static_cast<int32_t>(error));
673                 }
674             }
675             break;
676         case HWC2::PowerMode::Doze:
677         case HWC2::PowerMode::DozeSuspend:
678             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
679             {
680                 bool supportsDoze = false;
681                 auto error = hwcDisplay->supportsDoze(&supportsDoze);
682                 if (error != HWC2::Error::None) {
683                     ALOGE("setPowerMode: Unable to query doze support for "
684                             "display %d: %s (%d)", displayId,
685                             to_string(error).c_str(),
686                             static_cast<int32_t>(error));
687                 }
688                 if (!supportsDoze) {
689                     mode = HWC2::PowerMode::On;
690                 }
691 
692                 error = hwcDisplay->setPowerMode(mode);
693                 if (error != HWC2::Error::None) {
694                     ALOGE("setPowerMode: Unable to set power mode %s for "
695                             "display %d: %s (%d)", to_string(mode).c_str(),
696                             displayId, to_string(error).c_str(),
697                             static_cast<int32_t>(error));
698                 }
699             }
700             break;
701         default:
702             ALOGV("setPowerMode: Not calling HWC");
703             break;
704     }
705 
706     return NO_ERROR;
707 }
708 
setActiveConfig(int32_t displayId,size_t configId)709 status_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) {
710     if (!isValidDisplay(displayId)) {
711         ALOGE("setActiveConfig: Display %d is not valid", displayId);
712         return BAD_INDEX;
713     }
714 
715     auto& displayData = mDisplayData[displayId];
716     if (displayData.configMap.count(configId) == 0) {
717         ALOGE("setActiveConfig: Invalid config %zd", configId);
718         return BAD_INDEX;
719     }
720 
721     auto error = displayData.hwcDisplay->setActiveConfig(
722             displayData.configMap[configId]);
723     if (error != HWC2::Error::None) {
724         ALOGE("setActiveConfig: Failed to set config %zu on display %d: "
725                 "%s (%d)", configId, displayId, to_string(error).c_str(),
726                 static_cast<int32_t>(error));
727         return UNKNOWN_ERROR;
728     }
729 
730     return NO_ERROR;
731 }
732 
setColorTransform(int32_t displayId,const mat4 & transform)733 status_t HWComposer::setColorTransform(int32_t displayId,
734         const mat4& transform) {
735     if (!isValidDisplay(displayId)) {
736         ALOGE("setColorTransform: Display %d is not valid", displayId);
737         return BAD_INDEX;
738     }
739 
740     auto& displayData = mDisplayData[displayId];
741     bool isIdentity = transform == mat4();
742     auto error = displayData.hwcDisplay->setColorTransform(transform,
743             isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
744             HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
745     if (error != HWC2::Error::None) {
746         ALOGE("setColorTransform: Failed to set transform on display %d: "
747                 "%s (%d)", displayId, to_string(error).c_str(),
748                 static_cast<int32_t>(error));
749         return UNKNOWN_ERROR;
750     }
751 
752     return NO_ERROR;
753 }
754 
disconnectDisplay(int displayId)755 void HWComposer::disconnectDisplay(int displayId) {
756     LOG_ALWAYS_FATAL_IF(displayId < 0);
757     auto& displayData = mDisplayData[displayId];
758 
759     auto displayType = HWC2::DisplayType::Invalid;
760     auto error = displayData.hwcDisplay->getType(&displayType);
761     if (error != HWC2::Error::None) {
762         ALOGE("disconnectDisplay: Failed to determine type of display %d",
763                 displayId);
764         return;
765     }
766 
767     // If this was a virtual display, add its slot back for reuse by future
768     // virtual displays
769     if (displayType == HWC2::DisplayType::Virtual) {
770         mFreeDisplaySlots.insert(displayId);
771         ++mRemainingHwcVirtualDisplays;
772     }
773 
774     auto hwcId = displayData.hwcDisplay->getId();
775     mHwcDisplaySlots.erase(hwcId);
776     displayData.reset();
777 }
778 
setOutputBuffer(int32_t displayId,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & buffer)779 status_t HWComposer::setOutputBuffer(int32_t displayId,
780         const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
781     if (!isValidDisplay(displayId)) {
782         ALOGE("setOutputBuffer: Display %d is not valid", displayId);
783         return BAD_INDEX;
784     }
785 
786     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
787     auto displayType = HWC2::DisplayType::Invalid;
788     auto error = hwcDisplay->getType(&displayType);
789     if (error != HWC2::Error::None) {
790         ALOGE("setOutputBuffer: Failed to determine type of display %d",
791                 displayId);
792         return NAME_NOT_FOUND;
793     }
794 
795     if (displayType != HWC2::DisplayType::Virtual) {
796         ALOGE("setOutputBuffer: Display %d is not virtual", displayId);
797         return INVALID_OPERATION;
798     }
799 
800     error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
801     if (error != HWC2::Error::None) {
802         ALOGE("setOutputBuffer: Failed to set buffer on display %d: %s (%d)",
803                 displayId, to_string(error).c_str(),
804                 static_cast<int32_t>(error));
805         return UNKNOWN_ERROR;
806     }
807 
808     return NO_ERROR;
809 }
810 
clearReleaseFences(int32_t displayId)811 void HWComposer::clearReleaseFences(int32_t displayId) {
812     if (!isValidDisplay(displayId)) {
813         ALOGE("clearReleaseFences: Display %d is not valid", displayId);
814         return;
815     }
816     mDisplayData[displayId].releaseFences.clear();
817 }
818 
getHdrCapabilities(int32_t displayId)819 std::unique_ptr<HdrCapabilities> HWComposer::getHdrCapabilities(
820         int32_t displayId) {
821     if (!isValidDisplay(displayId)) {
822         ALOGE("getHdrCapabilities: Display %d is not valid", displayId);
823         return nullptr;
824     }
825 
826     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
827     std::unique_ptr<HdrCapabilities> capabilities;
828     auto error = hwcDisplay->getHdrCapabilities(&capabilities);
829     if (error != HWC2::Error::None) {
830         ALOGE("getOutputCapabilities: Failed to get capabilities on display %d:"
831                 " %s (%d)", displayId, to_string(error).c_str(),
832                 static_cast<int32_t>(error));
833         return nullptr;
834     }
835 
836     return capabilities;
837 }
838 
839 // Converts a PixelFormat to a human-readable string.  Max 11 chars.
840 // (Could use a table of prefab String8 objects.)
841 /*
842 static String8 getFormatStr(PixelFormat format) {
843     switch (format) {
844     case PIXEL_FORMAT_RGBA_8888:    return String8("RGBA_8888");
845     case PIXEL_FORMAT_RGBX_8888:    return String8("RGBx_8888");
846     case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
847     case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
848     case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
849     case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
850                                     return String8("ImplDef");
851     default:
852         String8 result;
853         result.appendFormat("? %08x", format);
854         return result;
855     }
856 }
857 */
858 
dump(String8 & result) const859 void HWComposer::dump(String8& result) const {
860     // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
861     // all the state going into the layers. This is probably better done in
862     // Layer itself, but it's going to take a bit of work to get there.
863     result.append(mHwcDevice->dump().c_str());
864 }
865 
866 // ---------------------------------------------------------------------------
867 
DisplayData()868 HWComposer::DisplayData::DisplayData()
869   : hasClientComposition(false),
870     hasDeviceComposition(false),
871     hwcDisplay(),
872     lastRetireFence(Fence::NO_FENCE),
873     outbufHandle(nullptr),
874     outbufAcquireFence(Fence::NO_FENCE),
875     vsyncEnabled(HWC2::Vsync::Disable) {
876     ALOGV("Created new DisplayData");
877 }
878 
~DisplayData()879 HWComposer::DisplayData::~DisplayData() {
880 }
881 
reset()882 void HWComposer::DisplayData::reset() {
883     ALOGV("DisplayData reset");
884     *this = DisplayData();
885 }
886 
887 // ---------------------------------------------------------------------------
888 }; // namespace android
889