blob: d72139e12d078304ade0f840687d7ffbf5b62577 [file] [log] [blame]
Dan Stozac6998d22015-09-24 17:03:36 -07001/*
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 "HWC2On1Adapter"
21#define ATRACE_TAG ATRACE_TAG_GRAPHICS
22
23#include "HWC2On1Adapter.h"
24
Dan Stozac6998d22015-09-24 17:03:36 -070025#include <inttypes.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070026
27#include <chrono>
28#include <cstdlib>
Dan Stozac6998d22015-09-24 17:03:36 -070029#include <sstream>
30
Mark Salyzyna5e161b2016-09-29 08:08:05 -070031#include <hardware/hwcomposer.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070032#include <log/log.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070033#include <utils/Trace.h>
34
Dan Stozac6998d22015-09-24 17:03:36 -070035using namespace std::chrono_literals;
36
Dan Stozac6998d22015-09-24 17:03:36 -070037static uint8_t getMinorVersion(struct hwc_composer_device_1* device)
38{
39 auto version = device->common.version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
40 return (version >> 16) & 0xF;
41}
42
43template <typename PFN, typename T>
44static hwc2_function_pointer_t asFP(T function)
45{
46 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
47 return reinterpret_cast<hwc2_function_pointer_t>(function);
48}
49
50using namespace HWC2;
51
Michael Wright28f24d02016-07-12 13:30:53 -070052static constexpr Attribute ColorMode = static_cast<Attribute>(6);
Dan Stoza076ac672016-03-14 10:47:53 -070053
Dan Stozac6998d22015-09-24 17:03:36 -070054namespace android {
55
Dan Stozac6998d22015-09-24 17:03:36 -070056class HWC2On1Adapter::Callbacks : public hwc_procs_t {
57 public:
Chih-Hung Hsiehc4067912016-05-03 14:03:27 -070058 explicit Callbacks(HWC2On1Adapter& adapter) : mAdapter(adapter) {
Dan Stozac6998d22015-09-24 17:03:36 -070059 invalidate = &invalidateHook;
60 vsync = &vsyncHook;
61 hotplug = &hotplugHook;
62 }
63
64 static void invalidateHook(const hwc_procs_t* procs) {
65 auto callbacks = static_cast<const Callbacks*>(procs);
66 callbacks->mAdapter.hwc1Invalidate();
67 }
68
69 static void vsyncHook(const hwc_procs_t* procs, int display,
70 int64_t timestamp) {
71 auto callbacks = static_cast<const Callbacks*>(procs);
72 callbacks->mAdapter.hwc1Vsync(display, timestamp);
73 }
74
75 static void hotplugHook(const hwc_procs_t* procs, int display,
76 int connected) {
77 auto callbacks = static_cast<const Callbacks*>(procs);
78 callbacks->mAdapter.hwc1Hotplug(display, connected);
79 }
80
81 private:
82 HWC2On1Adapter& mAdapter;
83};
84
85static int closeHook(hw_device_t* /*device*/)
86{
87 // Do nothing, since the real work is done in the class destructor, but we
88 // need to provide a valid function pointer for hwc2_close to call
89 return 0;
90}
91
92HWC2On1Adapter::HWC2On1Adapter(hwc_composer_device_1_t* hwc1Device)
93 : mDumpString(),
94 mHwc1Device(hwc1Device),
95 mHwc1MinorVersion(getMinorVersion(hwc1Device)),
96 mHwc1SupportsVirtualDisplays(false),
Fabien Sanglardeb3db612016-11-18 16:12:31 -080097 mHwc1SupportsBackgroundColor(false),
Dan Stozac6998d22015-09-24 17:03:36 -070098 mHwc1Callbacks(std::make_unique<Callbacks>(*this)),
99 mCapabilities(),
100 mLayers(),
101 mHwc1VirtualDisplay(),
102 mStateMutex(),
103 mCallbacks(),
104 mHasPendingInvalidate(false),
105 mPendingVsyncs(),
106 mPendingHotplugs(),
107 mDisplays(),
108 mHwc1DisplayMap()
109{
110 common.close = closeHook;
111 getCapabilities = getCapabilitiesHook;
112 getFunction = getFunctionHook;
113 populateCapabilities();
114 populatePrimary();
115 mHwc1Device->registerProcs(mHwc1Device,
116 static_cast<const hwc_procs_t*>(mHwc1Callbacks.get()));
117}
118
119HWC2On1Adapter::~HWC2On1Adapter() {
120 hwc_close_1(mHwc1Device);
121}
122
123void HWC2On1Adapter::doGetCapabilities(uint32_t* outCount,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800124 int32_t* outCapabilities) {
Dan Stozac6998d22015-09-24 17:03:36 -0700125 if (outCapabilities == nullptr) {
126 *outCount = mCapabilities.size();
127 return;
128 }
129
130 auto capabilityIter = mCapabilities.cbegin();
131 for (size_t written = 0; written < *outCount; ++written) {
132 if (capabilityIter == mCapabilities.cend()) {
133 return;
134 }
135 outCapabilities[written] = static_cast<int32_t>(*capabilityIter);
136 ++capabilityIter;
137 }
138}
139
140hwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800141 FunctionDescriptor descriptor) {
Dan Stozac6998d22015-09-24 17:03:36 -0700142 switch (descriptor) {
143 // Device functions
144 case FunctionDescriptor::CreateVirtualDisplay:
145 return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
146 createVirtualDisplayHook);
147 case FunctionDescriptor::DestroyVirtualDisplay:
148 return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
149 destroyVirtualDisplayHook);
150 case FunctionDescriptor::Dump:
151 return asFP<HWC2_PFN_DUMP>(dumpHook);
152 case FunctionDescriptor::GetMaxVirtualDisplayCount:
153 return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
154 getMaxVirtualDisplayCountHook);
155 case FunctionDescriptor::RegisterCallback:
156 return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
157
158 // Display functions
159 case FunctionDescriptor::AcceptDisplayChanges:
160 return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
161 displayHook<decltype(&Display::acceptChanges),
162 &Display::acceptChanges>);
163 case FunctionDescriptor::CreateLayer:
164 return asFP<HWC2_PFN_CREATE_LAYER>(
165 displayHook<decltype(&Display::createLayer),
166 &Display::createLayer, hwc2_layer_t*>);
167 case FunctionDescriptor::DestroyLayer:
168 return asFP<HWC2_PFN_DESTROY_LAYER>(
169 displayHook<decltype(&Display::destroyLayer),
170 &Display::destroyLayer, hwc2_layer_t>);
171 case FunctionDescriptor::GetActiveConfig:
172 return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
173 displayHook<decltype(&Display::getActiveConfig),
174 &Display::getActiveConfig, hwc2_config_t*>);
175 case FunctionDescriptor::GetChangedCompositionTypes:
176 return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
177 displayHook<decltype(&Display::getChangedCompositionTypes),
178 &Display::getChangedCompositionTypes, uint32_t*,
179 hwc2_layer_t*, int32_t*>);
Dan Stoza076ac672016-03-14 10:47:53 -0700180 case FunctionDescriptor::GetColorModes:
181 return asFP<HWC2_PFN_GET_COLOR_MODES>(
182 displayHook<decltype(&Display::getColorModes),
183 &Display::getColorModes, uint32_t*, int32_t*>);
Dan Stozac6998d22015-09-24 17:03:36 -0700184 case FunctionDescriptor::GetDisplayAttribute:
185 return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
186 getDisplayAttributeHook);
187 case FunctionDescriptor::GetDisplayConfigs:
188 return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
189 displayHook<decltype(&Display::getConfigs),
190 &Display::getConfigs, uint32_t*, hwc2_config_t*>);
191 case FunctionDescriptor::GetDisplayName:
192 return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
193 displayHook<decltype(&Display::getName),
194 &Display::getName, uint32_t*, char*>);
195 case FunctionDescriptor::GetDisplayRequests:
196 return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
197 displayHook<decltype(&Display::getRequests),
198 &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*,
199 int32_t*>);
200 case FunctionDescriptor::GetDisplayType:
201 return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
202 displayHook<decltype(&Display::getType),
203 &Display::getType, int32_t*>);
204 case FunctionDescriptor::GetDozeSupport:
205 return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
206 displayHook<decltype(&Display::getDozeSupport),
207 &Display::getDozeSupport, int32_t*>);
Dan Stozaed40eba2016-03-16 12:33:52 -0700208 case FunctionDescriptor::GetHdrCapabilities:
209 return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
210 displayHook<decltype(&Display::getHdrCapabilities),
211 &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
212 float*, float*>);
Dan Stozac6998d22015-09-24 17:03:36 -0700213 case FunctionDescriptor::GetReleaseFences:
214 return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
215 displayHook<decltype(&Display::getReleaseFences),
216 &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
217 int32_t*>);
218 case FunctionDescriptor::PresentDisplay:
219 return asFP<HWC2_PFN_PRESENT_DISPLAY>(
220 displayHook<decltype(&Display::present),
221 &Display::present, int32_t*>);
222 case FunctionDescriptor::SetActiveConfig:
223 return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
224 displayHook<decltype(&Display::setActiveConfig),
225 &Display::setActiveConfig, hwc2_config_t>);
226 case FunctionDescriptor::SetClientTarget:
227 return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
228 displayHook<decltype(&Display::setClientTarget),
229 &Display::setClientTarget, buffer_handle_t, int32_t,
Dan Stoza5cf424b2016-05-20 14:02:39 -0700230 int32_t, hwc_region_t>);
Dan Stoza076ac672016-03-14 10:47:53 -0700231 case FunctionDescriptor::SetColorMode:
Michael Wright28f24d02016-07-12 13:30:53 -0700232 return asFP<HWC2_PFN_SET_COLOR_MODE>(setColorModeHook);
Dan Stoza5df2a862016-03-24 16:19:37 -0700233 case FunctionDescriptor::SetColorTransform:
234 return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
Dan Stozac6998d22015-09-24 17:03:36 -0700235 case FunctionDescriptor::SetOutputBuffer:
236 return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
237 displayHook<decltype(&Display::setOutputBuffer),
238 &Display::setOutputBuffer, buffer_handle_t, int32_t>);
239 case FunctionDescriptor::SetPowerMode:
240 return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
241 case FunctionDescriptor::SetVsyncEnabled:
242 return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook);
243 case FunctionDescriptor::ValidateDisplay:
244 return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
245 displayHook<decltype(&Display::validate),
246 &Display::validate, uint32_t*, uint32_t*>);
247
248 // Layer functions
249 case FunctionDescriptor::SetCursorPosition:
250 return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
251 layerHook<decltype(&Layer::setCursorPosition),
252 &Layer::setCursorPosition, int32_t, int32_t>);
253 case FunctionDescriptor::SetLayerBuffer:
254 return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
255 layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
256 buffer_handle_t, int32_t>);
257 case FunctionDescriptor::SetLayerSurfaceDamage:
258 return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
259 layerHook<decltype(&Layer::setSurfaceDamage),
260 &Layer::setSurfaceDamage, hwc_region_t>);
261
262 // Layer state functions
263 case FunctionDescriptor::SetLayerBlendMode:
264 return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
265 setLayerBlendModeHook);
266 case FunctionDescriptor::SetLayerColor:
267 return asFP<HWC2_PFN_SET_LAYER_COLOR>(
268 layerHook<decltype(&Layer::setColor), &Layer::setColor,
269 hwc_color_t>);
270 case FunctionDescriptor::SetLayerCompositionType:
271 return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
272 setLayerCompositionTypeHook);
Dan Stoza5df2a862016-03-24 16:19:37 -0700273 case FunctionDescriptor::SetLayerDataspace:
274 return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerDataspaceHook);
Dan Stozac6998d22015-09-24 17:03:36 -0700275 case FunctionDescriptor::SetLayerDisplayFrame:
276 return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
277 layerHook<decltype(&Layer::setDisplayFrame),
278 &Layer::setDisplayFrame, hwc_rect_t>);
279 case FunctionDescriptor::SetLayerPlaneAlpha:
280 return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
281 layerHook<decltype(&Layer::setPlaneAlpha),
282 &Layer::setPlaneAlpha, float>);
283 case FunctionDescriptor::SetLayerSidebandStream:
284 return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
285 layerHook<decltype(&Layer::setSidebandStream),
286 &Layer::setSidebandStream, const native_handle_t*>);
287 case FunctionDescriptor::SetLayerSourceCrop:
288 return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
289 layerHook<decltype(&Layer::setSourceCrop),
290 &Layer::setSourceCrop, hwc_frect_t>);
291 case FunctionDescriptor::SetLayerTransform:
292 return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerTransformHook);
293 case FunctionDescriptor::SetLayerVisibleRegion:
294 return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
295 layerHook<decltype(&Layer::setVisibleRegion),
296 &Layer::setVisibleRegion, hwc_region_t>);
297 case FunctionDescriptor::SetLayerZOrder:
298 return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerZOrderHook);
299
300 default:
301 ALOGE("doGetFunction: Unknown function descriptor: %d (%s)",
302 static_cast<int32_t>(descriptor),
303 to_string(descriptor).c_str());
304 return nullptr;
305 }
306}
307
308// Device functions
309
310Error HWC2On1Adapter::createVirtualDisplay(uint32_t width,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800311 uint32_t height, hwc2_display_t* outDisplay) {
Dan Stozafc4e2022016-02-23 11:43:19 -0800312 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -0700313
314 if (mHwc1VirtualDisplay) {
315 // We have already allocated our only HWC1 virtual display
316 ALOGE("createVirtualDisplay: HWC1 virtual display already allocated");
317 return Error::NoResources;
318 }
319
320 if (MAX_VIRTUAL_DISPLAY_DIMENSION != 0 &&
321 (width > MAX_VIRTUAL_DISPLAY_DIMENSION ||
322 height > MAX_VIRTUAL_DISPLAY_DIMENSION)) {
323 ALOGE("createVirtualDisplay: Can't create a virtual display with"
324 " a dimension > %u (tried %u x %u)",
325 MAX_VIRTUAL_DISPLAY_DIMENSION, width, height);
326 return Error::NoResources;
327 }
328
329 mHwc1VirtualDisplay = std::make_shared<HWC2On1Adapter::Display>(*this,
330 HWC2::DisplayType::Virtual);
331 mHwc1VirtualDisplay->populateConfigs(width, height);
332 const auto displayId = mHwc1VirtualDisplay->getId();
333 mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL] = displayId;
334 mHwc1VirtualDisplay->setHwc1Id(HWC_DISPLAY_VIRTUAL);
335 mDisplays.emplace(displayId, mHwc1VirtualDisplay);
336 *outDisplay = displayId;
337
338 return Error::None;
339}
340
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800341Error HWC2On1Adapter::destroyVirtualDisplay(hwc2_display_t displayId) {
Dan Stozafc4e2022016-02-23 11:43:19 -0800342 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -0700343
344 if (!mHwc1VirtualDisplay || (mHwc1VirtualDisplay->getId() != displayId)) {
345 return Error::BadDisplay;
346 }
347
348 mHwc1VirtualDisplay.reset();
349 mHwc1DisplayMap.erase(HWC_DISPLAY_VIRTUAL);
350 mDisplays.erase(displayId);
351
352 return Error::None;
353}
354
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800355void HWC2On1Adapter::dump(uint32_t* outSize, char* outBuffer) {
Dan Stozac6998d22015-09-24 17:03:36 -0700356 if (outBuffer != nullptr) {
357 auto copiedBytes = mDumpString.copy(outBuffer, *outSize);
358 *outSize = static_cast<uint32_t>(copiedBytes);
359 return;
360 }
361
362 std::stringstream output;
363
364 output << "-- HWC2On1Adapter --\n";
365
366 output << "Adapting to a HWC 1." << static_cast<int>(mHwc1MinorVersion) <<
367 " device\n";
368
369 // Attempt to acquire the lock for 1 second, but proceed without the lock
370 // after that, so we can still get some information if we're deadlocked
Dan Stozafc4e2022016-02-23 11:43:19 -0800371 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex,
372 std::defer_lock);
Dan Stozac6998d22015-09-24 17:03:36 -0700373 lock.try_lock_for(1s);
374
375 if (mCapabilities.empty()) {
376 output << "Capabilities: None\n";
377 } else {
378 output << "Capabilities:\n";
379 for (auto capability : mCapabilities) {
380 output << " " << to_string(capability) << '\n';
381 }
382 }
383
384 output << "Displays:\n";
385 for (const auto& element : mDisplays) {
386 const auto& display = element.second;
387 output << display->dump();
388 }
389 output << '\n';
390
Dan Stozafc4e2022016-02-23 11:43:19 -0800391 // Release the lock before calling into HWC1, and since we no longer require
392 // mutual exclusion to access mCapabilities or mDisplays
393 lock.unlock();
394
Dan Stozac6998d22015-09-24 17:03:36 -0700395 if (mHwc1Device->dump) {
396 output << "HWC1 dump:\n";
397 std::vector<char> hwc1Dump(4096);
398 // Call with size - 1 to preserve a null character at the end
399 mHwc1Device->dump(mHwc1Device, hwc1Dump.data(),
400 static_cast<int>(hwc1Dump.size() - 1));
401 output << hwc1Dump.data();
402 }
403
404 mDumpString = output.str();
405 *outSize = static_cast<uint32_t>(mDumpString.size());
406}
407
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800408uint32_t HWC2On1Adapter::getMaxVirtualDisplayCount() {
Dan Stozac6998d22015-09-24 17:03:36 -0700409 return mHwc1SupportsVirtualDisplays ? 1 : 0;
410}
411
412static bool isValid(Callback descriptor) {
413 switch (descriptor) {
414 case Callback::Hotplug: // Fall-through
415 case Callback::Refresh: // Fall-through
416 case Callback::Vsync: return true;
417 default: return false;
418 }
419}
420
421Error HWC2On1Adapter::registerCallback(Callback descriptor,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800422 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
Dan Stozac6998d22015-09-24 17:03:36 -0700423 if (!isValid(descriptor)) {
424 return Error::BadParameter;
425 }
426
427 ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(),
428 callbackData, pointer);
429
Dan Stozafc4e2022016-02-23 11:43:19 -0800430 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -0700431
432 mCallbacks[descriptor] = {callbackData, pointer};
433
434 bool hasPendingInvalidate = false;
435 std::vector<hwc2_display_t> displayIds;
436 std::vector<std::pair<hwc2_display_t, int64_t>> pendingVsyncs;
437 std::vector<std::pair<hwc2_display_t, int>> pendingHotplugs;
438
439 if (descriptor == Callback::Refresh) {
440 hasPendingInvalidate = mHasPendingInvalidate;
441 if (hasPendingInvalidate) {
442 for (auto& displayPair : mDisplays) {
443 displayIds.emplace_back(displayPair.first);
444 }
445 }
446 mHasPendingInvalidate = false;
447 } else if (descriptor == Callback::Vsync) {
448 for (auto pending : mPendingVsyncs) {
449 auto hwc1DisplayId = pending.first;
450 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
451 ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d",
452 hwc1DisplayId);
453 continue;
454 }
455 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
456 auto timestamp = pending.second;
457 pendingVsyncs.emplace_back(displayId, timestamp);
458 }
459 mPendingVsyncs.clear();
460 } else if (descriptor == Callback::Hotplug) {
461 // Hotplug the primary display
462 pendingHotplugs.emplace_back(mHwc1DisplayMap[HWC_DISPLAY_PRIMARY],
463 static_cast<int32_t>(Connection::Connected));
464
465 for (auto pending : mPendingHotplugs) {
466 auto hwc1DisplayId = pending.first;
467 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
468 ALOGE("hwc1Hotplug: Couldn't find display for HWC1 id %d",
469 hwc1DisplayId);
470 continue;
471 }
472 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
473 auto connected = pending.second;
474 pendingHotplugs.emplace_back(displayId, connected);
475 }
476 }
477
478 // Call pending callbacks without the state lock held
479 lock.unlock();
480
481 if (hasPendingInvalidate) {
482 auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
483 for (auto displayId : displayIds) {
484 refresh(callbackData, displayId);
485 }
486 }
487 if (!pendingVsyncs.empty()) {
488 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
489 for (auto& pendingVsync : pendingVsyncs) {
490 vsync(callbackData, pendingVsync.first, pendingVsync.second);
491 }
492 }
493 if (!pendingHotplugs.empty()) {
494 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
495 for (auto& pendingHotplug : pendingHotplugs) {
496 hotplug(callbackData, pendingHotplug.first, pendingHotplug.second);
497 }
498 }
499 return Error::None;
500}
501
502// Display functions
503
504std::atomic<hwc2_display_t> HWC2On1Adapter::Display::sNextId(1);
505
506HWC2On1Adapter::Display::Display(HWC2On1Adapter& device, HWC2::DisplayType type)
507 : mId(sNextId++),
508 mDevice(device),
Dan Stozac6998d22015-09-24 17:03:36 -0700509 mStateMutex(),
Dan Stozac6998d22015-09-24 17:03:36 -0700510 mHwc1RequestedContents(nullptr),
Dan Stozac6998d22015-09-24 17:03:36 -0700511 mRetireFence(),
512 mChanges(),
513 mHwc1Id(-1),
514 mConfigs(),
515 mActiveConfig(nullptr),
Michael Wrightc75ca512016-07-20 21:34:48 +0100516 mActiveColorMode(static_cast<android_color_mode_t>(-1)),
Dan Stozac6998d22015-09-24 17:03:36 -0700517 mName(),
518 mType(type),
519 mPowerMode(PowerMode::Off),
520 mVsyncEnabled(Vsync::Invalid),
521 mClientTarget(),
522 mOutputBuffer(),
Dan Stoza5df2a862016-03-24 16:19:37 -0700523 mHasColorTransform(false),
Dan Stozafc4e2022016-02-23 11:43:19 -0800524 mLayers(),
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800525 mHwc1LayerMap(),
526 mNumAvailableRects(0),
527 mNextAvailableRect(nullptr),
528 mGeometryChanged(false)
529 {}
Dan Stozac6998d22015-09-24 17:03:36 -0700530
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800531Error HWC2On1Adapter::Display::acceptChanges() {
Dan Stozac6998d22015-09-24 17:03:36 -0700532 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
533
534 if (!mChanges) {
535 ALOGV("[%" PRIu64 "] acceptChanges failed, not validated", mId);
536 return Error::NotValidated;
537 }
538
539 ALOGV("[%" PRIu64 "] acceptChanges", mId);
540
541 for (auto& change : mChanges->getTypeChanges()) {
542 auto layerId = change.first;
543 auto type = change.second;
544 auto layer = mDevice.mLayers[layerId];
545 layer->setCompositionType(type);
546 }
547
548 mChanges->clearTypeChanges();
549
Dan Stozac6998d22015-09-24 17:03:36 -0700550 return Error::None;
551}
552
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800553Error HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId) {
Dan Stozac6998d22015-09-24 17:03:36 -0700554 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
555
556 auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
557 mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
558 *outLayerId = layer->getId();
559 ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId);
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800560 markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -0700561 return Error::None;
562}
563
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800564Error HWC2On1Adapter::Display::destroyLayer(hwc2_layer_t layerId) {
Dan Stozac6998d22015-09-24 17:03:36 -0700565 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
566
567 const auto mapLayer = mDevice.mLayers.find(layerId);
568 if (mapLayer == mDevice.mLayers.end()) {
569 ALOGV("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer",
570 mId, layerId);
571 return Error::BadLayer;
572 }
573 const auto layer = mapLayer->second;
574 mDevice.mLayers.erase(mapLayer);
575 const auto zRange = mLayers.equal_range(layer);
576 for (auto current = zRange.first; current != zRange.second; ++current) {
577 if (**current == *layer) {
578 current = mLayers.erase(current);
579 break;
580 }
581 }
582 ALOGV("[%" PRIu64 "] destroyed layer %" PRIu64, mId, layerId);
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800583 markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -0700584 return Error::None;
585}
586
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800587Error HWC2On1Adapter::Display::getActiveConfig(hwc2_config_t* outConfig) {
Dan Stozac6998d22015-09-24 17:03:36 -0700588 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
589
590 if (!mActiveConfig) {
591 ALOGV("[%" PRIu64 "] getActiveConfig --> %s", mId,
592 to_string(Error::BadConfig).c_str());
593 return Error::BadConfig;
594 }
595 auto configId = mActiveConfig->getId();
596 ALOGV("[%" PRIu64 "] getActiveConfig --> %u", mId, configId);
597 *outConfig = configId;
598 return Error::None;
599}
600
601Error HWC2On1Adapter::Display::getAttribute(hwc2_config_t configId,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800602 Attribute attribute, int32_t* outValue) {
Dan Stozac6998d22015-09-24 17:03:36 -0700603 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
604
605 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
606 ALOGV("[%" PRIu64 "] getAttribute failed: bad config (%u)", mId,
607 configId);
608 return Error::BadConfig;
609 }
610 *outValue = mConfigs[configId]->getAttribute(attribute);
611 ALOGV("[%" PRIu64 "] getAttribute(%u, %s) --> %d", mId, configId,
612 to_string(attribute).c_str(), *outValue);
613 return Error::None;
614}
615
616Error HWC2On1Adapter::Display::getChangedCompositionTypes(
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800617 uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) {
Dan Stozac6998d22015-09-24 17:03:36 -0700618 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
619
620 if (!mChanges) {
621 ALOGE("[%" PRIu64 "] getChangedCompositionTypes failed: not validated",
622 mId);
623 return Error::NotValidated;
624 }
625
626 if ((outLayers == nullptr) || (outTypes == nullptr)) {
627 *outNumElements = mChanges->getTypeChanges().size();
628 return Error::None;
629 }
630
631 uint32_t numWritten = 0;
632 for (const auto& element : mChanges->getTypeChanges()) {
633 if (numWritten == *outNumElements) {
634 break;
635 }
636 auto layerId = element.first;
637 auto intType = static_cast<int32_t>(element.second);
638 ALOGV("Adding %" PRIu64 " %s", layerId,
639 to_string(element.second).c_str());
640 outLayers[numWritten] = layerId;
641 outTypes[numWritten] = intType;
642 ++numWritten;
643 }
644 *outNumElements = numWritten;
645
646 return Error::None;
647}
648
Dan Stoza076ac672016-03-14 10:47:53 -0700649Error HWC2On1Adapter::Display::getColorModes(uint32_t* outNumModes,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800650 int32_t* outModes) {
Dan Stoza076ac672016-03-14 10:47:53 -0700651 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
652
653 if (!outModes) {
654 *outNumModes = mColorModes.size();
655 return Error::None;
656 }
657 uint32_t numModes = std::min(*outNumModes,
658 static_cast<uint32_t>(mColorModes.size()));
659 std::copy_n(mColorModes.cbegin(), numModes, outModes);
660 *outNumModes = numModes;
661 return Error::None;
662}
663
Dan Stozac6998d22015-09-24 17:03:36 -0700664Error HWC2On1Adapter::Display::getConfigs(uint32_t* outNumConfigs,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800665 hwc2_config_t* outConfigs) {
Dan Stozac6998d22015-09-24 17:03:36 -0700666 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
667
668 if (!outConfigs) {
669 *outNumConfigs = mConfigs.size();
670 return Error::None;
671 }
672 uint32_t numWritten = 0;
673 for (const auto& config : mConfigs) {
674 if (numWritten == *outNumConfigs) {
675 break;
676 }
677 outConfigs[numWritten] = config->getId();
678 ++numWritten;
679 }
680 *outNumConfigs = numWritten;
681 return Error::None;
682}
683
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800684Error HWC2On1Adapter::Display::getDozeSupport(int32_t* outSupport) {
Dan Stozac6998d22015-09-24 17:03:36 -0700685 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
686
687 if (mDevice.mHwc1MinorVersion < 4 || mHwc1Id != 0) {
688 *outSupport = 0;
689 } else {
690 *outSupport = 1;
691 }
692 return Error::None;
693}
694
Dan Stozaed40eba2016-03-16 12:33:52 -0700695Error HWC2On1Adapter::Display::getHdrCapabilities(uint32_t* outNumTypes,
696 int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800697 float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
Dan Stozaed40eba2016-03-16 12:33:52 -0700698 // This isn't supported on HWC1, so per the HWC2 header, return numTypes = 0
699 *outNumTypes = 0;
700 return Error::None;
701}
702
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800703Error HWC2On1Adapter::Display::getName(uint32_t* outSize, char* outName) {
Dan Stozac6998d22015-09-24 17:03:36 -0700704 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
705
706 if (!outName) {
707 *outSize = mName.size();
708 return Error::None;
709 }
710 auto numCopied = mName.copy(outName, *outSize);
711 *outSize = numCopied;
712 return Error::None;
713}
714
715Error HWC2On1Adapter::Display::getReleaseFences(uint32_t* outNumElements,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800716 hwc2_layer_t* outLayers, int32_t* outFences) {
Dan Stozac6998d22015-09-24 17:03:36 -0700717 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
718
719 uint32_t numWritten = 0;
720 bool outputsNonNull = (outLayers != nullptr) && (outFences != nullptr);
721 for (const auto& layer : mLayers) {
722 if (outputsNonNull && (numWritten == *outNumElements)) {
723 break;
724 }
725
726 auto releaseFence = layer->getReleaseFence();
727 if (releaseFence != Fence::NO_FENCE) {
728 if (outputsNonNull) {
729 outLayers[numWritten] = layer->getId();
730 outFences[numWritten] = releaseFence->dup();
731 }
732 ++numWritten;
733 }
734 }
735 *outNumElements = numWritten;
736
737 return Error::None;
738}
739
740Error HWC2On1Adapter::Display::getRequests(int32_t* outDisplayRequests,
741 uint32_t* outNumElements, hwc2_layer_t* outLayers,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800742 int32_t* outLayerRequests) {
Dan Stozac6998d22015-09-24 17:03:36 -0700743 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
744
745 if (!mChanges) {
746 return Error::NotValidated;
747 }
748
749 if (outLayers == nullptr || outLayerRequests == nullptr) {
750 *outNumElements = mChanges->getNumLayerRequests();
751 return Error::None;
752 }
753
Fabien Sanglard601938c2016-11-29 11:10:40 -0800754 // Display requests (HWC2::DisplayRequest) are not supported by hwc1:
755 // A hwc1 has always zero requests for the client.
756 *outDisplayRequests = 0;
757
Dan Stozac6998d22015-09-24 17:03:36 -0700758 uint32_t numWritten = 0;
759 for (const auto& request : mChanges->getLayerRequests()) {
760 if (numWritten == *outNumElements) {
761 break;
762 }
763 outLayers[numWritten] = request.first;
764 outLayerRequests[numWritten] = static_cast<int32_t>(request.second);
765 ++numWritten;
766 }
767
768 return Error::None;
769}
770
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800771Error HWC2On1Adapter::Display::getType(int32_t* outType) {
Dan Stozac6998d22015-09-24 17:03:36 -0700772 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
773
774 *outType = static_cast<int32_t>(mType);
775 return Error::None;
776}
777
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800778Error HWC2On1Adapter::Display::present(int32_t* outRetireFence) {
Dan Stozac6998d22015-09-24 17:03:36 -0700779 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
780
781 if (mChanges) {
782 Error error = mDevice.setAllDisplays();
783 if (error != Error::None) {
784 ALOGE("[%" PRIu64 "] present: setAllDisplaysFailed (%s)", mId,
785 to_string(error).c_str());
786 return error;
787 }
788 }
789
790 *outRetireFence = mRetireFence.get()->dup();
791 ALOGV("[%" PRIu64 "] present returning retire fence %d", mId,
792 *outRetireFence);
793
794 return Error::None;
795}
796
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800797Error HWC2On1Adapter::Display::setActiveConfig(hwc2_config_t configId) {
Dan Stozac6998d22015-09-24 17:03:36 -0700798 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
799
800 auto config = getConfig(configId);
801 if (!config) {
802 return Error::BadConfig;
803 }
Dan Stoza076ac672016-03-14 10:47:53 -0700804 if (config == mActiveConfig) {
805 return Error::None;
Dan Stozac6998d22015-09-24 17:03:36 -0700806 }
Dan Stoza076ac672016-03-14 10:47:53 -0700807
808 if (mDevice.mHwc1MinorVersion >= 4) {
809 uint32_t hwc1Id = 0;
810 auto error = config->getHwc1IdForColorMode(mActiveColorMode, &hwc1Id);
811 if (error != Error::None) {
812 return error;
813 }
814
815 int intError = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
816 mHwc1Id, static_cast<int>(hwc1Id));
817 if (intError != 0) {
818 ALOGE("setActiveConfig: Failed to set active config on HWC1 (%d)",
819 intError);
820 return Error::BadConfig;
821 }
822 mActiveConfig = config;
823 }
824
Dan Stozac6998d22015-09-24 17:03:36 -0700825 return Error::None;
826}
827
828Error HWC2On1Adapter::Display::setClientTarget(buffer_handle_t target,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800829 int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
Dan Stozac6998d22015-09-24 17:03:36 -0700830 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
831
832 ALOGV("[%" PRIu64 "] setClientTarget(%p, %d)", mId, target, acquireFence);
833 mClientTarget.setBuffer(target);
834 mClientTarget.setFence(acquireFence);
Dan Stoza5cf424b2016-05-20 14:02:39 -0700835 // dataspace and damage can't be used by HWC1, so ignore them
Dan Stozac6998d22015-09-24 17:03:36 -0700836 return Error::None;
837}
838
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800839Error HWC2On1Adapter::Display::setColorMode(android_color_mode_t mode) {
Dan Stoza076ac672016-03-14 10:47:53 -0700840 std::unique_lock<std::recursive_mutex> lock (mStateMutex);
841
842 ALOGV("[%" PRIu64 "] setColorMode(%d)", mId, mode);
843
844 if (mode == mActiveColorMode) {
845 return Error::None;
846 }
847 if (mColorModes.count(mode) == 0) {
848 ALOGE("[%" PRIu64 "] Mode %d not found in mColorModes", mId, mode);
849 return Error::Unsupported;
850 }
851
852 uint32_t hwc1Config = 0;
853 auto error = mActiveConfig->getHwc1IdForColorMode(mode, &hwc1Config);
854 if (error != Error::None) {
855 return error;
856 }
857
858 ALOGV("[%" PRIu64 "] Setting HWC1 config %u", mId, hwc1Config);
859 int intError = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
860 mHwc1Id, hwc1Config);
861 if (intError != 0) {
862 ALOGE("[%" PRIu64 "] Failed to set HWC1 config (%d)", mId, intError);
863 return Error::Unsupported;
864 }
865
866 mActiveColorMode = mode;
867 return Error::None;
868}
869
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800870Error HWC2On1Adapter::Display::setColorTransform(android_color_transform_t hint) {
Dan Stoza5df2a862016-03-24 16:19:37 -0700871 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
872
873 ALOGV("%" PRIu64 "] setColorTransform(%d)", mId,
874 static_cast<int32_t>(hint));
875 mHasColorTransform = (hint != HAL_COLOR_TRANSFORM_IDENTITY);
876 return Error::None;
877}
878
Dan Stozac6998d22015-09-24 17:03:36 -0700879Error HWC2On1Adapter::Display::setOutputBuffer(buffer_handle_t buffer,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800880 int32_t releaseFence) {
Dan Stozac6998d22015-09-24 17:03:36 -0700881 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
882
883 ALOGV("[%" PRIu64 "] setOutputBuffer(%p, %d)", mId, buffer, releaseFence);
884 mOutputBuffer.setBuffer(buffer);
885 mOutputBuffer.setFence(releaseFence);
886 return Error::None;
887}
888
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800889static bool isValid(PowerMode mode) {
Dan Stozac6998d22015-09-24 17:03:36 -0700890 switch (mode) {
891 case PowerMode::Off: // Fall-through
892 case PowerMode::DozeSuspend: // Fall-through
893 case PowerMode::Doze: // Fall-through
894 case PowerMode::On: return true;
Dan Stozac6998d22015-09-24 17:03:36 -0700895 }
896}
897
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800898static int getHwc1PowerMode(PowerMode mode) {
Dan Stozac6998d22015-09-24 17:03:36 -0700899 switch (mode) {
900 case PowerMode::Off: return HWC_POWER_MODE_OFF;
901 case PowerMode::DozeSuspend: return HWC_POWER_MODE_DOZE_SUSPEND;
902 case PowerMode::Doze: return HWC_POWER_MODE_DOZE;
903 case PowerMode::On: return HWC_POWER_MODE_NORMAL;
Dan Stozac6998d22015-09-24 17:03:36 -0700904 }
905}
906
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800907Error HWC2On1Adapter::Display::setPowerMode(PowerMode mode) {
Dan Stozac6998d22015-09-24 17:03:36 -0700908 if (!isValid(mode)) {
909 return Error::BadParameter;
910 }
911 if (mode == mPowerMode) {
912 return Error::None;
913 }
914
915 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
916
917 int error = 0;
918 if (mDevice.mHwc1MinorVersion < 4) {
919 error = mDevice.mHwc1Device->blank(mDevice.mHwc1Device, mHwc1Id,
920 mode == PowerMode::Off);
921 } else {
922 error = mDevice.mHwc1Device->setPowerMode(mDevice.mHwc1Device,
923 mHwc1Id, getHwc1PowerMode(mode));
924 }
925 ALOGE_IF(error != 0, "setPowerMode: Failed to set power mode on HWC1 (%d)",
926 error);
927
928 ALOGV("[%" PRIu64 "] setPowerMode(%s)", mId, to_string(mode).c_str());
929 mPowerMode = mode;
930 return Error::None;
931}
932
933static bool isValid(Vsync enable) {
934 switch (enable) {
935 case Vsync::Enable: // Fall-through
936 case Vsync::Disable: return true;
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800937 case Vsync::Invalid: return false;
Dan Stozac6998d22015-09-24 17:03:36 -0700938 }
939}
940
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800941Error HWC2On1Adapter::Display::setVsyncEnabled(Vsync enable) {
Dan Stozac6998d22015-09-24 17:03:36 -0700942 if (!isValid(enable)) {
943 return Error::BadParameter;
944 }
945 if (enable == mVsyncEnabled) {
946 return Error::None;
947 }
948
949 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
950
951 int error = mDevice.mHwc1Device->eventControl(mDevice.mHwc1Device,
952 mHwc1Id, HWC_EVENT_VSYNC, enable == Vsync::Enable);
953 ALOGE_IF(error != 0, "setVsyncEnabled: Failed to set vsync on HWC1 (%d)",
954 error);
955
956 mVsyncEnabled = enable;
957 return Error::None;
958}
959
960Error HWC2On1Adapter::Display::validate(uint32_t* outNumTypes,
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800961 uint32_t* outNumRequests) {
Dan Stozac6998d22015-09-24 17:03:36 -0700962 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
963
964 ALOGV("[%" PRIu64 "] Entering validate", mId);
965
966 if (!mChanges) {
967 if (!mDevice.prepareAllDisplays()) {
968 return Error::BadDisplay;
969 }
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800970 } else {
971 ALOGE("Validate was called more than once!");
Dan Stozac6998d22015-09-24 17:03:36 -0700972 }
973
974 *outNumTypes = mChanges->getNumTypes();
975 *outNumRequests = mChanges->getNumLayerRequests();
976 ALOGV("[%" PRIu64 "] validate --> %u types, %u requests", mId, *outNumTypes,
977 *outNumRequests);
978 for (auto request : mChanges->getTypeChanges()) {
979 ALOGV("Layer %" PRIu64 " --> %s", request.first,
980 to_string(request.second).c_str());
981 }
982 return *outNumTypes > 0 ? Error::HasChanges : Error::None;
983}
984
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800985Error HWC2On1Adapter::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
Dan Stozac6998d22015-09-24 17:03:36 -0700986 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
987
988 const auto mapLayer = mDevice.mLayers.find(layerId);
989 if (mapLayer == mDevice.mLayers.end()) {
990 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer", mId);
991 return Error::BadLayer;
992 }
993
994 const auto layer = mapLayer->second;
995 const auto zRange = mLayers.equal_range(layer);
996 bool layerOnDisplay = false;
997 for (auto current = zRange.first; current != zRange.second; ++current) {
998 if (**current == *layer) {
999 if ((*current)->getZ() == z) {
1000 // Don't change anything if the Z hasn't changed
1001 return Error::None;
1002 }
1003 current = mLayers.erase(current);
1004 layerOnDisplay = true;
1005 break;
1006 }
1007 }
1008
1009 if (!layerOnDisplay) {
1010 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display",
1011 mId);
1012 return Error::BadLayer;
1013 }
1014
1015 layer->setZ(z);
1016 mLayers.emplace(std::move(layer));
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001017 markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001018
1019 return Error::None;
1020}
1021
Dan Stoza076ac672016-03-14 10:47:53 -07001022static constexpr uint32_t ATTRIBUTES_WITH_COLOR[] = {
1023 HWC_DISPLAY_VSYNC_PERIOD,
1024 HWC_DISPLAY_WIDTH,
1025 HWC_DISPLAY_HEIGHT,
1026 HWC_DISPLAY_DPI_X,
1027 HWC_DISPLAY_DPI_Y,
1028 HWC_DISPLAY_COLOR_TRANSFORM,
1029 HWC_DISPLAY_NO_ATTRIBUTE,
1030};
1031
1032static constexpr uint32_t ATTRIBUTES_WITHOUT_COLOR[] = {
Dan Stozac6998d22015-09-24 17:03:36 -07001033 HWC_DISPLAY_VSYNC_PERIOD,
1034 HWC_DISPLAY_WIDTH,
1035 HWC_DISPLAY_HEIGHT,
1036 HWC_DISPLAY_DPI_X,
1037 HWC_DISPLAY_DPI_Y,
1038 HWC_DISPLAY_NO_ATTRIBUTE,
1039};
Dan Stozac6998d22015-09-24 17:03:36 -07001040
Dan Stoza076ac672016-03-14 10:47:53 -07001041static constexpr size_t NUM_ATTRIBUTES_WITH_COLOR =
1042 sizeof(ATTRIBUTES_WITH_COLOR) / sizeof(uint32_t);
1043static_assert(sizeof(ATTRIBUTES_WITH_COLOR) > sizeof(ATTRIBUTES_WITHOUT_COLOR),
1044 "Attribute tables have unexpected sizes");
1045
1046static constexpr uint32_t ATTRIBUTE_MAP_WITH_COLOR[] = {
1047 6, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1048 0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1049 1, // HWC_DISPLAY_WIDTH = 2,
1050 2, // HWC_DISPLAY_HEIGHT = 3,
1051 3, // HWC_DISPLAY_DPI_X = 4,
1052 4, // HWC_DISPLAY_DPI_Y = 5,
1053 5, // HWC_DISPLAY_COLOR_TRANSFORM = 6,
1054};
1055
1056static constexpr uint32_t ATTRIBUTE_MAP_WITHOUT_COLOR[] = {
Dan Stozac6998d22015-09-24 17:03:36 -07001057 5, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1058 0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1059 1, // HWC_DISPLAY_WIDTH = 2,
1060 2, // HWC_DISPLAY_HEIGHT = 3,
1061 3, // HWC_DISPLAY_DPI_X = 4,
1062 4, // HWC_DISPLAY_DPI_Y = 5,
1063};
1064
1065template <uint32_t attribute>
1066static constexpr bool attributesMatch()
1067{
Dan Stoza076ac672016-03-14 10:47:53 -07001068 bool match = (attribute ==
1069 ATTRIBUTES_WITH_COLOR[ATTRIBUTE_MAP_WITH_COLOR[attribute]]);
1070 if (attribute == HWC_DISPLAY_COLOR_TRANSFORM) {
1071 return match;
1072 }
1073
1074 return match && (attribute ==
1075 ATTRIBUTES_WITHOUT_COLOR[ATTRIBUTE_MAP_WITHOUT_COLOR[attribute]]);
Dan Stozac6998d22015-09-24 17:03:36 -07001076}
1077static_assert(attributesMatch<HWC_DISPLAY_VSYNC_PERIOD>(),
1078 "Tables out of sync");
1079static_assert(attributesMatch<HWC_DISPLAY_WIDTH>(), "Tables out of sync");
1080static_assert(attributesMatch<HWC_DISPLAY_HEIGHT>(), "Tables out of sync");
1081static_assert(attributesMatch<HWC_DISPLAY_DPI_X>(), "Tables out of sync");
1082static_assert(attributesMatch<HWC_DISPLAY_DPI_Y>(), "Tables out of sync");
Dan Stoza076ac672016-03-14 10:47:53 -07001083static_assert(attributesMatch<HWC_DISPLAY_COLOR_TRANSFORM>(),
1084 "Tables out of sync");
Dan Stozac6998d22015-09-24 17:03:36 -07001085
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001086void HWC2On1Adapter::Display::populateConfigs() {
Dan Stozac6998d22015-09-24 17:03:36 -07001087 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1088
1089 ALOGV("[%" PRIu64 "] populateConfigs", mId);
1090
1091 if (mHwc1Id == -1) {
1092 ALOGE("populateConfigs: HWC1 ID not set");
1093 return;
1094 }
1095
1096 const size_t MAX_NUM_CONFIGS = 128;
1097 uint32_t configs[MAX_NUM_CONFIGS] = {};
1098 size_t numConfigs = MAX_NUM_CONFIGS;
1099 mDevice.mHwc1Device->getDisplayConfigs(mDevice.mHwc1Device, mHwc1Id,
1100 configs, &numConfigs);
1101
1102 for (size_t c = 0; c < numConfigs; ++c) {
1103 uint32_t hwc1ConfigId = configs[c];
Dan Stoza076ac672016-03-14 10:47:53 -07001104 auto newConfig = std::make_shared<Config>(*this);
Dan Stozac6998d22015-09-24 17:03:36 -07001105
Dan Stoza076ac672016-03-14 10:47:53 -07001106 int32_t values[NUM_ATTRIBUTES_WITH_COLOR] = {};
1107 bool hasColor = true;
1108 auto result = mDevice.mHwc1Device->getDisplayAttributes(
1109 mDevice.mHwc1Device, mHwc1Id, hwc1ConfigId,
1110 ATTRIBUTES_WITH_COLOR, values);
1111 if (result != 0) {
1112 mDevice.mHwc1Device->getDisplayAttributes(mDevice.mHwc1Device,
1113 mHwc1Id, hwc1ConfigId, ATTRIBUTES_WITHOUT_COLOR, values);
1114 hasColor = false;
Dan Stozac6998d22015-09-24 17:03:36 -07001115 }
Dan Stoza076ac672016-03-14 10:47:53 -07001116
1117 auto attributeMap = hasColor ?
1118 ATTRIBUTE_MAP_WITH_COLOR : ATTRIBUTE_MAP_WITHOUT_COLOR;
1119
1120 newConfig->setAttribute(Attribute::VsyncPeriod,
1121 values[attributeMap[HWC_DISPLAY_VSYNC_PERIOD]]);
1122 newConfig->setAttribute(Attribute::Width,
1123 values[attributeMap[HWC_DISPLAY_WIDTH]]);
1124 newConfig->setAttribute(Attribute::Height,
1125 values[attributeMap[HWC_DISPLAY_HEIGHT]]);
1126 newConfig->setAttribute(Attribute::DpiX,
1127 values[attributeMap[HWC_DISPLAY_DPI_X]]);
1128 newConfig->setAttribute(Attribute::DpiY,
1129 values[attributeMap[HWC_DISPLAY_DPI_Y]]);
1130 if (hasColor) {
Michael Wright28f24d02016-07-12 13:30:53 -07001131 // In HWC1, color modes are referred to as color transforms. To avoid confusion with
1132 // the HWC2 concept of color transforms, we internally refer to them as color modes for
1133 // both HWC1 and 2.
1134 newConfig->setAttribute(ColorMode,
Dan Stoza076ac672016-03-14 10:47:53 -07001135 values[attributeMap[HWC_DISPLAY_COLOR_TRANSFORM]]);
1136 }
1137
Michael Wright28f24d02016-07-12 13:30:53 -07001138 // We can only do this after attempting to read the color mode
Dan Stoza076ac672016-03-14 10:47:53 -07001139 newConfig->setHwc1Id(hwc1ConfigId);
1140
1141 for (auto& existingConfig : mConfigs) {
1142 if (existingConfig->merge(*newConfig)) {
1143 ALOGV("Merged config %d with existing config %u: %s",
1144 hwc1ConfigId, existingConfig->getId(),
1145 existingConfig->toString().c_str());
1146 newConfig.reset();
1147 break;
1148 }
1149 }
1150
1151 // If it wasn't merged with any existing config, add it to the end
1152 if (newConfig) {
1153 newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
1154 ALOGV("Found new config %u: %s", newConfig->getId(),
1155 newConfig->toString().c_str());
1156 mConfigs.emplace_back(std::move(newConfig));
1157 }
Dan Stozac6998d22015-09-24 17:03:36 -07001158 }
Dan Stoza076ac672016-03-14 10:47:53 -07001159
1160 initializeActiveConfig();
1161 populateColorModes();
Dan Stozac6998d22015-09-24 17:03:36 -07001162}
1163
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001164void HWC2On1Adapter::Display::populateConfigs(uint32_t width, uint32_t height) {
Dan Stozac6998d22015-09-24 17:03:36 -07001165 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1166
Dan Stoza076ac672016-03-14 10:47:53 -07001167 mConfigs.emplace_back(std::make_shared<Config>(*this));
Dan Stozac6998d22015-09-24 17:03:36 -07001168 auto& config = mConfigs[0];
1169
1170 config->setAttribute(Attribute::Width, static_cast<int32_t>(width));
1171 config->setAttribute(Attribute::Height, static_cast<int32_t>(height));
Dan Stoza076ac672016-03-14 10:47:53 -07001172 config->setHwc1Id(0);
1173 config->setId(0);
Dan Stozac6998d22015-09-24 17:03:36 -07001174 mActiveConfig = config;
1175}
1176
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001177bool HWC2On1Adapter::Display::prepare() {
Dan Stozac6998d22015-09-24 17:03:36 -07001178 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1179
1180 // Only prepare display contents for displays HWC1 knows about
1181 if (mHwc1Id == -1) {
1182 return true;
1183 }
1184
1185 // It doesn't make sense to prepare a display for which there is no active
1186 // config, so return early
1187 if (!mActiveConfig) {
1188 ALOGE("[%" PRIu64 "] Attempted to prepare, but no config active", mId);
1189 return false;
1190 }
1191
1192 ALOGV("[%" PRIu64 "] Entering prepare", mId);
1193
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001194 allocateRequestedContents();
1195 assignHwc1LayerIds();
Dan Stozac6998d22015-09-24 17:03:36 -07001196
1197 mHwc1RequestedContents->retireFenceFd = -1;
1198 mHwc1RequestedContents->flags = 0;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001199 if (mGeometryChanged) {
Dan Stozac6998d22015-09-24 17:03:36 -07001200 mHwc1RequestedContents->flags |= HWC_GEOMETRY_CHANGED;
1201 }
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001202 mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer();
1203 mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence();
Dan Stozac6998d22015-09-24 17:03:36 -07001204
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001205 // +1 is for framebuffer target layer.
1206 mHwc1RequestedContents->numHwLayers = mLayers.size() + 1;
Dan Stozac6998d22015-09-24 17:03:36 -07001207 for (auto& layer : mLayers) {
1208 auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
1209 hwc1Layer.releaseFenceFd = -1;
Fabien Sanglard16ab8192017-01-31 12:12:10 -08001210 hwc1Layer.acquireFenceFd = -1;
Fabien Sanglard999a7fd2017-02-02 16:59:44 -08001211 ALOGV("Applying states for layer %" PRIu64 " ", layer->getId());
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001212 layer->applyState(hwc1Layer);
Dan Stozac6998d22015-09-24 17:03:36 -07001213 }
1214
Dan Stozac6998d22015-09-24 17:03:36 -07001215 prepareFramebufferTarget();
1216
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001217 resetGeometryMarker();
1218
Dan Stozac6998d22015-09-24 17:03:36 -07001219 return true;
1220}
1221
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001222void HWC2On1Adapter::Display::generateChanges() {
Dan Stozac6998d22015-09-24 17:03:36 -07001223 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1224
Dan Stozac6998d22015-09-24 17:03:36 -07001225 mChanges.reset(new Changes);
1226
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001227 size_t numLayers = mHwc1RequestedContents->numHwLayers;
Dan Stozac6998d22015-09-24 17:03:36 -07001228 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001229 const auto& receivedLayer = mHwc1RequestedContents->hwLayers[hwc1Id];
Dan Stozac6998d22015-09-24 17:03:36 -07001230 if (mHwc1LayerMap.count(hwc1Id) == 0) {
1231 ALOGE_IF(receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001232 "generateChanges: HWC1 layer %zd doesn't have a"
Dan Stozac6998d22015-09-24 17:03:36 -07001233 " matching HWC2 layer, and isn't the framebuffer target",
1234 hwc1Id);
1235 continue;
1236 }
1237
1238 Layer& layer = *mHwc1LayerMap[hwc1Id];
1239 updateTypeChanges(receivedLayer, layer);
1240 updateLayerRequests(receivedLayer, layer);
1241 }
1242}
1243
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001244bool HWC2On1Adapter::Display::hasChanges() const {
Dan Stozac6998d22015-09-24 17:03:36 -07001245 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1246 return mChanges != nullptr;
1247}
1248
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001249Error HWC2On1Adapter::Display::set(hwc_display_contents_1& hwcContents) {
Dan Stozac6998d22015-09-24 17:03:36 -07001250 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1251
1252 if (!mChanges || (mChanges->getNumTypes() > 0)) {
1253 ALOGE("[%" PRIu64 "] set failed: not validated", mId);
1254 return Error::NotValidated;
1255 }
1256
1257 // Set up the client/framebuffer target
1258 auto numLayers = hwcContents.numHwLayers;
1259
1260 // Close acquire fences on FRAMEBUFFER layers, since they will not be used
1261 // by HWC
1262 for (size_t l = 0; l < numLayers - 1; ++l) {
1263 auto& layer = hwcContents.hwLayers[l];
1264 if (layer.compositionType == HWC_FRAMEBUFFER) {
1265 ALOGV("Closing fence %d for layer %zd", layer.acquireFenceFd, l);
1266 close(layer.acquireFenceFd);
1267 layer.acquireFenceFd = -1;
1268 }
1269 }
1270
1271 auto& clientTargetLayer = hwcContents.hwLayers[numLayers - 1];
1272 if (clientTargetLayer.compositionType == HWC_FRAMEBUFFER_TARGET) {
1273 clientTargetLayer.handle = mClientTarget.getBuffer();
1274 clientTargetLayer.acquireFenceFd = mClientTarget.getFence();
1275 } else {
1276 ALOGE("[%" PRIu64 "] set: last HWC layer wasn't FRAMEBUFFER_TARGET",
1277 mId);
1278 }
1279
1280 mChanges.reset();
1281
1282 return Error::None;
1283}
1284
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001285void HWC2On1Adapter::Display::addRetireFence(int fenceFd) {
Dan Stozac6998d22015-09-24 17:03:36 -07001286 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1287 mRetireFence.add(fenceFd);
1288}
1289
1290void HWC2On1Adapter::Display::addReleaseFences(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001291 const hwc_display_contents_1_t& hwcContents) {
Dan Stozac6998d22015-09-24 17:03:36 -07001292 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1293
1294 size_t numLayers = hwcContents.numHwLayers;
1295 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1296 const auto& receivedLayer = hwcContents.hwLayers[hwc1Id];
1297 if (mHwc1LayerMap.count(hwc1Id) == 0) {
1298 if (receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET) {
1299 ALOGE("addReleaseFences: HWC1 layer %zd doesn't have a"
1300 " matching HWC2 layer, and isn't the framebuffer"
1301 " target", hwc1Id);
1302 }
1303 // Close the framebuffer target release fence since we will use the
1304 // display retire fence instead
1305 if (receivedLayer.releaseFenceFd != -1) {
1306 close(receivedLayer.releaseFenceFd);
1307 }
1308 continue;
1309 }
1310
1311 Layer& layer = *mHwc1LayerMap[hwc1Id];
1312 ALOGV("Adding release fence %d to layer %" PRIu64,
1313 receivedLayer.releaseFenceFd, layer.getId());
1314 layer.addReleaseFence(receivedLayer.releaseFenceFd);
1315 }
1316}
1317
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001318bool HWC2On1Adapter::Display::hasColorTransform() const {
Dan Stoza5df2a862016-03-24 16:19:37 -07001319 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1320 return mHasColorTransform;
1321}
1322
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001323static std::string hwc1CompositionString(int32_t type) {
Dan Stozac6998d22015-09-24 17:03:36 -07001324 switch (type) {
1325 case HWC_FRAMEBUFFER: return "Framebuffer";
1326 case HWC_OVERLAY: return "Overlay";
1327 case HWC_BACKGROUND: return "Background";
1328 case HWC_FRAMEBUFFER_TARGET: return "FramebufferTarget";
1329 case HWC_SIDEBAND: return "Sideband";
1330 case HWC_CURSOR_OVERLAY: return "CursorOverlay";
1331 default:
1332 return std::string("Unknown (") + std::to_string(type) + ")";
1333 }
1334}
1335
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001336static std::string hwc1TransformString(int32_t transform) {
Dan Stozac6998d22015-09-24 17:03:36 -07001337 switch (transform) {
1338 case 0: return "None";
1339 case HWC_TRANSFORM_FLIP_H: return "FlipH";
1340 case HWC_TRANSFORM_FLIP_V: return "FlipV";
1341 case HWC_TRANSFORM_ROT_90: return "Rotate90";
1342 case HWC_TRANSFORM_ROT_180: return "Rotate180";
1343 case HWC_TRANSFORM_ROT_270: return "Rotate270";
1344 case HWC_TRANSFORM_FLIP_H_ROT_90: return "FlipHRotate90";
1345 case HWC_TRANSFORM_FLIP_V_ROT_90: return "FlipVRotate90";
1346 default:
1347 return std::string("Unknown (") + std::to_string(transform) + ")";
1348 }
1349}
1350
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001351static std::string hwc1BlendModeString(int32_t mode) {
Dan Stozac6998d22015-09-24 17:03:36 -07001352 switch (mode) {
1353 case HWC_BLENDING_NONE: return "None";
1354 case HWC_BLENDING_PREMULT: return "Premultiplied";
1355 case HWC_BLENDING_COVERAGE: return "Coverage";
1356 default:
1357 return std::string("Unknown (") + std::to_string(mode) + ")";
1358 }
1359}
1360
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001361static std::string rectString(hwc_rect_t rect) {
Dan Stozac6998d22015-09-24 17:03:36 -07001362 std::stringstream output;
1363 output << "[" << rect.left << ", " << rect.top << ", ";
1364 output << rect.right << ", " << rect.bottom << "]";
1365 return output.str();
1366}
1367
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001368static std::string approximateFloatString(float f) {
Dan Stozac6998d22015-09-24 17:03:36 -07001369 if (static_cast<int32_t>(f) == f) {
1370 return std::to_string(static_cast<int32_t>(f));
1371 }
1372 int32_t truncated = static_cast<int32_t>(f * 10);
1373 bool approximate = (static_cast<float>(truncated) != f * 10);
1374 const size_t BUFFER_SIZE = 32;
1375 char buffer[BUFFER_SIZE] = {};
1376 auto bytesWritten = snprintf(buffer, BUFFER_SIZE,
1377 "%s%.1f", approximate ? "~" : "", f);
1378 return std::string(buffer, bytesWritten);
1379}
1380
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001381static std::string frectString(hwc_frect_t frect) {
Dan Stozac6998d22015-09-24 17:03:36 -07001382 std::stringstream output;
1383 output << "[" << approximateFloatString(frect.left) << ", ";
1384 output << approximateFloatString(frect.top) << ", ";
1385 output << approximateFloatString(frect.right) << ", ";
1386 output << approximateFloatString(frect.bottom) << "]";
1387 return output.str();
1388}
1389
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001390static std::string colorString(hwc_color_t color) {
Dan Stozac6998d22015-09-24 17:03:36 -07001391 std::stringstream output;
1392 output << "RGBA [";
1393 output << static_cast<int32_t>(color.r) << ", ";
1394 output << static_cast<int32_t>(color.g) << ", ";
1395 output << static_cast<int32_t>(color.b) << ", ";
1396 output << static_cast<int32_t>(color.a) << "]";
1397 return output.str();
1398}
1399
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001400static std::string alphaString(float f) {
Dan Stozac6998d22015-09-24 17:03:36 -07001401 const size_t BUFFER_SIZE = 8;
1402 char buffer[BUFFER_SIZE] = {};
1403 auto bytesWritten = snprintf(buffer, BUFFER_SIZE, "%.3f", f);
1404 return std::string(buffer, bytesWritten);
1405}
1406
1407static std::string to_string(const hwc_layer_1_t& hwcLayer,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001408 int32_t hwc1MinorVersion) {
Dan Stozac6998d22015-09-24 17:03:36 -07001409 const char* fill = " ";
1410
1411 std::stringstream output;
1412
1413 output << " Composition: " <<
1414 hwc1CompositionString(hwcLayer.compositionType);
1415
1416 if (hwcLayer.compositionType == HWC_BACKGROUND) {
1417 output << " Color: " << colorString(hwcLayer.backgroundColor) << '\n';
1418 } else if (hwcLayer.compositionType == HWC_SIDEBAND) {
1419 output << " Stream: " << hwcLayer.sidebandStream << '\n';
1420 } else {
1421 output << " Buffer: " << hwcLayer.handle << "/" <<
1422 hwcLayer.acquireFenceFd << '\n';
1423 }
1424
1425 output << fill << "Display frame: " << rectString(hwcLayer.displayFrame) <<
1426 '\n';
1427
1428 output << fill << "Source crop: ";
1429 if (hwc1MinorVersion >= 3) {
1430 output << frectString(hwcLayer.sourceCropf) << '\n';
1431 } else {
1432 output << rectString(hwcLayer.sourceCropi) << '\n';
1433 }
1434
1435 output << fill << "Transform: " << hwc1TransformString(hwcLayer.transform);
1436 output << " Blend mode: " << hwc1BlendModeString(hwcLayer.blending);
1437 if (hwcLayer.planeAlpha != 0xFF) {
1438 output << " Alpha: " << alphaString(hwcLayer.planeAlpha / 255.0f);
1439 }
1440 output << '\n';
1441
1442 if (hwcLayer.hints != 0) {
1443 output << fill << "Hints:";
1444 if ((hwcLayer.hints & HWC_HINT_TRIPLE_BUFFER) != 0) {
1445 output << " TripleBuffer";
1446 }
1447 if ((hwcLayer.hints & HWC_HINT_CLEAR_FB) != 0) {
1448 output << " ClearFB";
1449 }
1450 output << '\n';
1451 }
1452
1453 if (hwcLayer.flags != 0) {
1454 output << fill << "Flags:";
1455 if ((hwcLayer.flags & HWC_SKIP_LAYER) != 0) {
1456 output << " SkipLayer";
1457 }
1458 if ((hwcLayer.flags & HWC_IS_CURSOR_LAYER) != 0) {
1459 output << " IsCursorLayer";
1460 }
1461 output << '\n';
1462 }
1463
1464 return output.str();
1465}
1466
1467static std::string to_string(const hwc_display_contents_1_t& hwcContents,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001468 int32_t hwc1MinorVersion) {
Dan Stozac6998d22015-09-24 17:03:36 -07001469 const char* fill = " ";
1470
1471 std::stringstream output;
1472 output << fill << "Geometry changed: " <<
1473 ((hwcContents.flags & HWC_GEOMETRY_CHANGED) != 0 ? "Y\n" : "N\n");
1474
1475 output << fill << hwcContents.numHwLayers << " Layer" <<
1476 ((hwcContents.numHwLayers == 1) ? "\n" : "s\n");
1477 for (size_t layer = 0; layer < hwcContents.numHwLayers; ++layer) {
1478 output << fill << " Layer " << layer;
1479 output << to_string(hwcContents.hwLayers[layer], hwc1MinorVersion);
1480 }
1481
1482 if (hwcContents.outbuf != nullptr) {
1483 output << fill << "Output buffer: " << hwcContents.outbuf << "/" <<
1484 hwcContents.outbufAcquireFenceFd << '\n';
1485 }
1486
1487 return output.str();
1488}
1489
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001490std::string HWC2On1Adapter::Display::dump() const {
Dan Stozac6998d22015-09-24 17:03:36 -07001491 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1492
1493 std::stringstream output;
1494
1495 output << " Display " << mId << ": ";
1496 output << to_string(mType) << " ";
1497 output << "HWC1 ID: " << mHwc1Id << " ";
1498 output << "Power mode: " << to_string(mPowerMode) << " ";
1499 output << "Vsync: " << to_string(mVsyncEnabled) << '\n';
1500
Dan Stoza076ac672016-03-14 10:47:53 -07001501 output << " Color modes [active]:";
1502 for (const auto& mode : mColorModes) {
1503 if (mode == mActiveColorMode) {
1504 output << " [" << mode << ']';
Dan Stozac6998d22015-09-24 17:03:36 -07001505 } else {
Dan Stoza076ac672016-03-14 10:47:53 -07001506 output << " " << mode;
Dan Stozac6998d22015-09-24 17:03:36 -07001507 }
1508 }
1509 output << '\n';
1510
Dan Stoza076ac672016-03-14 10:47:53 -07001511 output << " " << mConfigs.size() << " Config" <<
1512 (mConfigs.size() == 1 ? "" : "s") << " (* active)\n";
1513 for (const auto& config : mConfigs) {
1514 output << (config == mActiveConfig ? " * " : " ");
1515 output << config->toString(true) << '\n';
1516 }
1517
Dan Stozac6998d22015-09-24 17:03:36 -07001518 output << " " << mLayers.size() << " Layer" <<
1519 (mLayers.size() == 1 ? "" : "s") << '\n';
1520 for (const auto& layer : mLayers) {
1521 output << layer->dump();
1522 }
1523
1524 output << " Client target: " << mClientTarget.getBuffer() << '\n';
1525
1526 if (mOutputBuffer.getBuffer() != nullptr) {
1527 output << " Output buffer: " << mOutputBuffer.getBuffer() << '\n';
1528 }
1529
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001530 if (mHwc1RequestedContents) {
Dan Stozac6998d22015-09-24 17:03:36 -07001531 output << " Last requested HWC1 state\n";
1532 output << to_string(*mHwc1RequestedContents, mDevice.mHwc1MinorVersion);
1533 }
1534
1535 return output.str();
1536}
1537
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001538hwc_rect_t* HWC2On1Adapter::Display::GetRects(size_t numRects) {
1539 if (numRects == 0) {
1540 return nullptr;
1541 }
1542
1543 if (numRects > mNumAvailableRects) {
1544 // This should NEVER happen since we calculated how many rects the
1545 // display would need.
1546 ALOGE("Rect allocation failure! SF is likely to crash soon!");
1547 return nullptr;
1548
1549 }
1550 hwc_rect_t* rects = mNextAvailableRect;
1551 mNextAvailableRect += numRects;
1552 mNumAvailableRects -= numRects;
1553 return rects;
1554}
1555
1556hwc_display_contents_1* HWC2On1Adapter::Display::getDisplayContents() {
1557 return mHwc1RequestedContents.get();
1558}
1559
Dan Stozac6998d22015-09-24 17:03:36 -07001560void HWC2On1Adapter::Display::Config::setAttribute(HWC2::Attribute attribute,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001561 int32_t value) {
Dan Stozac6998d22015-09-24 17:03:36 -07001562 mAttributes[attribute] = value;
1563}
1564
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001565int32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const {
Dan Stozac6998d22015-09-24 17:03:36 -07001566 if (mAttributes.count(attribute) == 0) {
1567 return -1;
1568 }
1569 return mAttributes.at(attribute);
1570}
1571
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001572void HWC2On1Adapter::Display::Config::setHwc1Id(uint32_t id) {
Michael Wright28f24d02016-07-12 13:30:53 -07001573 android_color_mode_t colorMode = static_cast<android_color_mode_t>(getAttribute(ColorMode));
1574 mHwc1Ids.emplace(colorMode, id);
Dan Stoza076ac672016-03-14 10:47:53 -07001575}
1576
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001577bool HWC2On1Adapter::Display::Config::hasHwc1Id(uint32_t id) const {
Dan Stoza076ac672016-03-14 10:47:53 -07001578 for (const auto& idPair : mHwc1Ids) {
1579 if (id == idPair.second) {
1580 return true;
1581 }
1582 }
1583 return false;
1584}
1585
Michael Wright28f24d02016-07-12 13:30:53 -07001586Error HWC2On1Adapter::Display::Config::getColorModeForHwc1Id(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001587 uint32_t id, android_color_mode_t* outMode) const {
Dan Stoza076ac672016-03-14 10:47:53 -07001588 for (const auto& idPair : mHwc1Ids) {
1589 if (id == idPair.second) {
Michael Wright28f24d02016-07-12 13:30:53 -07001590 *outMode = idPair.first;
1591 return Error::None;
Dan Stoza076ac672016-03-14 10:47:53 -07001592 }
1593 }
Michael Wright28f24d02016-07-12 13:30:53 -07001594 ALOGE("Unable to find color mode for HWC ID %" PRIu32 " on config %u", id, mId);
1595 return Error::BadParameter;
Dan Stoza076ac672016-03-14 10:47:53 -07001596}
1597
Michael Wright28f24d02016-07-12 13:30:53 -07001598Error HWC2On1Adapter::Display::Config::getHwc1IdForColorMode(android_color_mode_t mode,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001599 uint32_t* outId) const {
Dan Stoza076ac672016-03-14 10:47:53 -07001600 for (const auto& idPair : mHwc1Ids) {
1601 if (mode == idPair.first) {
1602 *outId = idPair.second;
1603 return Error::None;
1604 }
1605 }
1606 ALOGE("Unable to find HWC1 ID for color mode %d on config %u", mode, mId);
1607 return Error::BadParameter;
1608}
1609
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001610bool HWC2On1Adapter::Display::Config::merge(const Config& other) {
Dan Stoza076ac672016-03-14 10:47:53 -07001611 auto attributes = {HWC2::Attribute::Width, HWC2::Attribute::Height,
1612 HWC2::Attribute::VsyncPeriod, HWC2::Attribute::DpiX,
1613 HWC2::Attribute::DpiY};
1614 for (auto attribute : attributes) {
1615 if (getAttribute(attribute) != other.getAttribute(attribute)) {
1616 return false;
1617 }
1618 }
Michael Wright28f24d02016-07-12 13:30:53 -07001619 android_color_mode_t otherColorMode =
1620 static_cast<android_color_mode_t>(other.getAttribute(ColorMode));
1621 if (mHwc1Ids.count(otherColorMode) != 0) {
Dan Stoza076ac672016-03-14 10:47:53 -07001622 ALOGE("Attempted to merge two configs (%u and %u) which appear to be "
Michael Wright28f24d02016-07-12 13:30:53 -07001623 "identical", mHwc1Ids.at(otherColorMode),
1624 other.mHwc1Ids.at(otherColorMode));
Dan Stoza076ac672016-03-14 10:47:53 -07001625 return false;
1626 }
Michael Wright28f24d02016-07-12 13:30:53 -07001627 mHwc1Ids.emplace(otherColorMode,
1628 other.mHwc1Ids.at(otherColorMode));
Dan Stoza076ac672016-03-14 10:47:53 -07001629 return true;
1630}
1631
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001632std::set<android_color_mode_t> HWC2On1Adapter::Display::Config::getColorModes() const {
Michael Wright28f24d02016-07-12 13:30:53 -07001633 std::set<android_color_mode_t> colorModes;
Dan Stoza076ac672016-03-14 10:47:53 -07001634 for (const auto& idPair : mHwc1Ids) {
Michael Wright28f24d02016-07-12 13:30:53 -07001635 colorModes.emplace(idPair.first);
Dan Stoza076ac672016-03-14 10:47:53 -07001636 }
Michael Wright28f24d02016-07-12 13:30:53 -07001637 return colorModes;
Dan Stoza076ac672016-03-14 10:47:53 -07001638}
1639
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001640std::string HWC2On1Adapter::Display::Config::toString(bool splitLine) const {
Dan Stozac6998d22015-09-24 17:03:36 -07001641 std::string output;
1642
1643 const size_t BUFFER_SIZE = 100;
1644 char buffer[BUFFER_SIZE] = {};
1645 auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
Dan Stoza076ac672016-03-14 10:47:53 -07001646 "%u x %u", mAttributes.at(HWC2::Attribute::Width),
Dan Stozac6998d22015-09-24 17:03:36 -07001647 mAttributes.at(HWC2::Attribute::Height));
1648 output.append(buffer, writtenBytes);
1649
1650 if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
1651 std::memset(buffer, 0, BUFFER_SIZE);
1652 writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
1653 1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
1654 output.append(buffer, writtenBytes);
1655 }
1656
1657 if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
1658 mAttributes.at(HWC2::Attribute::DpiX) != -1) {
1659 std::memset(buffer, 0, BUFFER_SIZE);
1660 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1661 ", DPI: %.1f x %.1f",
1662 mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
1663 mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
1664 output.append(buffer, writtenBytes);
1665 }
1666
Dan Stoza076ac672016-03-14 10:47:53 -07001667 std::memset(buffer, 0, BUFFER_SIZE);
1668 if (splitLine) {
1669 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1670 "\n HWC1 ID/Color transform:");
1671 } else {
1672 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1673 ", HWC1 ID/Color transform:");
1674 }
1675 output.append(buffer, writtenBytes);
1676
1677
1678 for (const auto& id : mHwc1Ids) {
Michael Wright28f24d02016-07-12 13:30:53 -07001679 android_color_mode_t colorMode = id.first;
Dan Stoza076ac672016-03-14 10:47:53 -07001680 uint32_t hwc1Id = id.second;
1681 std::memset(buffer, 0, BUFFER_SIZE);
Michael Wright28f24d02016-07-12 13:30:53 -07001682 if (colorMode == mDisplay.mActiveColorMode) {
Dan Stoza076ac672016-03-14 10:47:53 -07001683 writtenBytes = snprintf(buffer, BUFFER_SIZE, " [%u/%d]", hwc1Id,
Michael Wright28f24d02016-07-12 13:30:53 -07001684 colorMode);
Dan Stoza076ac672016-03-14 10:47:53 -07001685 } else {
1686 writtenBytes = snprintf(buffer, BUFFER_SIZE, " %u/%d", hwc1Id,
Michael Wright28f24d02016-07-12 13:30:53 -07001687 colorMode);
Dan Stoza076ac672016-03-14 10:47:53 -07001688 }
1689 output.append(buffer, writtenBytes);
1690 }
1691
Dan Stozac6998d22015-09-24 17:03:36 -07001692 return output;
1693}
1694
1695std::shared_ptr<const HWC2On1Adapter::Display::Config>
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001696 HWC2On1Adapter::Display::getConfig(hwc2_config_t configId) const {
Dan Stozac6998d22015-09-24 17:03:36 -07001697 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
1698 return nullptr;
1699 }
1700 return mConfigs[configId];
1701}
1702
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001703void HWC2On1Adapter::Display::populateColorModes() {
Michael Wright28f24d02016-07-12 13:30:53 -07001704 mColorModes = mConfigs[0]->getColorModes();
Dan Stoza076ac672016-03-14 10:47:53 -07001705 for (const auto& config : mConfigs) {
Michael Wright28f24d02016-07-12 13:30:53 -07001706 std::set<android_color_mode_t> intersection;
1707 auto configModes = config->getColorModes();
Dan Stoza076ac672016-03-14 10:47:53 -07001708 std::set_intersection(mColorModes.cbegin(), mColorModes.cend(),
1709 configModes.cbegin(), configModes.cend(),
1710 std::inserter(intersection, intersection.begin()));
1711 std::swap(intersection, mColorModes);
1712 }
1713}
1714
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001715void HWC2On1Adapter::Display::initializeActiveConfig() {
Dan Stoza076ac672016-03-14 10:47:53 -07001716 if (mDevice.mHwc1Device->getActiveConfig == nullptr) {
1717 ALOGV("getActiveConfig is null, choosing config 0");
1718 mActiveConfig = mConfigs[0];
Michael Wright28f24d02016-07-12 13:30:53 -07001719 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
Dan Stoza076ac672016-03-14 10:47:53 -07001720 return;
1721 }
1722
1723 auto activeConfig = mDevice.mHwc1Device->getActiveConfig(
1724 mDevice.mHwc1Device, mHwc1Id);
Fabien Sanglardb7432cc2016-11-11 09:40:27 -08001725
1726 // Some devices startup without an activeConfig:
1727 // We need to set one ourselves.
1728 if (activeConfig == HWC_ERROR) {
1729 ALOGV("There is no active configuration: Picking the first one: 0.");
1730 const int defaultIndex = 0;
1731 mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device, mHwc1Id, defaultIndex);
1732 activeConfig = defaultIndex;
1733 }
1734
1735 for (const auto& config : mConfigs) {
1736 if (config->hasHwc1Id(activeConfig)) {
1737 ALOGE("Setting active config to %d for HWC1 config %u", config->getId(), activeConfig);
1738 mActiveConfig = config;
1739 if (config->getColorModeForHwc1Id(activeConfig, &mActiveColorMode) != Error::None) {
1740 // This should never happen since we checked for the config's presence before
1741 // setting it as active.
1742 ALOGE("Unable to find color mode for active HWC1 config %d", config->getId());
1743 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
Dan Stoza076ac672016-03-14 10:47:53 -07001744 }
Fabien Sanglardb7432cc2016-11-11 09:40:27 -08001745 break;
Dan Stoza076ac672016-03-14 10:47:53 -07001746 }
1747 }
Fabien Sanglardb7432cc2016-11-11 09:40:27 -08001748 if (!mActiveConfig) {
1749 ALOGV("Unable to find active HWC1 config %u, defaulting to "
1750 "config 0", activeConfig);
1751 mActiveConfig = mConfigs[0];
1752 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1753 }
1754
1755
1756
1757
Dan Stoza076ac672016-03-14 10:47:53 -07001758}
1759
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001760void HWC2On1Adapter::Display::allocateRequestedContents() {
1761 // What needs to be allocated:
1762 // 1 hwc_display_contents_1_t
1763 // 1 hwc_layer_1_t for each layer
1764 // 1 hwc_rect_t for each layer's surfaceDamage
1765 // 1 hwc_rect_t for each layer's visibleRegion
1766 // 1 hwc_layer_1_t for the framebuffer
1767 // 1 hwc_rect_t for the framebuffer's visibleRegion
1768
1769 // Count # of surfaceDamage
1770 size_t numSurfaceDamages = 0;
1771 for (const auto& layer : mLayers) {
1772 numSurfaceDamages += layer->getNumSurfaceDamages();
1773 }
1774
1775 // Count # of visibleRegions (start at 1 for mandatory framebuffer target
1776 // region)
1777 size_t numVisibleRegion = 1;
1778 for (const auto& layer : mLayers) {
1779 numVisibleRegion += layer->getNumVisibleRegions();
1780 }
1781
1782 size_t numRects = numVisibleRegion + numSurfaceDamages;
Dan Stozac6998d22015-09-24 17:03:36 -07001783 auto numLayers = mLayers.size() + 1;
1784 size_t size = sizeof(hwc_display_contents_1_t) +
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001785 sizeof(hwc_layer_1_t) * numLayers +
1786 sizeof(hwc_rect_t) * numRects;
1787 auto contents = static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1));
Dan Stozac6998d22015-09-24 17:03:36 -07001788 mHwc1RequestedContents.reset(contents);
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001789 mNextAvailableRect = reinterpret_cast<hwc_rect_t*>(&contents->hwLayers[numLayers]);
1790 mNumAvailableRects = numRects;
Dan Stozac6998d22015-09-24 17:03:36 -07001791}
1792
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001793void HWC2On1Adapter::Display::assignHwc1LayerIds() {
Dan Stozac6998d22015-09-24 17:03:36 -07001794 mHwc1LayerMap.clear();
1795 size_t nextHwc1Id = 0;
1796 for (auto& layer : mLayers) {
1797 mHwc1LayerMap[nextHwc1Id] = layer;
1798 layer->setHwc1Id(nextHwc1Id++);
1799 }
1800}
1801
1802void HWC2On1Adapter::Display::updateTypeChanges(const hwc_layer_1_t& hwc1Layer,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001803 const Layer& layer) {
Dan Stozac6998d22015-09-24 17:03:36 -07001804 auto layerId = layer.getId();
1805 switch (hwc1Layer.compositionType) {
1806 case HWC_FRAMEBUFFER:
1807 if (layer.getCompositionType() != Composition::Client) {
1808 mChanges->addTypeChange(layerId, Composition::Client);
1809 }
1810 break;
1811 case HWC_OVERLAY:
1812 if (layer.getCompositionType() != Composition::Device) {
1813 mChanges->addTypeChange(layerId, Composition::Device);
1814 }
1815 break;
1816 case HWC_BACKGROUND:
1817 ALOGE_IF(layer.getCompositionType() != Composition::SolidColor,
1818 "updateTypeChanges: HWC1 requested BACKGROUND, but HWC2"
1819 " wasn't expecting SolidColor");
1820 break;
1821 case HWC_FRAMEBUFFER_TARGET:
1822 // Do nothing, since it shouldn't be modified by HWC1
1823 break;
1824 case HWC_SIDEBAND:
1825 ALOGE_IF(layer.getCompositionType() != Composition::Sideband,
1826 "updateTypeChanges: HWC1 requested SIDEBAND, but HWC2"
1827 " wasn't expecting Sideband");
1828 break;
1829 case HWC_CURSOR_OVERLAY:
1830 ALOGE_IF(layer.getCompositionType() != Composition::Cursor,
1831 "updateTypeChanges: HWC1 requested CURSOR_OVERLAY, but"
1832 " HWC2 wasn't expecting Cursor");
1833 break;
1834 }
1835}
1836
1837void HWC2On1Adapter::Display::updateLayerRequests(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001838 const hwc_layer_1_t& hwc1Layer, const Layer& layer) {
Dan Stozac6998d22015-09-24 17:03:36 -07001839 if ((hwc1Layer.hints & HWC_HINT_CLEAR_FB) != 0) {
1840 mChanges->addLayerRequest(layer.getId(),
1841 LayerRequest::ClearClientTarget);
1842 }
1843}
1844
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001845void HWC2On1Adapter::Display::prepareFramebufferTarget() {
Dan Stozac6998d22015-09-24 17:03:36 -07001846 // We check that mActiveConfig is valid in Display::prepare
1847 int32_t width = mActiveConfig->getAttribute(Attribute::Width);
1848 int32_t height = mActiveConfig->getAttribute(Attribute::Height);
1849
1850 auto& hwc1Target = mHwc1RequestedContents->hwLayers[mLayers.size()];
1851 hwc1Target.compositionType = HWC_FRAMEBUFFER_TARGET;
1852 hwc1Target.releaseFenceFd = -1;
1853 hwc1Target.hints = 0;
1854 hwc1Target.flags = 0;
1855 hwc1Target.transform = 0;
1856 hwc1Target.blending = HWC_BLENDING_PREMULT;
1857 if (mDevice.getHwc1MinorVersion() < 3) {
1858 hwc1Target.sourceCropi = {0, 0, width, height};
1859 } else {
1860 hwc1Target.sourceCropf = {0.0f, 0.0f, static_cast<float>(width),
1861 static_cast<float>(height)};
1862 }
1863 hwc1Target.displayFrame = {0, 0, width, height};
1864 hwc1Target.planeAlpha = 255;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001865
Dan Stozac6998d22015-09-24 17:03:36 -07001866 hwc1Target.visibleRegionScreen.numRects = 1;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001867 hwc_rect_t* rects = GetRects(1);
Dan Stozac6998d22015-09-24 17:03:36 -07001868 rects[0].left = 0;
1869 rects[0].top = 0;
1870 rects[0].right = width;
1871 rects[0].bottom = height;
1872 hwc1Target.visibleRegionScreen.rects = rects;
1873
1874 // We will set this to the correct value in set
1875 hwc1Target.acquireFenceFd = -1;
1876}
1877
1878// Layer functions
1879
1880std::atomic<hwc2_layer_t> HWC2On1Adapter::Layer::sNextId(1);
1881
1882HWC2On1Adapter::Layer::Layer(Display& display)
1883 : mId(sNextId++),
1884 mDisplay(display),
Dan Stozafc4e2022016-02-23 11:43:19 -08001885 mBuffer(),
1886 mSurfaceDamage(),
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001887 mBlendMode(BlendMode::None),
1888 mColor({0, 0, 0, 0}),
1889 mCompositionType(Composition::Invalid),
1890 mDisplayFrame({0, 0, -1, -1}),
1891 mPlaneAlpha(0.0f),
1892 mSidebandStream(nullptr),
1893 mSourceCrop({0.0f, 0.0f, -1.0f, -1.0f}),
1894 mTransform(Transform::None),
1895 mVisibleRegion(),
Dan Stozac6998d22015-09-24 17:03:36 -07001896 mZ(0),
Dan Stozafc4e2022016-02-23 11:43:19 -08001897 mReleaseFence(),
Dan Stozac6998d22015-09-24 17:03:36 -07001898 mHwc1Id(0),
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001899 mHasUnsupportedPlaneAlpha(false) {}
Dan Stozac6998d22015-09-24 17:03:36 -07001900
1901bool HWC2On1Adapter::SortLayersByZ::operator()(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001902 const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs) {
Dan Stozac6998d22015-09-24 17:03:36 -07001903 return lhs->getZ() < rhs->getZ();
1904}
1905
1906Error HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001907 int32_t acquireFence) {
Dan Stozac6998d22015-09-24 17:03:36 -07001908 ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
1909 mBuffer.setBuffer(buffer);
1910 mBuffer.setFence(acquireFence);
1911 return Error::None;
1912}
1913
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001914Error HWC2On1Adapter::Layer::setCursorPosition(int32_t x, int32_t y) {
1915 if (mCompositionType != Composition::Cursor) {
Dan Stozac6998d22015-09-24 17:03:36 -07001916 return Error::BadLayer;
1917 }
1918
1919 if (mDisplay.hasChanges()) {
1920 return Error::NotValidated;
1921 }
1922
1923 auto displayId = mDisplay.getHwc1Id();
1924 auto hwc1Device = mDisplay.getDevice().getHwc1Device();
1925 hwc1Device->setCursorPositionAsync(hwc1Device, displayId, x, y);
1926 return Error::None;
1927}
1928
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001929Error HWC2On1Adapter::Layer::setSurfaceDamage(hwc_region_t damage) {
Fabien Sanglard356bcd42017-02-17 16:14:18 -08001930 // HWC1 supports surface damage starting only with version 1.5.
1931 if (mDisplay.getDevice().mHwc1MinorVersion < 5) {
1932 return Error::None;
1933 }
Dan Stozac6998d22015-09-24 17:03:36 -07001934 mSurfaceDamage.resize(damage.numRects);
1935 std::copy_n(damage.rects, damage.numRects, mSurfaceDamage.begin());
1936 return Error::None;
1937}
1938
1939// Layer state functions
1940
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001941Error HWC2On1Adapter::Layer::setBlendMode(BlendMode mode) {
1942 mBlendMode = mode;
1943 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001944 return Error::None;
1945}
1946
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001947Error HWC2On1Adapter::Layer::setColor(hwc_color_t color) {
1948 mColor = color;
1949 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001950 return Error::None;
1951}
1952
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001953Error HWC2On1Adapter::Layer::setCompositionType(Composition type) {
1954 mCompositionType = type;
1955 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001956 return Error::None;
1957}
1958
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001959Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t) {
Dan Stoza5df2a862016-03-24 16:19:37 -07001960 return Error::None;
1961}
1962
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001963Error HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame) {
1964 mDisplayFrame = frame;
1965 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001966 return Error::None;
1967}
1968
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001969Error HWC2On1Adapter::Layer::setPlaneAlpha(float alpha) {
1970 mPlaneAlpha = alpha;
1971 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001972 return Error::None;
1973}
1974
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001975Error HWC2On1Adapter::Layer::setSidebandStream(const native_handle_t* stream) {
1976 mSidebandStream = stream;
1977 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001978 return Error::None;
1979}
1980
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001981Error HWC2On1Adapter::Layer::setSourceCrop(hwc_frect_t crop) {
1982 mSourceCrop = crop;
1983 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001984 return Error::None;
1985}
1986
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001987Error HWC2On1Adapter::Layer::setTransform(Transform transform) {
1988 mTransform = transform;
1989 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001990 return Error::None;
1991}
1992
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001993Error HWC2On1Adapter::Layer::setVisibleRegion(hwc_region_t visible) {
1994 mVisibleRegion.resize(visible.numRects);
1995 std::copy_n(visible.rects, visible.numRects, mVisibleRegion.begin());
1996 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001997 return Error::None;
1998}
1999
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002000Error HWC2On1Adapter::Layer::setZ(uint32_t z) {
Dan Stozac6998d22015-09-24 17:03:36 -07002001 mZ = z;
2002 return Error::None;
2003}
2004
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002005void HWC2On1Adapter::Layer::addReleaseFence(int fenceFd) {
Dan Stozac6998d22015-09-24 17:03:36 -07002006 ALOGV("addReleaseFence %d to layer %" PRIu64, fenceFd, mId);
2007 mReleaseFence.add(fenceFd);
2008}
2009
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002010const sp<Fence>& HWC2On1Adapter::Layer::getReleaseFence() const {
Dan Stozac6998d22015-09-24 17:03:36 -07002011 return mReleaseFence.get();
2012}
2013
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002014void HWC2On1Adapter::Layer::applyState(hwc_layer_1_t& hwc1Layer) {
2015 applyCommonState(hwc1Layer);
2016 applyCompositionType(hwc1Layer);
2017 switch (mCompositionType) {
2018 case Composition::SolidColor : applySolidColorState(hwc1Layer); break;
2019 case Composition::Sideband : applySidebandState(hwc1Layer); break;
2020 default: applyBufferState(hwc1Layer); break;
Dan Stozac6998d22015-09-24 17:03:36 -07002021 }
Dan Stozac6998d22015-09-24 17:03:36 -07002022}
2023
Dan Stozac6998d22015-09-24 17:03:36 -07002024static std::string regionStrings(const std::vector<hwc_rect_t>& visibleRegion,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002025 const std::vector<hwc_rect_t>& surfaceDamage) {
Dan Stozac6998d22015-09-24 17:03:36 -07002026 std::string regions;
2027 regions += " Visible Region";
2028 regions.resize(40, ' ');
2029 regions += "Surface Damage\n";
2030
2031 size_t numPrinted = 0;
2032 size_t maxSize = std::max(visibleRegion.size(), surfaceDamage.size());
2033 while (numPrinted < maxSize) {
2034 std::string line(" ");
2035 if (visibleRegion.empty() && numPrinted == 0) {
2036 line += "None";
2037 } else if (numPrinted < visibleRegion.size()) {
2038 line += rectString(visibleRegion[numPrinted]);
2039 }
2040 line.resize(40, ' ');
2041 if (surfaceDamage.empty() && numPrinted == 0) {
2042 line += "None";
2043 } else if (numPrinted < surfaceDamage.size()) {
2044 line += rectString(surfaceDamage[numPrinted]);
2045 }
2046 line += '\n';
2047 regions += line;
2048 ++numPrinted;
2049 }
2050 return regions;
2051}
2052
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002053std::string HWC2On1Adapter::Layer::dump() const {
Dan Stozac6998d22015-09-24 17:03:36 -07002054 std::stringstream output;
2055 const char* fill = " ";
2056
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002057 output << fill << to_string(mCompositionType);
Dan Stozac6998d22015-09-24 17:03:36 -07002058 output << " Layer HWC2/1: " << mId << "/" << mHwc1Id << " ";
2059 output << "Z: " << mZ;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002060 if (mCompositionType == HWC2::Composition::SolidColor) {
2061 output << " " << colorString(mColor);
2062 } else if (mCompositionType == HWC2::Composition::Sideband) {
2063 output << " Handle: " << mSidebandStream << '\n';
Dan Stozac6998d22015-09-24 17:03:36 -07002064 } else {
2065 output << " Buffer: " << mBuffer.getBuffer() << "/" <<
2066 mBuffer.getFence() << '\n';
2067 output << fill << " Display frame [LTRB]: " <<
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002068 rectString(mDisplayFrame) << '\n';
Dan Stozac6998d22015-09-24 17:03:36 -07002069 output << fill << " Source crop: " <<
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002070 frectString(mSourceCrop) << '\n';
2071 output << fill << " Transform: " << to_string(mTransform);
2072 output << " Blend mode: " << to_string(mBlendMode);
2073 if (mPlaneAlpha != 1.0f) {
Dan Stozac6998d22015-09-24 17:03:36 -07002074 output << " Alpha: " <<
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002075 alphaString(mPlaneAlpha) << '\n';
Dan Stozac6998d22015-09-24 17:03:36 -07002076 } else {
2077 output << '\n';
2078 }
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002079 output << regionStrings(mVisibleRegion, mSurfaceDamage);
Dan Stozac6998d22015-09-24 17:03:36 -07002080 }
2081 return output.str();
2082}
2083
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002084static int getHwc1Blending(HWC2::BlendMode blendMode) {
Dan Stozac6998d22015-09-24 17:03:36 -07002085 switch (blendMode) {
2086 case BlendMode::Coverage: return HWC_BLENDING_COVERAGE;
2087 case BlendMode::Premultiplied: return HWC_BLENDING_PREMULT;
2088 default: return HWC_BLENDING_NONE;
2089 }
2090}
2091
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002092void HWC2On1Adapter::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer) {
Dan Stozac6998d22015-09-24 17:03:36 -07002093 auto minorVersion = mDisplay.getDevice().getHwc1MinorVersion();
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002094 hwc1Layer.blending = getHwc1Blending(mBlendMode);
2095 hwc1Layer.displayFrame = mDisplayFrame;
Dan Stozac6998d22015-09-24 17:03:36 -07002096
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002097 auto pendingAlpha = mPlaneAlpha;
2098 if (minorVersion < 2) {
2099 mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f;
2100 } else {
2101 hwc1Layer.planeAlpha =
2102 static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f);
2103 }
Dan Stozac6998d22015-09-24 17:03:36 -07002104
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002105 if (minorVersion < 3) {
2106 auto pending = mSourceCrop;
2107 hwc1Layer.sourceCropi.left =
2108 static_cast<int32_t>(std::ceil(pending.left));
2109 hwc1Layer.sourceCropi.top =
2110 static_cast<int32_t>(std::ceil(pending.top));
2111 hwc1Layer.sourceCropi.right =
2112 static_cast<int32_t>(std::floor(pending.right));
2113 hwc1Layer.sourceCropi.bottom =
2114 static_cast<int32_t>(std::floor(pending.bottom));
2115 } else {
2116 hwc1Layer.sourceCropf = mSourceCrop;
2117 }
2118
2119 hwc1Layer.transform = static_cast<uint32_t>(mTransform);
2120
2121 auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen;
2122 hwc1VisibleRegion.numRects = mVisibleRegion.size();
2123 hwc_rect_t* rects = mDisplay.GetRects(hwc1VisibleRegion.numRects);
2124 hwc1VisibleRegion.rects = rects;
2125 for (size_t i = 0; i < mVisibleRegion.size(); i++) {
2126 rects[i] = mVisibleRegion[i];
Dan Stozac6998d22015-09-24 17:03:36 -07002127 }
2128}
2129
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002130void HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer) {
2131 // If the device does not support background color it is likely to make
2132 // assumption regarding backgroundColor and handle (both fields occupy
2133 // the same location in hwc_layer_1_t union).
2134 // To not confuse these devices we don't set background color and we
2135 // make sure handle is a null pointer.
2136 if (hasUnsupportedBackgroundColor()) {
2137 hwc1Layer.handle = nullptr;
2138 } else {
2139 hwc1Layer.backgroundColor = mColor;
Dan Stozac6998d22015-09-24 17:03:36 -07002140 }
2141}
2142
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002143void HWC2On1Adapter::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer) {
2144 hwc1Layer.sidebandStream = mSidebandStream;
Dan Stozac6998d22015-09-24 17:03:36 -07002145}
2146
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002147void HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer) {
Dan Stozac6998d22015-09-24 17:03:36 -07002148 hwc1Layer.handle = mBuffer.getBuffer();
2149 hwc1Layer.acquireFenceFd = mBuffer.getFence();
2150}
2151
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002152void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer) {
Dan Stoza5df2a862016-03-24 16:19:37 -07002153 // HWC1 never supports color transforms or dataspaces and only sometimes
2154 // supports plane alpha (depending on the version). These require us to drop
2155 // some or all layers to client composition.
Fabien Sanglard999a7fd2017-02-02 16:59:44 -08002156 if (mHasUnsupportedPlaneAlpha || mDisplay.hasColorTransform() ||
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002157 hasUnsupportedBackgroundColor()) {
Dan Stozac6998d22015-09-24 17:03:36 -07002158 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2159 hwc1Layer.flags = HWC_SKIP_LAYER;
2160 return;
2161 }
2162
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002163 hwc1Layer.flags = 0;
2164 switch (mCompositionType) {
2165 case Composition::Client:
2166 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2167 hwc1Layer.flags |= HWC_SKIP_LAYER;
2168 break;
2169 case Composition::Device:
2170 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2171 break;
2172 case Composition::SolidColor:
2173 // In theory the following line should work, but since the HWC1
2174 // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
2175 // devices may not work correctly. To be on the safe side, we
2176 // fall back to client composition.
2177 //
2178 // hwc1Layer.compositionType = HWC_BACKGROUND;
2179 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2180 hwc1Layer.flags |= HWC_SKIP_LAYER;
2181 break;
2182 case Composition::Cursor:
2183 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2184 if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
2185 hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
2186 }
2187 break;
2188 case Composition::Sideband:
2189 if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
2190 hwc1Layer.compositionType = HWC_SIDEBAND;
2191 } else {
Dan Stozac6998d22015-09-24 17:03:36 -07002192 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2193 hwc1Layer.flags |= HWC_SKIP_LAYER;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002194 }
2195 break;
2196 default:
2197 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2198 hwc1Layer.flags |= HWC_SKIP_LAYER;
2199 break;
Dan Stozac6998d22015-09-24 17:03:36 -07002200 }
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002201 ALOGV("Layer %" PRIu64 " %s set to %d", mId,
2202 to_string(mCompositionType).c_str(),
2203 hwc1Layer.compositionType);
2204 ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, " and skipping");
Dan Stozac6998d22015-09-24 17:03:36 -07002205}
2206
2207// Adapter helpers
2208
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002209void HWC2On1Adapter::populateCapabilities() {
Dan Stozac6998d22015-09-24 17:03:36 -07002210 ALOGV("populateCapabilities");
2211 if (mHwc1MinorVersion >= 3U) {
2212 int supportedTypes = 0;
2213 auto result = mHwc1Device->query(mHwc1Device,
2214 HWC_DISPLAY_TYPES_SUPPORTED, &supportedTypes);
Fred Fettingerc50c01e2016-06-14 17:53:10 -05002215 if ((result == 0) && ((supportedTypes & HWC_DISPLAY_VIRTUAL_BIT) != 0)) {
Dan Stozac6998d22015-09-24 17:03:36 -07002216 ALOGI("Found support for HWC virtual displays");
2217 mHwc1SupportsVirtualDisplays = true;
2218 }
2219 }
2220 if (mHwc1MinorVersion >= 4U) {
2221 mCapabilities.insert(Capability::SidebandStream);
2222 }
Fabien Sanglardeb3db612016-11-18 16:12:31 -08002223
2224 // Check for HWC background color layer support.
2225 if (mHwc1MinorVersion >= 1U) {
2226 int backgroundColorSupported = 0;
2227 auto result = mHwc1Device->query(mHwc1Device,
2228 HWC_BACKGROUND_LAYER_SUPPORTED,
2229 &backgroundColorSupported);
2230 if ((result == 0) && (backgroundColorSupported == 1)) {
2231 ALOGV("Found support for HWC background color");
2232 mHwc1SupportsBackgroundColor = true;
2233 }
2234 }
Dan Stozac6998d22015-09-24 17:03:36 -07002235}
2236
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002237HWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id) {
Dan Stozafc4e2022016-02-23 11:43:19 -08002238 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002239
2240 auto display = mDisplays.find(id);
2241 if (display == mDisplays.end()) {
2242 return nullptr;
2243 }
2244
2245 return display->second.get();
2246}
2247
2248std::tuple<HWC2On1Adapter::Layer*, Error> HWC2On1Adapter::getLayer(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002249 hwc2_display_t displayId, hwc2_layer_t layerId) {
Dan Stozac6998d22015-09-24 17:03:36 -07002250 auto display = getDisplay(displayId);
2251 if (!display) {
2252 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
2253 }
2254
2255 auto layerEntry = mLayers.find(layerId);
2256 if (layerEntry == mLayers.end()) {
2257 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2258 }
2259
2260 auto layer = layerEntry->second;
2261 if (layer->getDisplay().getId() != displayId) {
2262 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2263 }
2264 return std::make_tuple(layer.get(), Error::None);
2265}
2266
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002267void HWC2On1Adapter::populatePrimary() {
Dan Stozac6998d22015-09-24 17:03:36 -07002268 ALOGV("populatePrimary");
2269
Dan Stozafc4e2022016-02-23 11:43:19 -08002270 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002271
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002272 auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
Dan Stozac6998d22015-09-24 17:03:36 -07002273 mHwc1DisplayMap[HWC_DISPLAY_PRIMARY] = display->getId();
2274 display->setHwc1Id(HWC_DISPLAY_PRIMARY);
2275 display->populateConfigs();
2276 mDisplays.emplace(display->getId(), std::move(display));
2277}
2278
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002279bool HWC2On1Adapter::prepareAllDisplays() {
Dan Stozac6998d22015-09-24 17:03:36 -07002280 ATRACE_CALL();
2281
Dan Stozafc4e2022016-02-23 11:43:19 -08002282 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002283
2284 for (const auto& displayPair : mDisplays) {
2285 auto& display = displayPair.second;
2286 if (!display->prepare()) {
2287 return false;
2288 }
2289 }
2290
Fabien Sanglard7382ed72017-02-11 22:47:36 -08002291 if (mHwc1DisplayMap.count(HWC_DISPLAY_PRIMARY) == 0) {
Dan Stozac6998d22015-09-24 17:03:36 -07002292 ALOGE("prepareAllDisplays: Unable to find primary HWC1 display");
2293 return false;
2294 }
2295
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002296 // Build an array of hwc_display_contents_1 to call prepare() on HWC1.
2297 mHwc1Contents.clear();
2298
Dan Stozac6998d22015-09-24 17:03:36 -07002299 // Always push the primary display
Dan Stozac6998d22015-09-24 17:03:36 -07002300 auto primaryDisplayId = mHwc1DisplayMap[HWC_DISPLAY_PRIMARY];
2301 auto& primaryDisplay = mDisplays[primaryDisplayId];
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002302 mHwc1Contents.push_back(primaryDisplay->getDisplayContents());
Dan Stozac6998d22015-09-24 17:03:36 -07002303
2304 // Push the external display, if present
2305 if (mHwc1DisplayMap.count(HWC_DISPLAY_EXTERNAL) != 0) {
2306 auto externalDisplayId = mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL];
2307 auto& externalDisplay = mDisplays[externalDisplayId];
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002308 mHwc1Contents.push_back(externalDisplay->getDisplayContents());
Dan Stozac6998d22015-09-24 17:03:36 -07002309 } else {
2310 // Even if an external display isn't present, we still need to send
2311 // at least two displays down to HWC1
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002312 mHwc1Contents.push_back(nullptr);
Dan Stozac6998d22015-09-24 17:03:36 -07002313 }
2314
2315 // Push the hardware virtual display, if supported and present
2316 if (mHwc1MinorVersion >= 3) {
2317 if (mHwc1DisplayMap.count(HWC_DISPLAY_VIRTUAL) != 0) {
2318 auto virtualDisplayId = mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL];
2319 auto& virtualDisplay = mDisplays[virtualDisplayId];
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002320 mHwc1Contents.push_back(virtualDisplay->getDisplayContents());
Dan Stozac6998d22015-09-24 17:03:36 -07002321 } else {
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002322 mHwc1Contents.push_back(nullptr);
Dan Stozac6998d22015-09-24 17:03:36 -07002323 }
2324 }
2325
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002326 for (auto& displayContents : mHwc1Contents) {
Dan Stozac6998d22015-09-24 17:03:36 -07002327 if (!displayContents) {
2328 continue;
2329 }
2330
2331 ALOGV("Display %zd layers:", mHwc1Contents.size() - 1);
2332 for (size_t l = 0; l < displayContents->numHwLayers; ++l) {
2333 auto& layer = displayContents->hwLayers[l];
2334 ALOGV(" %zd: %d", l, layer.compositionType);
2335 }
2336 }
2337
2338 ALOGV("Calling HWC1 prepare");
2339 {
2340 ATRACE_NAME("HWC1 prepare");
2341 mHwc1Device->prepare(mHwc1Device, mHwc1Contents.size(),
2342 mHwc1Contents.data());
2343 }
2344
2345 for (size_t c = 0; c < mHwc1Contents.size(); ++c) {
2346 auto& contents = mHwc1Contents[c];
2347 if (!contents) {
2348 continue;
2349 }
2350 ALOGV("Display %zd layers:", c);
2351 for (size_t l = 0; l < contents->numHwLayers; ++l) {
2352 ALOGV(" %zd: %d", l, contents->hwLayers[l].compositionType);
2353 }
2354 }
2355
2356 // Return the received contents to their respective displays
2357 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2358 if (mHwc1Contents[hwc1Id] == nullptr) {
2359 continue;
2360 }
2361
2362 auto displayId = mHwc1DisplayMap[hwc1Id];
2363 auto& display = mDisplays[displayId];
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002364 display->generateChanges();
Dan Stozac6998d22015-09-24 17:03:36 -07002365 }
2366
2367 return true;
2368}
2369
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002370Error HWC2On1Adapter::setAllDisplays() {
Dan Stozac6998d22015-09-24 17:03:36 -07002371 ATRACE_CALL();
2372
Dan Stozafc4e2022016-02-23 11:43:19 -08002373 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002374
2375 // Make sure we're ready to validate
2376 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2377 if (mHwc1Contents[hwc1Id] == nullptr) {
2378 continue;
2379 }
2380
2381 auto displayId = mHwc1DisplayMap[hwc1Id];
2382 auto& display = mDisplays[displayId];
2383 Error error = display->set(*mHwc1Contents[hwc1Id]);
2384 if (error != Error::None) {
2385 ALOGE("setAllDisplays: Failed to set display %zd: %s", hwc1Id,
2386 to_string(error).c_str());
2387 return error;
2388 }
2389 }
2390
2391 ALOGV("Calling HWC1 set");
2392 {
2393 ATRACE_NAME("HWC1 set");
2394 mHwc1Device->set(mHwc1Device, mHwc1Contents.size(),
2395 mHwc1Contents.data());
2396 }
2397
2398 // Add retire and release fences
2399 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2400 if (mHwc1Contents[hwc1Id] == nullptr) {
2401 continue;
2402 }
2403
2404 auto displayId = mHwc1DisplayMap[hwc1Id];
2405 auto& display = mDisplays[displayId];
2406 auto retireFenceFd = mHwc1Contents[hwc1Id]->retireFenceFd;
2407 ALOGV("setAllDisplays: Adding retire fence %d to display %zd",
2408 retireFenceFd, hwc1Id);
2409 display->addRetireFence(mHwc1Contents[hwc1Id]->retireFenceFd);
2410 display->addReleaseFences(*mHwc1Contents[hwc1Id]);
2411 }
2412
2413 return Error::None;
2414}
2415
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002416void HWC2On1Adapter::hwc1Invalidate() {
Dan Stozac6998d22015-09-24 17:03:36 -07002417 ALOGV("Received hwc1Invalidate");
2418
Dan Stozafc4e2022016-02-23 11:43:19 -08002419 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002420
2421 // If the HWC2-side callback hasn't been registered yet, buffer this until
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002422 // it is registered.
Dan Stozac6998d22015-09-24 17:03:36 -07002423 if (mCallbacks.count(Callback::Refresh) == 0) {
2424 mHasPendingInvalidate = true;
2425 return;
2426 }
2427
2428 const auto& callbackInfo = mCallbacks[Callback::Refresh];
2429 std::vector<hwc2_display_t> displays;
2430 for (const auto& displayPair : mDisplays) {
2431 displays.emplace_back(displayPair.first);
2432 }
2433
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002434 // Call back without the state lock held.
Dan Stozac6998d22015-09-24 17:03:36 -07002435 lock.unlock();
2436
2437 auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(callbackInfo.pointer);
2438 for (auto display : displays) {
2439 refresh(callbackInfo.data, display);
2440 }
2441}
2442
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002443void HWC2On1Adapter::hwc1Vsync(int hwc1DisplayId, int64_t timestamp) {
Dan Stozac6998d22015-09-24 17:03:36 -07002444 ALOGV("Received hwc1Vsync(%d, %" PRId64 ")", hwc1DisplayId, timestamp);
2445
Dan Stozafc4e2022016-02-23 11:43:19 -08002446 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002447
2448 // If the HWC2-side callback hasn't been registered yet, buffer this until
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002449 // it is registered.
Dan Stozac6998d22015-09-24 17:03:36 -07002450 if (mCallbacks.count(Callback::Vsync) == 0) {
2451 mPendingVsyncs.emplace_back(hwc1DisplayId, timestamp);
2452 return;
2453 }
2454
2455 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2456 ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", hwc1DisplayId);
2457 return;
2458 }
2459
2460 const auto& callbackInfo = mCallbacks[Callback::Vsync];
2461 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
2462
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002463 // Call back without the state lock held.
Dan Stozac6998d22015-09-24 17:03:36 -07002464 lock.unlock();
2465
2466 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
2467 vsync(callbackInfo.data, displayId, timestamp);
2468}
2469
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002470void HWC2On1Adapter::hwc1Hotplug(int hwc1DisplayId, int connected) {
Dan Stozac6998d22015-09-24 17:03:36 -07002471 ALOGV("Received hwc1Hotplug(%d, %d)", hwc1DisplayId, connected);
2472
2473 if (hwc1DisplayId != HWC_DISPLAY_EXTERNAL) {
2474 ALOGE("hwc1Hotplug: Received hotplug for non-external display");
2475 return;
2476 }
2477
Dan Stozafc4e2022016-02-23 11:43:19 -08002478 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002479
2480 // If the HWC2-side callback hasn't been registered yet, buffer this until
2481 // it is registered
2482 if (mCallbacks.count(Callback::Hotplug) == 0) {
2483 mPendingHotplugs.emplace_back(hwc1DisplayId, connected);
2484 return;
2485 }
2486
2487 hwc2_display_t displayId = UINT64_MAX;
2488 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2489 if (connected == 0) {
2490 ALOGW("hwc1Hotplug: Received disconnect for unconnected display");
2491 return;
2492 }
2493
2494 // Create a new display on connect
2495 auto display = std::make_shared<HWC2On1Adapter::Display>(*this,
2496 HWC2::DisplayType::Physical);
2497 display->setHwc1Id(HWC_DISPLAY_EXTERNAL);
2498 display->populateConfigs();
2499 displayId = display->getId();
2500 mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL] = displayId;
2501 mDisplays.emplace(displayId, std::move(display));
2502 } else {
2503 if (connected != 0) {
2504 ALOGW("hwc1Hotplug: Received connect for previously connected "
2505 "display");
2506 return;
2507 }
2508
2509 // Disconnect an existing display
2510 displayId = mHwc1DisplayMap[hwc1DisplayId];
2511 mHwc1DisplayMap.erase(HWC_DISPLAY_EXTERNAL);
2512 mDisplays.erase(displayId);
2513 }
2514
2515 const auto& callbackInfo = mCallbacks[Callback::Hotplug];
2516
2517 // Call back without the state lock held
2518 lock.unlock();
2519
2520 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(callbackInfo.pointer);
2521 auto hwc2Connected = (connected == 0) ?
2522 HWC2::Connection::Disconnected : HWC2::Connection::Connected;
2523 hotplug(callbackInfo.data, displayId, static_cast<int32_t>(hwc2Connected));
2524}
Dan Stozac6998d22015-09-24 17:03:36 -07002525} // namespace android