blob: 1bbf039b7528d7c4099d6d61510270adfe2824e4 [file] [log] [blame]
Mathias Agopiana350ff92010-08-10 17:14:02 -07001/*
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
Dan Stoza9e56aa02015-11-02 13:00:03 -080017// #define LOG_NDEBUG 0
18
19#undef LOG_TAG
20#define LOG_TAG "HWComposer"
Mathias Agopian2965b262012-04-08 15:13:32 -070021#define ATRACE_TAG ATRACE_TAG_GRAPHICS
22
Mark Salyzyn92dc3fc2014-03-12 13:12:44 -070023#include <inttypes.h>
24#include <math.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070025#include <stdint.h>
Mathias Agopianf1352df2010-08-11 17:31:33 -070026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070029#include <sys/types.h>
30
31#include <utils/Errors.h>
Mathias Agopianda27af92012-09-13 18:17:13 -070032#include <utils/misc.h>
Jesse Hall399184a2014-03-03 15:42:54 -080033#include <utils/NativeHandle.h>
Mathias Agopian83727852010-09-23 18:13:21 -070034#include <utils/String8.h>
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070035#include <utils/Thread.h>
Mathias Agopian2965b262012-04-08 15:13:32 -070036#include <utils/Trace.h>
Mathias Agopian22da60c2011-09-09 00:49:11 -070037#include <utils/Vector.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070038
Mathias Agopian921e6ac2012-07-23 23:11:29 -070039#include <ui/GraphicBuffer.h>
40
Mathias Agopiana350ff92010-08-10 17:14:02 -070041#include <hardware/hardware.h>
Mathias Agopian3eb38cb2012-04-03 22:09:52 -070042#include <hardware/hwcomposer.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070043
Jesse Hall1c569c42013-04-05 13:44:52 -070044#include <android/configuration.h>
45
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -070046#include <cutils/properties.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070047#include <log/log.h>
Mathias Agopiana350ff92010-08-10 17:14:02 -070048
Mathias Agopiana350ff92010-08-10 17:14:02 -070049#include "HWComposer.h"
Dan Stoza9e56aa02015-11-02 13:00:03 -080050#include "HWC2.h"
Hendrik Wagenaar87670ff2017-02-01 12:10:46 -080051#include "ComposerHal.h"
Mathias Agopian33ceeb32013-04-01 16:54:58 -070052
53#include "../Layer.h" // needed only for debugging
54#include "../SurfaceFlinger.h"
Mathias Agopiana350ff92010-08-10 17:14:02 -070055
56namespace android {
Jesse Hall5880cc52012-06-05 23:40:32 -070057
Jesse Hall72960512013-01-10 16:19:56 -080058#define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION
Jesse Hall9eb1eb52012-08-29 10:39:38 -070059
Mathias Agopiana350ff92010-08-10 17:14:02 -070060// ---------------------------------------------------------------------------
61
Lloyd Piquea822d522017-12-20 16:42:57 -080062HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer)
63 : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}
Mathias Agopianbef42c52013-08-21 17:45:46 -070064
Lloyd Piquea822d522017-12-20 16:42:57 -080065HWComposer::~HWComposer() = default;
Dan Stoza9e56aa02015-11-02 13:00:03 -080066
Steven Thomas94e35b92017-07-26 18:48:28 -070067void HWComposer::registerCallback(HWC2::ComposerCallback* callback,
68 int32_t sequenceId) {
69 mHwcDevice->registerCallback(callback, sequenceId);
Dan Stoza9e56aa02015-11-02 13:00:03 -080070}
71
Dan Stoza9f26a9c2016-06-22 14:51:09 -070072bool HWComposer::hasCapability(HWC2::Capability capability) const
73{
74 return mHwcDevice->getCapabilities().count(capability) > 0;
75}
76
Dan Stoza9e56aa02015-11-02 13:00:03 -080077bool HWComposer::isValidDisplay(int32_t displayId) const {
78 return static_cast<size_t>(displayId) < mDisplayData.size() &&
79 mDisplayData[displayId].hwcDisplay;
80}
81
82void HWComposer::validateChange(HWC2::Composition from, HWC2::Composition to) {
83 bool valid = true;
84 switch (from) {
85 case HWC2::Composition::Client:
86 valid = false;
87 break;
88 case HWC2::Composition::Device:
89 case HWC2::Composition::SolidColor:
90 valid = (to == HWC2::Composition::Client);
91 break;
92 case HWC2::Composition::Cursor:
93 case HWC2::Composition::Sideband:
94 valid = (to == HWC2::Composition::Client ||
95 to == HWC2::Composition::Device);
96 break;
97 default:
98 break;
99 }
100
101 if (!valid) {
102 ALOGE("Invalid layer type change: %s --> %s", to_string(from).c_str(),
103 to_string(to).c_str());
Andy McFaddenb0d1dd32012-09-10 14:08:09 -0700104 }
105}
106
Lloyd Pique715a2c12017-12-14 17:18:08 -0800107void HWComposer::onHotplug(hwc2_display_t displayId, int32_t displayType,
Steven Thomas94e35b92017-07-26 18:48:28 -0700108 HWC2::Connection connection) {
Lloyd Pique715a2c12017-12-14 17:18:08 -0800109 if (displayType >= HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
110 ALOGE("Invalid display type of %d", displayType);
111 return;
112 }
113
114 ALOGV("hotplug: %" PRIu64 ", %s %s", displayId,
115 displayType == DisplayDevice::DISPLAY_PRIMARY ? "primary" : "external",
Steven Thomas94e35b92017-07-26 18:48:28 -0700116 to_string(connection).c_str());
117 mHwcDevice->onHotplug(displayId, connection);
Lloyd Pique715a2c12017-12-14 17:18:08 -0800118 // Disconnect is handled through HWComposer::disconnectDisplay via
119 // SurfaceFlinger's onHotplugReceived callback handling
120 if (connection == HWC2::Connection::Connected) {
121 mDisplayData[displayType].hwcDisplay = mHwcDevice->getDisplayById(displayId);
122 mHwcDisplaySlots[displayId] = displayType;
Andy McFaddenb0d1dd32012-09-10 14:08:09 -0700123 }
Andy McFaddenb0d1dd32012-09-10 14:08:09 -0700124}
125
Steven Thomas94e35b92017-07-26 18:48:28 -0700126bool HWComposer::onVsync(hwc2_display_t displayId, int64_t timestamp,
127 int32_t* outDisplay) {
128 auto display = mHwcDevice->getDisplayById(displayId);
129 if (!display) {
130 ALOGE("onVsync Failed to find display %" PRIu64, displayId);
131 return false;
132 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800133 auto displayType = HWC2::DisplayType::Invalid;
134 auto error = display->getType(&displayType);
135 if (error != HWC2::Error::None) {
Steven Thomas94e35b92017-07-26 18:48:28 -0700136 ALOGE("onVsync: Failed to determine type of display %" PRIu64,
Dan Stoza9e56aa02015-11-02 13:00:03 -0800137 display->getId());
Steven Thomas94e35b92017-07-26 18:48:28 -0700138 return false;
Jesse Hall1bd20e02012-08-29 10:47:52 -0700139 }
Jesse Hall1bd20e02012-08-29 10:47:52 -0700140
Dan Stoza9e56aa02015-11-02 13:00:03 -0800141 if (displayType == HWC2::DisplayType::Virtual) {
142 ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
143 display->getId());
Steven Thomas94e35b92017-07-26 18:48:28 -0700144 return false;
Jesse Hall1bd20e02012-08-29 10:47:52 -0700145 }
146
Dan Stoza9e56aa02015-11-02 13:00:03 -0800147 if (mHwcDisplaySlots.count(display->getId()) == 0) {
148 ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
149 display->getId());
Steven Thomas94e35b92017-07-26 18:48:28 -0700150 return false;
Jesse Hall1bd20e02012-08-29 10:47:52 -0700151 }
152
Dan Stoza9e56aa02015-11-02 13:00:03 -0800153 int32_t disp = mHwcDisplaySlots[display->getId()];
154 {
155 Mutex::Autolock _l(mLock);
Jesse Hall1bd20e02012-08-29 10:47:52 -0700156
Dan Stoza9e56aa02015-11-02 13:00:03 -0800157 // There have been reports of HWCs that signal several vsync events
158 // with the same timestamp when turning the display off and on. This
159 // is a bug in the HWC implementation, but filter the extra events
160 // out here so they don't cause havoc downstream.
161 if (timestamp == mLastHwVSync[disp]) {
162 ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
163 timestamp);
Steven Thomas94e35b92017-07-26 18:48:28 -0700164 return false;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800165 }
166
167 mLastHwVSync[disp] = timestamp;
Jesse Hall1c569c42013-04-05 13:44:52 -0700168 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800169
Steven Thomas94e35b92017-07-26 18:48:28 -0700170 if (outDisplay) {
171 *outDisplay = disp;
172 }
173
Dan Stoza9e56aa02015-11-02 13:00:03 -0800174 char tag[16];
175 snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
176 ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
177
Steven Thomas94e35b92017-07-26 18:48:28 -0700178 return true;
Jesse Hall1c569c42013-04-05 13:44:52 -0700179}
180
Dan Stoza9e56aa02015-11-02 13:00:03 -0800181status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700182 ui::PixelFormat* format, int32_t *outId) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800183 if (mRemainingHwcVirtualDisplays == 0) {
184 ALOGE("allocateVirtualDisplay: No remaining virtual displays");
Mathias Agopiane60b0682012-08-21 23:34:09 -0700185 return NO_MEMORY;
186 }
Mathias Agopiane60b0682012-08-21 23:34:09 -0700187
Fabien Sanglardc8e387e2017-03-10 10:30:28 -0800188 if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
189 (width > SurfaceFlinger::maxVirtualDisplaySize ||
190 height > SurfaceFlinger::maxVirtualDisplaySize)) {
Fabien Sanglarde29055f2017-03-08 11:36:46 -0800191 ALOGE("createVirtualDisplay: Can't create a virtual display with"
Fabien Sanglardc8e387e2017-03-10 10:30:28 -0800192 " a dimension > %" PRIu64 " (tried %u x %u)",
193 SurfaceFlinger::maxVirtualDisplaySize, width, height);
Fabien Sanglarde29055f2017-03-08 11:36:46 -0800194 return INVALID_OPERATION;
195 }
196
Steven Thomas94e35b92017-07-26 18:48:28 -0700197 HWC2::Display* display;
Dan Stoza5cf424b2016-05-20 14:02:39 -0700198 auto error = mHwcDevice->createVirtualDisplay(width, height, format,
199 &display);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800200 if (error != HWC2::Error::None) {
201 ALOGE("allocateVirtualDisplay: Failed to create HWC virtual display");
202 return NO_MEMORY;
Mathias Agopiane60b0682012-08-21 23:34:09 -0700203 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800204
205 size_t displaySlot = 0;
206 if (!mFreeDisplaySlots.empty()) {
207 displaySlot = *mFreeDisplaySlots.begin();
208 mFreeDisplaySlots.erase(displaySlot);
209 } else if (mDisplayData.size() < INT32_MAX) {
210 // Don't bother allocating a slot larger than we can return
211 displaySlot = mDisplayData.size();
212 mDisplayData.resize(displaySlot + 1);
213 } else {
214 ALOGE("allocateVirtualDisplay: Unable to allocate a display slot");
215 return NO_MEMORY;
Mathias Agopiane60b0682012-08-21 23:34:09 -0700216 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800217
218 mDisplayData[displaySlot].hwcDisplay = display;
219
220 --mRemainingHwcVirtualDisplays;
221 *outId = static_cast<int32_t>(displaySlot);
222
Mathias Agopiane60b0682012-08-21 23:34:09 -0700223 return NO_ERROR;
224}
225
Steven Thomas94e35b92017-07-26 18:48:28 -0700226HWC2::Layer* HWComposer::createLayer(int32_t displayId) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800227 if (!isValidDisplay(displayId)) {
228 ALOGE("Failed to create layer on invalid display %d", displayId);
229 return nullptr;
230 }
231 auto display = mDisplayData[displayId].hwcDisplay;
Steven Thomas94e35b92017-07-26 18:48:28 -0700232 HWC2::Layer* layer;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800233 auto error = display->createLayer(&layer);
234 if (error != HWC2::Error::None) {
235 ALOGE("Failed to create layer on display %d: %s (%d)", displayId,
236 to_string(error).c_str(), static_cast<int32_t>(error));
237 return nullptr;
238 }
239 return layer;
240}
241
Steven Thomas94e35b92017-07-26 18:48:28 -0700242void HWComposer::destroyLayer(int32_t displayId, HWC2::Layer* layer) {
243 if (!isValidDisplay(displayId)) {
244 ALOGE("Failed to destroy layer on invalid display %d", displayId);
245 return;
246 }
247 auto display = mDisplayData[displayId].hwcDisplay;
248 auto error = display->destroyLayer(layer);
249 if (error != HWC2::Error::None) {
250 ALOGE("Failed to destroy layer on display %d: %s (%d)", displayId,
251 to_string(error).c_str(), static_cast<int32_t>(error));
252 }
253}
254
Fabien Sanglarddf0b7052016-11-30 15:51:53 -0800255nsecs_t HWComposer::getRefreshTimestamp(int32_t displayId) const {
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700256 // this returns the last refresh timestamp.
257 // if the last one is not available, we estimate it based on
258 // the refresh period and whatever closest timestamp we have.
259 Mutex::Autolock _l(mLock);
260 nsecs_t now = systemTime(CLOCK_MONOTONIC);
Fabien Sanglarddf0b7052016-11-30 15:51:53 -0800261 auto vsyncPeriod = getActiveConfig(displayId)->getVsyncPeriod();
262 return now - ((now - mLastHwVSync[displayId]) % vsyncPeriod);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700263}
264
Fabien Sanglarddf0b7052016-11-30 15:51:53 -0800265bool HWComposer::isConnected(int32_t displayId) const {
266 if (!isValidDisplay(displayId)) {
267 ALOGE("isConnected: Attempted to access invalid display %d", displayId);
Mathias Agopiane60b0682012-08-21 23:34:09 -0700268 return false;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800269 }
Fabien Sanglarddf0b7052016-11-30 15:51:53 -0800270 return mDisplayData[displayId].hwcDisplay->isConnected();
Mathias Agopian9c6e2972011-09-20 17:21:56 -0700271}
272
Dan Stoza9e56aa02015-11-02 13:00:03 -0800273std::vector<std::shared_ptr<const HWC2::Display::Config>>
274 HWComposer::getConfigs(int32_t displayId) const {
275 if (!isValidDisplay(displayId)) {
276 ALOGE("getConfigs: Attempted to access invalid display %d", displayId);
277 return {};
278 }
279 auto& displayData = mDisplayData[displayId];
280 auto configs = mDisplayData[displayId].hwcDisplay->getConfigs();
281 if (displayData.configMap.empty()) {
282 for (size_t i = 0; i < configs.size(); ++i) {
283 displayData.configMap[i] = configs[i];
Mathias Agopianda27af92012-09-13 18:17:13 -0700284 }
285 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800286 return configs;
Mathias Agopianda27af92012-09-13 18:17:13 -0700287}
288
Dan Stoza9e56aa02015-11-02 13:00:03 -0800289std::shared_ptr<const HWC2::Display::Config>
290 HWComposer::getActiveConfig(int32_t displayId) const {
291 if (!isValidDisplay(displayId)) {
Fabien Sanglardb7432cc2016-11-11 09:40:27 -0800292 ALOGV("getActiveConfigs: Attempted to access invalid display %d",
Dan Stoza9e56aa02015-11-02 13:00:03 -0800293 displayId);
294 return nullptr;
Mathias Agopian58959342010-10-07 14:57:04 -0700295 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800296 std::shared_ptr<const HWC2::Display::Config> config;
297 auto error = mDisplayData[displayId].hwcDisplay->getActiveConfig(&config);
298 if (error == HWC2::Error::BadConfig) {
Fabien Sanglardb7432cc2016-11-11 09:40:27 -0800299 ALOGE("getActiveConfig: No config active, returning null");
Dan Stoza9e56aa02015-11-02 13:00:03 -0800300 return nullptr;
301 } else if (error != HWC2::Error::None) {
302 ALOGE("getActiveConfig failed for display %d: %s (%d)", displayId,
303 to_string(error).c_str(), static_cast<int32_t>(error));
304 return nullptr;
305 } else if (!config) {
306 ALOGE("getActiveConfig returned an unknown config for display %d",
307 displayId);
308 return nullptr;
309 }
310
311 return config;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700312}
313
Peiyong Linfd997e02018-03-28 15:29:00 -0700314std::vector<ui::ColorMode> HWComposer::getColorModes(int32_t displayId) const {
315 std::vector<ui::ColorMode> modes;
Courtney Goeltzenleuchterfad9d8c2016-06-23 11:49:50 -0600316
317 if (!isValidDisplay(displayId)) {
318 ALOGE("getColorModes: Attempted to access invalid display %d",
319 displayId);
320 return modes;
321 }
Courtney Goeltzenleuchterfad9d8c2016-06-23 11:49:50 -0600322
Steven Thomas94e35b92017-07-26 18:48:28 -0700323 auto error = mDisplayData[displayId].hwcDisplay->getColorModes(&modes);
Courtney Goeltzenleuchterfad9d8c2016-06-23 11:49:50 -0600324 if (error != HWC2::Error::None) {
325 ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
326 to_string(error).c_str(), static_cast<int32_t>(error));
Peiyong Linfd997e02018-03-28 15:29:00 -0700327 return std::vector<ui::ColorMode>();
Courtney Goeltzenleuchterfad9d8c2016-06-23 11:49:50 -0600328 }
329
330 return modes;
331}
332
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700333status_t HWComposer::setActiveColorMode(int32_t displayId, ui::ColorMode mode,
334 ui::RenderIntent renderIntent) {
Michael Wright28f24d02016-07-12 13:30:53 -0700335 if (!isValidDisplay(displayId)) {
336 ALOGE("setActiveColorMode: Display %d is not valid", displayId);
337 return BAD_INDEX;
338 }
339
340 auto& displayData = mDisplayData[displayId];
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700341 auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent);
Michael Wright28f24d02016-07-12 13:30:53 -0700342 if (error != HWC2::Error::None) {
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700343 ALOGE("setActiveConfig: Failed to set color mode %d"
344 "with render intent %d on display %d: "
345 "%s (%d)", mode, renderIntent, displayId,
346 to_string(error).c_str(),
Michael Wright28f24d02016-07-12 13:30:53 -0700347 static_cast<int32_t>(error));
348 return UNKNOWN_ERROR;
349 }
350
351 return NO_ERROR;
352}
353
354
Fabien Sanglarddf0b7052016-11-30 15:51:53 -0800355void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) {
356 if (displayId < 0 || displayId >= HWC_DISPLAY_VIRTUAL) {
357 ALOGD("setVsyncEnabled: Ignoring for virtual display %d", displayId);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800358 return;
359 }
360
Fabien Sanglarddf0b7052016-11-30 15:51:53 -0800361 if (!isValidDisplay(displayId)) {
362 ALOGE("setVsyncEnabled: Attempted to access invalid display %d",
363 displayId);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800364 return;
365 }
366
367 // NOTE: we use our own internal lock here because we have to call
368 // into the HWC with the lock held, and we want to make sure
369 // that even if HWC blocks (which it shouldn't), it won't
370 // affect other threads.
371 Mutex::Autolock _l(mVsyncLock);
Fabien Sanglarddf0b7052016-11-30 15:51:53 -0800372 auto& displayData = mDisplayData[displayId];
Dan Stoza9e56aa02015-11-02 13:00:03 -0800373 if (enabled != displayData.vsyncEnabled) {
374 ATRACE_CALL();
375 auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
376 if (error == HWC2::Error::None) {
377 displayData.vsyncEnabled = enabled;
378
379 char tag[16];
Fabien Sanglarddf0b7052016-11-30 15:51:53 -0800380 snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", displayId);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800381 ATRACE_INT(tag, enabled == HWC2::Vsync::Enable ? 1 : 0);
Prashant Malani2c9b11f2014-05-25 01:36:31 -0700382 } else {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800383 ALOGE("setVsyncEnabled: Failed to set vsync to %s on %d/%" PRIu64
Fabien Sanglarddf0b7052016-11-30 15:51:53 -0800384 ": %s (%d)", to_string(enabled).c_str(), displayId,
385 mDisplayData[displayId].hwcDisplay->getId(),
Dan Stoza9e56aa02015-11-02 13:00:03 -0800386 to_string(error).c_str(), static_cast<int32_t>(error));
Prashant Malani2c9b11f2014-05-25 01:36:31 -0700387 }
Colin Cross10fbdb62012-07-12 17:56:34 -0700388 }
Colin Cross10fbdb62012-07-12 17:56:34 -0700389}
390
Chia-I Wu06d63de2017-01-04 14:58:51 +0800391status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot,
Dan Stoza9e56aa02015-11-02 13:00:03 -0800392 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700393 ui::Dataspace dataspace) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800394 if (!isValidDisplay(displayId)) {
Jesse Hall851cfe82013-03-20 13:44:00 -0700395 return BAD_INDEX;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800396 }
Jesse Hall851cfe82013-03-20 13:44:00 -0700397
Dan Stoza9e56aa02015-11-02 13:00:03 -0800398 ALOGV("setClientTarget for display %d", displayId);
399 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400400 auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800401 if (error != HWC2::Error::None) {
402 ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
403 to_string(error).c_str(), static_cast<int32_t>(error));
404 return BAD_VALUE;
405 }
406
Jesse Hall851cfe82013-03-20 13:44:00 -0700407 return NO_ERROR;
408}
409
Dan Stoza9e56aa02015-11-02 13:00:03 -0800410status_t HWComposer::prepare(DisplayDevice& displayDevice) {
411 ATRACE_CALL();
412
413 Mutex::Autolock _l(mDisplayLock);
414 auto displayId = displayDevice.getHwcDisplayId();
Dan Stozaec0f7172016-07-21 11:09:40 -0700415 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
416 ALOGV("Skipping HWComposer prepare for non-HWC display");
417 return NO_ERROR;
418 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800419 if (!isValidDisplay(displayId)) {
420 return BAD_INDEX;
421 }
422
423 auto& displayData = mDisplayData[displayId];
424 auto& hwcDisplay = displayData.hwcDisplay;
425 if (!hwcDisplay->isConnected()) {
426 return NO_ERROR;
427 }
428
429 uint32_t numTypes = 0;
430 uint32_t numRequests = 0;
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700431
432 HWC2::Error error = HWC2::Error::None;
433
Chia-I Wu41b98d42017-12-11 11:04:36 -0800434 // First try to skip validate altogether when there is no client
435 // composition. When there is client composition, since we haven't
436 // rendered to the client target yet, we should not attempt to skip
437 // validate.
438 //
439 // displayData.hasClientComposition hasn't been updated for this frame.
440 // The check below is incorrect. We actually rely on HWC here to fall
441 // back to validate when there is any client layer.
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700442 displayData.validateWasSkipped = false;
Chia-I Wu41b98d42017-12-11 11:04:36 -0800443 if (!displayData.hasClientComposition) {
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700444 sp<android::Fence> outPresentFence;
445 uint32_t state = UINT32_MAX;
446 error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
447 if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
448 ALOGV("skipValidate: Failed to Present or Validate");
449 return UNKNOWN_ERROR;
450 }
451 if (state == 1) { //Present Succeeded.
Steven Thomas94e35b92017-07-26 18:48:28 -0700452 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700453 error = hwcDisplay->getReleaseFences(&releaseFences);
454 displayData.releaseFences = std::move(releaseFences);
455 displayData.lastPresentFence = outPresentFence;
456 displayData.validateWasSkipped = true;
457 displayData.presentError = error;
458 return NO_ERROR;
459 }
460 // Present failed but Validate ran.
461 } else {
462 error = hwcDisplay->validate(&numTypes, &numRequests);
463 }
464 ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
Dan Stoza9e56aa02015-11-02 13:00:03 -0800465 if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
466 ALOGE("prepare: validate failed for display %d: %s (%d)", displayId,
467 to_string(error).c_str(), static_cast<int32_t>(error));
468 return BAD_INDEX;
469 }
470
Steven Thomas94e35b92017-07-26 18:48:28 -0700471 std::unordered_map<HWC2::Layer*, HWC2::Composition> changedTypes;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800472 changedTypes.reserve(numTypes);
473 error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
474 if (error != HWC2::Error::None) {
475 ALOGE("prepare: getChangedCompositionTypes failed on display %d: "
476 "%s (%d)", displayId, to_string(error).c_str(),
477 static_cast<int32_t>(error));
478 return BAD_INDEX;
479 }
480
481
482 displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
Steven Thomas94e35b92017-07-26 18:48:28 -0700483 std::unordered_map<HWC2::Layer*, HWC2::LayerRequest> layerRequests;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800484 layerRequests.reserve(numRequests);
485 error = hwcDisplay->getRequests(&displayData.displayRequests,
486 &layerRequests);
487 if (error != HWC2::Error::None) {
488 ALOGE("prepare: getRequests failed on display %d: %s (%d)", displayId,
489 to_string(error).c_str(), static_cast<int32_t>(error));
490 return BAD_INDEX;
491 }
492
493 displayData.hasClientComposition = false;
494 displayData.hasDeviceComposition = false;
495 for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) {
496 auto hwcLayer = layer->getHwcLayer(displayId);
497
498 if (changedTypes.count(hwcLayer) != 0) {
499 // We pass false so we only update our state and don't call back
500 // into the HWC device
501 validateChange(layer->getCompositionType(displayId),
502 changedTypes[hwcLayer]);
503 layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
504 }
505
506 switch (layer->getCompositionType(displayId)) {
507 case HWC2::Composition::Client:
508 displayData.hasClientComposition = true;
509 break;
510 case HWC2::Composition::Device:
511 case HWC2::Composition::SolidColor:
512 case HWC2::Composition::Cursor:
513 case HWC2::Composition::Sideband:
514 displayData.hasDeviceComposition = true;
515 break;
516 default:
517 break;
518 }
519
520 if (layerRequests.count(hwcLayer) != 0 &&
521 layerRequests[hwcLayer] ==
522 HWC2::LayerRequest::ClearClientTarget) {
523 layer->setClearClientTarget(displayId, true);
524 } else {
525 if (layerRequests.count(hwcLayer) != 0) {
526 ALOGE("prepare: Unknown layer request: %s",
527 to_string(layerRequests[hwcLayer]).c_str());
528 }
529 layer->setClearClientTarget(displayId, false);
530 }
531 }
532
533 error = hwcDisplay->acceptChanges();
534 if (error != HWC2::Error::None) {
535 ALOGE("prepare: acceptChanges failed: %s", to_string(error).c_str());
536 return BAD_INDEX;
537 }
538
539 return NO_ERROR;
540}
541
542bool HWComposer::hasDeviceComposition(int32_t displayId) const {
Dan Stozaec0f7172016-07-21 11:09:40 -0700543 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
544 // Displays without a corresponding HWC display are never composed by
545 // the device
546 return false;
547 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800548 if (!isValidDisplay(displayId)) {
549 ALOGE("hasDeviceComposition: Invalid display %d", displayId);
550 return false;
551 }
552 return mDisplayData[displayId].hasDeviceComposition;
553}
554
Madhuri Athota88a905b2017-05-04 16:58:15 +0530555bool HWComposer::hasFlipClientTargetRequest(int32_t displayId) const {
556 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
557 // Displays without a corresponding HWC display are never composed by
558 // the device
559 return false;
560 }
561 if (!isValidDisplay(displayId)) {
562 ALOGE("hasFlipClientTargetRequest: Invalid display %d", displayId);
563 return false;
564 }
565 return ((static_cast<uint32_t>(mDisplayData[displayId].displayRequests) &
566 static_cast<uint32_t>(HWC2::DisplayRequest::FlipClientTarget)) != 0);
567}
568
Dan Stoza9e56aa02015-11-02 13:00:03 -0800569bool HWComposer::hasClientComposition(int32_t displayId) const {
Dan Stozaec0f7172016-07-21 11:09:40 -0700570 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
571 // Displays without a corresponding HWC display are always composed by
572 // the client
573 return true;
574 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800575 if (!isValidDisplay(displayId)) {
576 ALOGE("hasClientComposition: Invalid display %d", displayId);
577 return true;
578 }
579 return mDisplayData[displayId].hasClientComposition;
580}
581
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800582sp<Fence> HWComposer::getPresentFence(int32_t displayId) const {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800583 if (!isValidDisplay(displayId)) {
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800584 ALOGE("getPresentFence failed for invalid display %d", displayId);
Jesse Hall851cfe82013-03-20 13:44:00 -0700585 return Fence::NO_FENCE;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800586 }
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800587 return mDisplayData[displayId].lastPresentFence;
Jesse Hall851cfe82013-03-20 13:44:00 -0700588}
589
Dan Stoza9e56aa02015-11-02 13:00:03 -0800590sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
Steven Thomas94e35b92017-07-26 18:48:28 -0700591 HWC2::Layer* layer) const {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800592 if (!isValidDisplay(displayId)) {
593 ALOGE("getLayerReleaseFence: Invalid display");
594 return Fence::NO_FENCE;
Riley Andrews03414a12014-07-01 14:22:59 -0700595 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800596 auto displayFences = mDisplayData[displayId].releaseFences;
597 if (displayFences.count(layer) == 0) {
598 ALOGV("getLayerReleaseFence: Release fence not found");
599 return Fence::NO_FENCE;
Riley Andrews03414a12014-07-01 14:22:59 -0700600 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800601 return displayFences[layer];
Riley Andrews03414a12014-07-01 14:22:59 -0700602}
603
Fabien Sanglarda87aa7b2016-11-30 16:27:22 -0800604status_t HWComposer::presentAndGetReleaseFences(int32_t displayId) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800605 ATRACE_CALL();
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700606
Dan Stoza9e56aa02015-11-02 13:00:03 -0800607 if (!isValidDisplay(displayId)) {
608 return BAD_INDEX;
Mathias Agopianc3973602012-08-31 17:51:25 -0700609 }
Pablo Ceballosd814cf22015-09-11 14:37:39 -0700610
Dan Stoza9e56aa02015-11-02 13:00:03 -0800611 auto& displayData = mDisplayData[displayId];
612 auto& hwcDisplay = displayData.hwcDisplay;
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700613
614 if (displayData.validateWasSkipped) {
Chia-I Wuae5a6b82017-10-10 09:09:22 -0700615 // explicitly flush all pending commands
616 auto error = mHwcDevice->flushCommands();
617 if (displayData.presentError != HWC2::Error::None) {
618 error = displayData.presentError;
619 }
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700620 if (error != HWC2::Error::None) {
621 ALOGE("skipValidate: failed for display %d: %s (%d)",
622 displayId, to_string(error).c_str(), static_cast<int32_t>(error));
623 return UNKNOWN_ERROR;
624 }
625 return NO_ERROR;
626 }
627
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800628 auto error = hwcDisplay->present(&displayData.lastPresentFence);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800629 if (error != HWC2::Error::None) {
Fabien Sanglarda87aa7b2016-11-30 16:27:22 -0800630 ALOGE("presentAndGetReleaseFences: failed for display %d: %s (%d)",
631 displayId, to_string(error).c_str(), static_cast<int32_t>(error));
Dan Stoza9e56aa02015-11-02 13:00:03 -0800632 return UNKNOWN_ERROR;
633 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700634
Steven Thomas94e35b92017-07-26 18:48:28 -0700635 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800636 error = hwcDisplay->getReleaseFences(&releaseFences);
637 if (error != HWC2::Error::None) {
Fabien Sanglarda87aa7b2016-11-30 16:27:22 -0800638 ALOGE("presentAndGetReleaseFences: Failed to get release fences "
639 "for display %d: %s (%d)",
Dan Stoza9e56aa02015-11-02 13:00:03 -0800640 displayId, to_string(error).c_str(),
641 static_cast<int32_t>(error));
642 return UNKNOWN_ERROR;
Mathias Agopianf4358632012-08-22 17:16:19 -0700643 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800644
645 displayData.releaseFences = std::move(releaseFences);
646
647 return NO_ERROR;
Mathias Agopiana350ff92010-08-10 17:14:02 -0700648}
649
Dan Stoza9e56aa02015-11-02 13:00:03 -0800650status_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) {
651 ALOGV("setPowerMode(%d, %d)", displayId, intMode);
652 if (!isValidDisplay(displayId)) {
653 ALOGE("setPowerMode: Bad display");
654 return BAD_INDEX;
655 }
656 if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
657 ALOGE("setPowerMode: Virtual display %d passed in, returning",
658 displayId);
659 return BAD_INDEX;
660 }
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700661
Dan Stoza9e56aa02015-11-02 13:00:03 -0800662 auto mode = static_cast<HWC2::PowerMode>(intMode);
663 if (mode == HWC2::PowerMode::Off) {
664 setVsyncEnabled(displayId, HWC2::Vsync::Disable);
665 }
666
667 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
668 switch (mode) {
669 case HWC2::PowerMode::Off:
670 case HWC2::PowerMode::On:
671 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
672 {
673 auto error = hwcDisplay->setPowerMode(mode);
674 if (error != HWC2::Error::None) {
675 ALOGE("setPowerMode: Unable to set power mode %s for "
676 "display %d: %s (%d)", to_string(mode).c_str(),
677 displayId, to_string(error).c_str(),
678 static_cast<int32_t>(error));
Mathias Agopianda27af92012-09-13 18:17:13 -0700679 }
680 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800681 break;
682 case HWC2::PowerMode::Doze:
683 case HWC2::PowerMode::DozeSuspend:
684 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
685 {
686 bool supportsDoze = false;
687 auto error = hwcDisplay->supportsDoze(&supportsDoze);
688 if (error != HWC2::Error::None) {
689 ALOGE("setPowerMode: Unable to query doze support for "
690 "display %d: %s (%d)", displayId,
691 to_string(error).c_str(),
692 static_cast<int32_t>(error));
693 }
694 if (!supportsDoze) {
695 mode = HWC2::PowerMode::On;
696 }
697
698 error = hwcDisplay->setPowerMode(mode);
699 if (error != HWC2::Error::None) {
700 ALOGE("setPowerMode: Unable to set power mode %s for "
701 "display %d: %s (%d)", to_string(mode).c_str(),
702 displayId, to_string(error).c_str(),
703 static_cast<int32_t>(error));
704 }
705 }
706 break;
707 default:
708 ALOGV("setPowerMode: Not calling HWC");
709 break;
Mathias Agopianda27af92012-09-13 18:17:13 -0700710 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800711
712 return NO_ERROR;
713}
714
715status_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) {
716 if (!isValidDisplay(displayId)) {
717 ALOGE("setActiveConfig: Display %d is not valid", displayId);
718 return BAD_INDEX;
719 }
720
721 auto& displayData = mDisplayData[displayId];
722 if (displayData.configMap.count(configId) == 0) {
723 ALOGE("setActiveConfig: Invalid config %zd", configId);
724 return BAD_INDEX;
725 }
726
727 auto error = displayData.hwcDisplay->setActiveConfig(
728 displayData.configMap[configId]);
729 if (error != HWC2::Error::None) {
730 ALOGE("setActiveConfig: Failed to set config %zu on display %d: "
731 "%s (%d)", configId, displayId, to_string(error).c_str(),
732 static_cast<int32_t>(error));
733 return UNKNOWN_ERROR;
734 }
735
736 return NO_ERROR;
737}
738
Dan Stoza9f26a9c2016-06-22 14:51:09 -0700739status_t HWComposer::setColorTransform(int32_t displayId,
740 const mat4& transform) {
741 if (!isValidDisplay(displayId)) {
742 ALOGE("setColorTransform: Display %d is not valid", displayId);
743 return BAD_INDEX;
744 }
745
746 auto& displayData = mDisplayData[displayId];
747 bool isIdentity = transform == mat4();
748 auto error = displayData.hwcDisplay->setColorTransform(transform,
749 isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
750 HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
751 if (error != HWC2::Error::None) {
752 ALOGE("setColorTransform: Failed to set transform on display %d: "
753 "%s (%d)", displayId, to_string(error).c_str(),
754 static_cast<int32_t>(error));
755 return UNKNOWN_ERROR;
756 }
757
758 return NO_ERROR;
759}
760
Dan Stoza9e56aa02015-11-02 13:00:03 -0800761void HWComposer::disconnectDisplay(int displayId) {
762 LOG_ALWAYS_FATAL_IF(displayId < 0);
763 auto& displayData = mDisplayData[displayId];
764
765 auto displayType = HWC2::DisplayType::Invalid;
766 auto error = displayData.hwcDisplay->getType(&displayType);
767 if (error != HWC2::Error::None) {
768 ALOGE("disconnectDisplay: Failed to determine type of display %d",
769 displayId);
770 return;
771 }
772
773 // If this was a virtual display, add its slot back for reuse by future
774 // virtual displays
775 if (displayType == HWC2::DisplayType::Virtual) {
776 mFreeDisplaySlots.insert(displayId);
777 ++mRemainingHwcVirtualDisplays;
778 }
779
780 auto hwcId = displayData.hwcDisplay->getId();
781 mHwcDisplaySlots.erase(hwcId);
782 displayData.reset();
Steven Thomas94e35b92017-07-26 18:48:28 -0700783
784 mHwcDevice->destroyDisplay(hwcId);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800785}
786
787status_t HWComposer::setOutputBuffer(int32_t displayId,
788 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
789 if (!isValidDisplay(displayId)) {
790 ALOGE("setOutputBuffer: Display %d is not valid", displayId);
791 return BAD_INDEX;
792 }
793
794 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
795 auto displayType = HWC2::DisplayType::Invalid;
796 auto error = hwcDisplay->getType(&displayType);
797 if (error != HWC2::Error::None) {
798 ALOGE("setOutputBuffer: Failed to determine type of display %d",
799 displayId);
800 return NAME_NOT_FOUND;
801 }
802
803 if (displayType != HWC2::DisplayType::Virtual) {
804 ALOGE("setOutputBuffer: Display %d is not virtual", displayId);
805 return INVALID_OPERATION;
806 }
807
808 error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
809 if (error != HWC2::Error::None) {
810 ALOGE("setOutputBuffer: Failed to set buffer on display %d: %s (%d)",
811 displayId, to_string(error).c_str(),
812 static_cast<int32_t>(error));
813 return UNKNOWN_ERROR;
814 }
815
816 return NO_ERROR;
817}
818
819void HWComposer::clearReleaseFences(int32_t displayId) {
820 if (!isValidDisplay(displayId)) {
821 ALOGE("clearReleaseFences: Display %d is not valid", displayId);
822 return;
823 }
824 mDisplayData[displayId].releaseFences.clear();
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700825}
826
Peiyong Lin62665892018-04-16 11:07:44 -0700827status_t HWComposer::getHdrCapabilities(
828 int32_t displayId, HdrCapabilities* outCapabilities) {
Dan Stozac4f471e2016-03-24 09:31:08 -0700829 if (!isValidDisplay(displayId)) {
830 ALOGE("getHdrCapabilities: Display %d is not valid", displayId);
Peiyong Lin62665892018-04-16 11:07:44 -0700831 return BAD_INDEX;
Dan Stozac4f471e2016-03-24 09:31:08 -0700832 }
833
834 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
Peiyong Lin62665892018-04-16 11:07:44 -0700835 auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
Dan Stozac4f471e2016-03-24 09:31:08 -0700836 if (error != HWC2::Error::None) {
837 ALOGE("getOutputCapabilities: Failed to get capabilities on display %d:"
Peiyong Lin62665892018-04-16 11:07:44 -0700838 " %s (%d)", displayId, to_string(error).c_str(),
839 static_cast<int32_t>(error));
840 return UNKNOWN_ERROR;
Dan Stozac4f471e2016-03-24 09:31:08 -0700841 }
Peiyong Lin62665892018-04-16 11:07:44 -0700842 return NO_ERROR;
Dan Stozac4f471e2016-03-24 09:31:08 -0700843}
844
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700845int32_t HWComposer::getSupportedPerFrameMetadata(int32_t displayId) const {
846 if (!isValidDisplay(displayId)) {
847 ALOGE("getPerFrameMetadataKeys: Attempted to access invalid display %d",
848 displayId);
849 return 0;
850 }
851
852 int32_t supportedMetadata;
853 auto error = mDisplayData[displayId].hwcDisplay->getSupportedPerFrameMetadata(
854 &supportedMetadata);
855 if (error != HWC2::Error::None) {
856 ALOGE("getPerFrameMetadataKeys failed for display %d: %s (%d)", displayId,
857 to_string(error).c_str(), static_cast<int32_t>(error));
858 return 0;
859 }
860
861 return supportedMetadata;
862}
863
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700864std::vector<ui::RenderIntent> HWComposer::getRenderIntents(int32_t displayId,
865 ui::ColorMode colorMode) const {
866 if (!isValidDisplay(displayId)) {
867 ALOGE("getRenderIntents: Attempted to access invalid display %d",
868 displayId);
869 return {};
870 }
871
872 std::vector<ui::RenderIntent> renderIntents;
873 auto error = mDisplayData[displayId].hwcDisplay->getRenderIntents(colorMode, &renderIntents);
874 if (error != HWC2::Error::None) {
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700875 ALOGE("getRenderIntents failed for display %d: %s (%d)", displayId,
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700876 to_string(error).c_str(), static_cast<int32_t>(error));
877 return std::vector<ui::RenderIntent>();
878 }
879
880 return renderIntents;
881}
882
883mat4 HWComposer::getDataspaceSaturationMatrix(int32_t displayId, ui::Dataspace dataspace) {
884 if (!isValidDisplay(displayId)) {
885 ALOGE("getDataSpaceSaturationMatrix: Attempted to access invalid display %d",
886 displayId);
887 return {};
888 }
889
890 mat4 matrix;
891 auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace,
892 &matrix);
893 if (error != HWC2::Error::None) {
894 ALOGE("getDataSpaceSaturationMatrix failed for display %d: %s (%d)", displayId,
895 to_string(error).c_str(), static_cast<int32_t>(error));
896 return mat4();
897 }
898
899 return matrix;
900}
901
Andy McFadden4df87bd2014-04-21 18:08:54 -0700902// Converts a PixelFormat to a human-readable string. Max 11 chars.
903// (Could use a table of prefab String8 objects.)
Dan Stoza9e56aa02015-11-02 13:00:03 -0800904/*
Andy McFadden4df87bd2014-04-21 18:08:54 -0700905static String8 getFormatStr(PixelFormat format) {
906 switch (format) {
907 case PIXEL_FORMAT_RGBA_8888: return String8("RGBA_8888");
908 case PIXEL_FORMAT_RGBX_8888: return String8("RGBx_8888");
909 case PIXEL_FORMAT_RGB_888: return String8("RGB_888");
910 case PIXEL_FORMAT_RGB_565: return String8("RGB_565");
911 case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888");
Andy McFaddenf0058ca2014-05-20 13:28:50 -0700912 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
913 return String8("ImplDef");
Andy McFadden4df87bd2014-04-21 18:08:54 -0700914 default:
915 String8 result;
916 result.appendFormat("? %08x", format);
917 return result;
918 }
919}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800920*/
Andy McFadden4df87bd2014-04-21 18:08:54 -0700921
Hendrik Wagenaar87670ff2017-02-01 12:10:46 -0800922bool HWComposer::isUsingVrComposer() const {
Hendrik Wagenaar87670ff2017-02-01 12:10:46 -0800923 return getComposer()->isUsingVrComposer();
Hendrik Wagenaar87670ff2017-02-01 12:10:46 -0800924}
925
Mathias Agopian74d211a2013-04-22 16:55:35 +0200926void HWComposer::dump(String8& result) const {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800927 // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
928 // all the state going into the layers. This is probably better done in
929 // Layer itself, but it's going to take a bit of work to get there.
930 result.append(mHwcDevice->dump().c_str());
Mathias Agopian83727852010-09-23 18:13:21 -0700931}
932
Steven Thomas6e8f7062017-11-22 14:15:29 -0800933std::optional<hwc2_display_t>
934HWComposer::getHwcDisplayId(int32_t displayId) const {
935 if (!isValidDisplay(displayId)) {
936 return {};
937 }
938 return mDisplayData[displayId].hwcDisplay->getId();
939}
940
Mathias Agopiana350ff92010-08-10 17:14:02 -0700941// ---------------------------------------------------------------------------
Mathias Agopian2965b262012-04-08 15:13:32 -0700942
Jesse Halla9a1b002013-02-27 16:39:25 -0800943HWComposer::DisplayData::DisplayData()
Dan Stoza9e56aa02015-11-02 13:00:03 -0800944 : hasClientComposition(false),
945 hasDeviceComposition(false),
Steven Thomas94e35b92017-07-26 18:48:28 -0700946 hwcDisplay(nullptr),
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800947 lastPresentFence(Fence::NO_FENCE),
Dan Stoza9e56aa02015-11-02 13:00:03 -0800948 outbufHandle(nullptr),
949 outbufAcquireFence(Fence::NO_FENCE),
950 vsyncEnabled(HWC2::Vsync::Disable) {
951 ALOGV("Created new DisplayData");
952}
Jesse Halla9a1b002013-02-27 16:39:25 -0800953
954HWComposer::DisplayData::~DisplayData() {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800955}
956
957void HWComposer::DisplayData::reset() {
958 ALOGV("DisplayData reset");
959 *this = DisplayData();
Jesse Halla9a1b002013-02-27 16:39:25 -0800960}
961
Mathias Agopian2965b262012-04-08 15:13:32 -0700962// ---------------------------------------------------------------------------
Mathias Agopiana350ff92010-08-10 17:14:02 -0700963}; // namespace android