blob: 418789004a77f3cf400986f9b1cdc4324b8a6281 [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
Dan Stozac6998d22015-09-24 17:03:36 -0700964 if (!mChanges) {
965 if (!mDevice.prepareAllDisplays()) {
966 return Error::BadDisplay;
967 }
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800968 } else {
969 ALOGE("Validate was called more than once!");
Dan Stozac6998d22015-09-24 17:03:36 -0700970 }
971
972 *outNumTypes = mChanges->getNumTypes();
973 *outNumRequests = mChanges->getNumLayerRequests();
974 ALOGV("[%" PRIu64 "] validate --> %u types, %u requests", mId, *outNumTypes,
975 *outNumRequests);
976 for (auto request : mChanges->getTypeChanges()) {
977 ALOGV("Layer %" PRIu64 " --> %s", request.first,
978 to_string(request.second).c_str());
979 }
980 return *outNumTypes > 0 ? Error::HasChanges : Error::None;
981}
982
Fabien Sanglard06e908a2017-02-12 00:08:14 -0800983Error HWC2On1Adapter::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
Dan Stozac6998d22015-09-24 17:03:36 -0700984 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
985
986 const auto mapLayer = mDevice.mLayers.find(layerId);
987 if (mapLayer == mDevice.mLayers.end()) {
988 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer", mId);
989 return Error::BadLayer;
990 }
991
992 const auto layer = mapLayer->second;
993 const auto zRange = mLayers.equal_range(layer);
994 bool layerOnDisplay = false;
995 for (auto current = zRange.first; current != zRange.second; ++current) {
996 if (**current == *layer) {
997 if ((*current)->getZ() == z) {
998 // Don't change anything if the Z hasn't changed
999 return Error::None;
1000 }
1001 current = mLayers.erase(current);
1002 layerOnDisplay = true;
1003 break;
1004 }
1005 }
1006
1007 if (!layerOnDisplay) {
1008 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display",
1009 mId);
1010 return Error::BadLayer;
1011 }
1012
1013 layer->setZ(z);
1014 mLayers.emplace(std::move(layer));
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001015 markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001016
1017 return Error::None;
1018}
1019
Dan Stoza076ac672016-03-14 10:47:53 -07001020static constexpr uint32_t ATTRIBUTES_WITH_COLOR[] = {
1021 HWC_DISPLAY_VSYNC_PERIOD,
1022 HWC_DISPLAY_WIDTH,
1023 HWC_DISPLAY_HEIGHT,
1024 HWC_DISPLAY_DPI_X,
1025 HWC_DISPLAY_DPI_Y,
1026 HWC_DISPLAY_COLOR_TRANSFORM,
1027 HWC_DISPLAY_NO_ATTRIBUTE,
1028};
1029
1030static constexpr uint32_t ATTRIBUTES_WITHOUT_COLOR[] = {
Dan Stozac6998d22015-09-24 17:03:36 -07001031 HWC_DISPLAY_VSYNC_PERIOD,
1032 HWC_DISPLAY_WIDTH,
1033 HWC_DISPLAY_HEIGHT,
1034 HWC_DISPLAY_DPI_X,
1035 HWC_DISPLAY_DPI_Y,
1036 HWC_DISPLAY_NO_ATTRIBUTE,
1037};
Dan Stozac6998d22015-09-24 17:03:36 -07001038
Dan Stoza076ac672016-03-14 10:47:53 -07001039static constexpr size_t NUM_ATTRIBUTES_WITH_COLOR =
1040 sizeof(ATTRIBUTES_WITH_COLOR) / sizeof(uint32_t);
1041static_assert(sizeof(ATTRIBUTES_WITH_COLOR) > sizeof(ATTRIBUTES_WITHOUT_COLOR),
1042 "Attribute tables have unexpected sizes");
1043
1044static constexpr uint32_t ATTRIBUTE_MAP_WITH_COLOR[] = {
1045 6, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1046 0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1047 1, // HWC_DISPLAY_WIDTH = 2,
1048 2, // HWC_DISPLAY_HEIGHT = 3,
1049 3, // HWC_DISPLAY_DPI_X = 4,
1050 4, // HWC_DISPLAY_DPI_Y = 5,
1051 5, // HWC_DISPLAY_COLOR_TRANSFORM = 6,
1052};
1053
1054static constexpr uint32_t ATTRIBUTE_MAP_WITHOUT_COLOR[] = {
Dan Stozac6998d22015-09-24 17:03:36 -07001055 5, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1056 0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1057 1, // HWC_DISPLAY_WIDTH = 2,
1058 2, // HWC_DISPLAY_HEIGHT = 3,
1059 3, // HWC_DISPLAY_DPI_X = 4,
1060 4, // HWC_DISPLAY_DPI_Y = 5,
1061};
1062
1063template <uint32_t attribute>
1064static constexpr bool attributesMatch()
1065{
Dan Stoza076ac672016-03-14 10:47:53 -07001066 bool match = (attribute ==
1067 ATTRIBUTES_WITH_COLOR[ATTRIBUTE_MAP_WITH_COLOR[attribute]]);
1068 if (attribute == HWC_DISPLAY_COLOR_TRANSFORM) {
1069 return match;
1070 }
1071
1072 return match && (attribute ==
1073 ATTRIBUTES_WITHOUT_COLOR[ATTRIBUTE_MAP_WITHOUT_COLOR[attribute]]);
Dan Stozac6998d22015-09-24 17:03:36 -07001074}
1075static_assert(attributesMatch<HWC_DISPLAY_VSYNC_PERIOD>(),
1076 "Tables out of sync");
1077static_assert(attributesMatch<HWC_DISPLAY_WIDTH>(), "Tables out of sync");
1078static_assert(attributesMatch<HWC_DISPLAY_HEIGHT>(), "Tables out of sync");
1079static_assert(attributesMatch<HWC_DISPLAY_DPI_X>(), "Tables out of sync");
1080static_assert(attributesMatch<HWC_DISPLAY_DPI_Y>(), "Tables out of sync");
Dan Stoza076ac672016-03-14 10:47:53 -07001081static_assert(attributesMatch<HWC_DISPLAY_COLOR_TRANSFORM>(),
1082 "Tables out of sync");
Dan Stozac6998d22015-09-24 17:03:36 -07001083
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001084void HWC2On1Adapter::Display::populateConfigs() {
Dan Stozac6998d22015-09-24 17:03:36 -07001085 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1086
1087 ALOGV("[%" PRIu64 "] populateConfigs", mId);
1088
1089 if (mHwc1Id == -1) {
1090 ALOGE("populateConfigs: HWC1 ID not set");
1091 return;
1092 }
1093
1094 const size_t MAX_NUM_CONFIGS = 128;
1095 uint32_t configs[MAX_NUM_CONFIGS] = {};
1096 size_t numConfigs = MAX_NUM_CONFIGS;
1097 mDevice.mHwc1Device->getDisplayConfigs(mDevice.mHwc1Device, mHwc1Id,
1098 configs, &numConfigs);
1099
1100 for (size_t c = 0; c < numConfigs; ++c) {
1101 uint32_t hwc1ConfigId = configs[c];
Dan Stoza076ac672016-03-14 10:47:53 -07001102 auto newConfig = std::make_shared<Config>(*this);
Dan Stozac6998d22015-09-24 17:03:36 -07001103
Dan Stoza076ac672016-03-14 10:47:53 -07001104 int32_t values[NUM_ATTRIBUTES_WITH_COLOR] = {};
1105 bool hasColor = true;
1106 auto result = mDevice.mHwc1Device->getDisplayAttributes(
1107 mDevice.mHwc1Device, mHwc1Id, hwc1ConfigId,
1108 ATTRIBUTES_WITH_COLOR, values);
1109 if (result != 0) {
1110 mDevice.mHwc1Device->getDisplayAttributes(mDevice.mHwc1Device,
1111 mHwc1Id, hwc1ConfigId, ATTRIBUTES_WITHOUT_COLOR, values);
1112 hasColor = false;
Dan Stozac6998d22015-09-24 17:03:36 -07001113 }
Dan Stoza076ac672016-03-14 10:47:53 -07001114
1115 auto attributeMap = hasColor ?
1116 ATTRIBUTE_MAP_WITH_COLOR : ATTRIBUTE_MAP_WITHOUT_COLOR;
1117
1118 newConfig->setAttribute(Attribute::VsyncPeriod,
1119 values[attributeMap[HWC_DISPLAY_VSYNC_PERIOD]]);
1120 newConfig->setAttribute(Attribute::Width,
1121 values[attributeMap[HWC_DISPLAY_WIDTH]]);
1122 newConfig->setAttribute(Attribute::Height,
1123 values[attributeMap[HWC_DISPLAY_HEIGHT]]);
1124 newConfig->setAttribute(Attribute::DpiX,
1125 values[attributeMap[HWC_DISPLAY_DPI_X]]);
1126 newConfig->setAttribute(Attribute::DpiY,
1127 values[attributeMap[HWC_DISPLAY_DPI_Y]]);
1128 if (hasColor) {
Michael Wright28f24d02016-07-12 13:30:53 -07001129 // In HWC1, color modes are referred to as color transforms. To avoid confusion with
1130 // the HWC2 concept of color transforms, we internally refer to them as color modes for
1131 // both HWC1 and 2.
1132 newConfig->setAttribute(ColorMode,
Dan Stoza076ac672016-03-14 10:47:53 -07001133 values[attributeMap[HWC_DISPLAY_COLOR_TRANSFORM]]);
1134 }
1135
Michael Wright28f24d02016-07-12 13:30:53 -07001136 // We can only do this after attempting to read the color mode
Dan Stoza076ac672016-03-14 10:47:53 -07001137 newConfig->setHwc1Id(hwc1ConfigId);
1138
1139 for (auto& existingConfig : mConfigs) {
1140 if (existingConfig->merge(*newConfig)) {
1141 ALOGV("Merged config %d with existing config %u: %s",
1142 hwc1ConfigId, existingConfig->getId(),
1143 existingConfig->toString().c_str());
1144 newConfig.reset();
1145 break;
1146 }
1147 }
1148
1149 // If it wasn't merged with any existing config, add it to the end
1150 if (newConfig) {
1151 newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
1152 ALOGV("Found new config %u: %s", newConfig->getId(),
1153 newConfig->toString().c_str());
1154 mConfigs.emplace_back(std::move(newConfig));
1155 }
Dan Stozac6998d22015-09-24 17:03:36 -07001156 }
Dan Stoza076ac672016-03-14 10:47:53 -07001157
1158 initializeActiveConfig();
1159 populateColorModes();
Dan Stozac6998d22015-09-24 17:03:36 -07001160}
1161
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001162void HWC2On1Adapter::Display::populateConfigs(uint32_t width, uint32_t height) {
Dan Stozac6998d22015-09-24 17:03:36 -07001163 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1164
Dan Stoza076ac672016-03-14 10:47:53 -07001165 mConfigs.emplace_back(std::make_shared<Config>(*this));
Dan Stozac6998d22015-09-24 17:03:36 -07001166 auto& config = mConfigs[0];
1167
1168 config->setAttribute(Attribute::Width, static_cast<int32_t>(width));
1169 config->setAttribute(Attribute::Height, static_cast<int32_t>(height));
Dan Stoza076ac672016-03-14 10:47:53 -07001170 config->setHwc1Id(0);
1171 config->setId(0);
Dan Stozac6998d22015-09-24 17:03:36 -07001172 mActiveConfig = config;
1173}
1174
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001175bool HWC2On1Adapter::Display::prepare() {
Dan Stozac6998d22015-09-24 17:03:36 -07001176 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1177
1178 // Only prepare display contents for displays HWC1 knows about
1179 if (mHwc1Id == -1) {
1180 return true;
1181 }
1182
1183 // It doesn't make sense to prepare a display for which there is no active
1184 // config, so return early
1185 if (!mActiveConfig) {
1186 ALOGE("[%" PRIu64 "] Attempted to prepare, but no config active", mId);
1187 return false;
1188 }
1189
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001190 allocateRequestedContents();
1191 assignHwc1LayerIds();
Dan Stozac6998d22015-09-24 17:03:36 -07001192
1193 mHwc1RequestedContents->retireFenceFd = -1;
1194 mHwc1RequestedContents->flags = 0;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001195 if (mGeometryChanged) {
Dan Stozac6998d22015-09-24 17:03:36 -07001196 mHwc1RequestedContents->flags |= HWC_GEOMETRY_CHANGED;
1197 }
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001198 mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer();
1199 mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence();
Dan Stozac6998d22015-09-24 17:03:36 -07001200
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001201 // +1 is for framebuffer target layer.
1202 mHwc1RequestedContents->numHwLayers = mLayers.size() + 1;
Dan Stozac6998d22015-09-24 17:03:36 -07001203 for (auto& layer : mLayers) {
1204 auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
1205 hwc1Layer.releaseFenceFd = -1;
Fabien Sanglard16ab8192017-01-31 12:12:10 -08001206 hwc1Layer.acquireFenceFd = -1;
Fabien Sanglard999a7fd2017-02-02 16:59:44 -08001207 ALOGV("Applying states for layer %" PRIu64 " ", layer->getId());
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001208 layer->applyState(hwc1Layer);
Dan Stozac6998d22015-09-24 17:03:36 -07001209 }
1210
Dan Stozac6998d22015-09-24 17:03:36 -07001211 prepareFramebufferTarget();
1212
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001213 resetGeometryMarker();
1214
Dan Stozac6998d22015-09-24 17:03:36 -07001215 return true;
1216}
1217
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001218void HWC2On1Adapter::Display::generateChanges() {
Dan Stozac6998d22015-09-24 17:03:36 -07001219 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1220
Dan Stozac6998d22015-09-24 17:03:36 -07001221 mChanges.reset(new Changes);
1222
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001223 size_t numLayers = mHwc1RequestedContents->numHwLayers;
Dan Stozac6998d22015-09-24 17:03:36 -07001224 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001225 const auto& receivedLayer = mHwc1RequestedContents->hwLayers[hwc1Id];
Dan Stozac6998d22015-09-24 17:03:36 -07001226 if (mHwc1LayerMap.count(hwc1Id) == 0) {
1227 ALOGE_IF(receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001228 "generateChanges: HWC1 layer %zd doesn't have a"
Dan Stozac6998d22015-09-24 17:03:36 -07001229 " matching HWC2 layer, and isn't the framebuffer target",
1230 hwc1Id);
1231 continue;
1232 }
1233
1234 Layer& layer = *mHwc1LayerMap[hwc1Id];
1235 updateTypeChanges(receivedLayer, layer);
1236 updateLayerRequests(receivedLayer, layer);
1237 }
1238}
1239
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001240bool HWC2On1Adapter::Display::hasChanges() const {
Dan Stozac6998d22015-09-24 17:03:36 -07001241 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1242 return mChanges != nullptr;
1243}
1244
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001245Error HWC2On1Adapter::Display::set(hwc_display_contents_1& hwcContents) {
Dan Stozac6998d22015-09-24 17:03:36 -07001246 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1247
1248 if (!mChanges || (mChanges->getNumTypes() > 0)) {
1249 ALOGE("[%" PRIu64 "] set failed: not validated", mId);
1250 return Error::NotValidated;
1251 }
1252
1253 // Set up the client/framebuffer target
1254 auto numLayers = hwcContents.numHwLayers;
1255
1256 // Close acquire fences on FRAMEBUFFER layers, since they will not be used
1257 // by HWC
1258 for (size_t l = 0; l < numLayers - 1; ++l) {
1259 auto& layer = hwcContents.hwLayers[l];
1260 if (layer.compositionType == HWC_FRAMEBUFFER) {
1261 ALOGV("Closing fence %d for layer %zd", layer.acquireFenceFd, l);
1262 close(layer.acquireFenceFd);
1263 layer.acquireFenceFd = -1;
1264 }
1265 }
1266
1267 auto& clientTargetLayer = hwcContents.hwLayers[numLayers - 1];
1268 if (clientTargetLayer.compositionType == HWC_FRAMEBUFFER_TARGET) {
1269 clientTargetLayer.handle = mClientTarget.getBuffer();
1270 clientTargetLayer.acquireFenceFd = mClientTarget.getFence();
1271 } else {
1272 ALOGE("[%" PRIu64 "] set: last HWC layer wasn't FRAMEBUFFER_TARGET",
1273 mId);
1274 }
1275
1276 mChanges.reset();
1277
1278 return Error::None;
1279}
1280
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001281void HWC2On1Adapter::Display::addRetireFence(int fenceFd) {
Dan Stozac6998d22015-09-24 17:03:36 -07001282 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1283 mRetireFence.add(fenceFd);
1284}
1285
1286void HWC2On1Adapter::Display::addReleaseFences(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001287 const hwc_display_contents_1_t& hwcContents) {
Dan Stozac6998d22015-09-24 17:03:36 -07001288 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1289
1290 size_t numLayers = hwcContents.numHwLayers;
1291 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1292 const auto& receivedLayer = hwcContents.hwLayers[hwc1Id];
1293 if (mHwc1LayerMap.count(hwc1Id) == 0) {
1294 if (receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET) {
1295 ALOGE("addReleaseFences: HWC1 layer %zd doesn't have a"
1296 " matching HWC2 layer, and isn't the framebuffer"
1297 " target", hwc1Id);
1298 }
1299 // Close the framebuffer target release fence since we will use the
1300 // display retire fence instead
1301 if (receivedLayer.releaseFenceFd != -1) {
1302 close(receivedLayer.releaseFenceFd);
1303 }
1304 continue;
1305 }
1306
1307 Layer& layer = *mHwc1LayerMap[hwc1Id];
1308 ALOGV("Adding release fence %d to layer %" PRIu64,
1309 receivedLayer.releaseFenceFd, layer.getId());
1310 layer.addReleaseFence(receivedLayer.releaseFenceFd);
1311 }
1312}
1313
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001314bool HWC2On1Adapter::Display::hasColorTransform() const {
Dan Stoza5df2a862016-03-24 16:19:37 -07001315 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1316 return mHasColorTransform;
1317}
1318
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001319static std::string hwc1CompositionString(int32_t type) {
Dan Stozac6998d22015-09-24 17:03:36 -07001320 switch (type) {
1321 case HWC_FRAMEBUFFER: return "Framebuffer";
1322 case HWC_OVERLAY: return "Overlay";
1323 case HWC_BACKGROUND: return "Background";
1324 case HWC_FRAMEBUFFER_TARGET: return "FramebufferTarget";
1325 case HWC_SIDEBAND: return "Sideband";
1326 case HWC_CURSOR_OVERLAY: return "CursorOverlay";
1327 default:
1328 return std::string("Unknown (") + std::to_string(type) + ")";
1329 }
1330}
1331
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001332static std::string hwc1TransformString(int32_t transform) {
Dan Stozac6998d22015-09-24 17:03:36 -07001333 switch (transform) {
1334 case 0: return "None";
1335 case HWC_TRANSFORM_FLIP_H: return "FlipH";
1336 case HWC_TRANSFORM_FLIP_V: return "FlipV";
1337 case HWC_TRANSFORM_ROT_90: return "Rotate90";
1338 case HWC_TRANSFORM_ROT_180: return "Rotate180";
1339 case HWC_TRANSFORM_ROT_270: return "Rotate270";
1340 case HWC_TRANSFORM_FLIP_H_ROT_90: return "FlipHRotate90";
1341 case HWC_TRANSFORM_FLIP_V_ROT_90: return "FlipVRotate90";
1342 default:
1343 return std::string("Unknown (") + std::to_string(transform) + ")";
1344 }
1345}
1346
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001347static std::string hwc1BlendModeString(int32_t mode) {
Dan Stozac6998d22015-09-24 17:03:36 -07001348 switch (mode) {
1349 case HWC_BLENDING_NONE: return "None";
1350 case HWC_BLENDING_PREMULT: return "Premultiplied";
1351 case HWC_BLENDING_COVERAGE: return "Coverage";
1352 default:
1353 return std::string("Unknown (") + std::to_string(mode) + ")";
1354 }
1355}
1356
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001357static std::string rectString(hwc_rect_t rect) {
Dan Stozac6998d22015-09-24 17:03:36 -07001358 std::stringstream output;
1359 output << "[" << rect.left << ", " << rect.top << ", ";
1360 output << rect.right << ", " << rect.bottom << "]";
1361 return output.str();
1362}
1363
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001364static std::string approximateFloatString(float f) {
Dan Stozac6998d22015-09-24 17:03:36 -07001365 if (static_cast<int32_t>(f) == f) {
1366 return std::to_string(static_cast<int32_t>(f));
1367 }
1368 int32_t truncated = static_cast<int32_t>(f * 10);
1369 bool approximate = (static_cast<float>(truncated) != f * 10);
1370 const size_t BUFFER_SIZE = 32;
1371 char buffer[BUFFER_SIZE] = {};
1372 auto bytesWritten = snprintf(buffer, BUFFER_SIZE,
1373 "%s%.1f", approximate ? "~" : "", f);
1374 return std::string(buffer, bytesWritten);
1375}
1376
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001377static std::string frectString(hwc_frect_t frect) {
Dan Stozac6998d22015-09-24 17:03:36 -07001378 std::stringstream output;
1379 output << "[" << approximateFloatString(frect.left) << ", ";
1380 output << approximateFloatString(frect.top) << ", ";
1381 output << approximateFloatString(frect.right) << ", ";
1382 output << approximateFloatString(frect.bottom) << "]";
1383 return output.str();
1384}
1385
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001386static std::string colorString(hwc_color_t color) {
Dan Stozac6998d22015-09-24 17:03:36 -07001387 std::stringstream output;
1388 output << "RGBA [";
1389 output << static_cast<int32_t>(color.r) << ", ";
1390 output << static_cast<int32_t>(color.g) << ", ";
1391 output << static_cast<int32_t>(color.b) << ", ";
1392 output << static_cast<int32_t>(color.a) << "]";
1393 return output.str();
1394}
1395
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001396static std::string alphaString(float f) {
Dan Stozac6998d22015-09-24 17:03:36 -07001397 const size_t BUFFER_SIZE = 8;
1398 char buffer[BUFFER_SIZE] = {};
1399 auto bytesWritten = snprintf(buffer, BUFFER_SIZE, "%.3f", f);
1400 return std::string(buffer, bytesWritten);
1401}
1402
1403static std::string to_string(const hwc_layer_1_t& hwcLayer,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001404 int32_t hwc1MinorVersion) {
Dan Stozac6998d22015-09-24 17:03:36 -07001405 const char* fill = " ";
1406
1407 std::stringstream output;
1408
1409 output << " Composition: " <<
1410 hwc1CompositionString(hwcLayer.compositionType);
1411
1412 if (hwcLayer.compositionType == HWC_BACKGROUND) {
1413 output << " Color: " << colorString(hwcLayer.backgroundColor) << '\n';
1414 } else if (hwcLayer.compositionType == HWC_SIDEBAND) {
1415 output << " Stream: " << hwcLayer.sidebandStream << '\n';
1416 } else {
1417 output << " Buffer: " << hwcLayer.handle << "/" <<
1418 hwcLayer.acquireFenceFd << '\n';
1419 }
1420
1421 output << fill << "Display frame: " << rectString(hwcLayer.displayFrame) <<
1422 '\n';
1423
1424 output << fill << "Source crop: ";
1425 if (hwc1MinorVersion >= 3) {
1426 output << frectString(hwcLayer.sourceCropf) << '\n';
1427 } else {
1428 output << rectString(hwcLayer.sourceCropi) << '\n';
1429 }
1430
1431 output << fill << "Transform: " << hwc1TransformString(hwcLayer.transform);
1432 output << " Blend mode: " << hwc1BlendModeString(hwcLayer.blending);
1433 if (hwcLayer.planeAlpha != 0xFF) {
1434 output << " Alpha: " << alphaString(hwcLayer.planeAlpha / 255.0f);
1435 }
1436 output << '\n';
1437
1438 if (hwcLayer.hints != 0) {
1439 output << fill << "Hints:";
1440 if ((hwcLayer.hints & HWC_HINT_TRIPLE_BUFFER) != 0) {
1441 output << " TripleBuffer";
1442 }
1443 if ((hwcLayer.hints & HWC_HINT_CLEAR_FB) != 0) {
1444 output << " ClearFB";
1445 }
1446 output << '\n';
1447 }
1448
1449 if (hwcLayer.flags != 0) {
1450 output << fill << "Flags:";
1451 if ((hwcLayer.flags & HWC_SKIP_LAYER) != 0) {
1452 output << " SkipLayer";
1453 }
1454 if ((hwcLayer.flags & HWC_IS_CURSOR_LAYER) != 0) {
1455 output << " IsCursorLayer";
1456 }
1457 output << '\n';
1458 }
1459
1460 return output.str();
1461}
1462
1463static std::string to_string(const hwc_display_contents_1_t& hwcContents,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001464 int32_t hwc1MinorVersion) {
Dan Stozac6998d22015-09-24 17:03:36 -07001465 const char* fill = " ";
1466
1467 std::stringstream output;
1468 output << fill << "Geometry changed: " <<
1469 ((hwcContents.flags & HWC_GEOMETRY_CHANGED) != 0 ? "Y\n" : "N\n");
1470
1471 output << fill << hwcContents.numHwLayers << " Layer" <<
1472 ((hwcContents.numHwLayers == 1) ? "\n" : "s\n");
1473 for (size_t layer = 0; layer < hwcContents.numHwLayers; ++layer) {
1474 output << fill << " Layer " << layer;
1475 output << to_string(hwcContents.hwLayers[layer], hwc1MinorVersion);
1476 }
1477
1478 if (hwcContents.outbuf != nullptr) {
1479 output << fill << "Output buffer: " << hwcContents.outbuf << "/" <<
1480 hwcContents.outbufAcquireFenceFd << '\n';
1481 }
1482
1483 return output.str();
1484}
1485
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001486std::string HWC2On1Adapter::Display::dump() const {
Dan Stozac6998d22015-09-24 17:03:36 -07001487 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1488
1489 std::stringstream output;
1490
1491 output << " Display " << mId << ": ";
1492 output << to_string(mType) << " ";
1493 output << "HWC1 ID: " << mHwc1Id << " ";
1494 output << "Power mode: " << to_string(mPowerMode) << " ";
1495 output << "Vsync: " << to_string(mVsyncEnabled) << '\n';
1496
Dan Stoza076ac672016-03-14 10:47:53 -07001497 output << " Color modes [active]:";
1498 for (const auto& mode : mColorModes) {
1499 if (mode == mActiveColorMode) {
1500 output << " [" << mode << ']';
Dan Stozac6998d22015-09-24 17:03:36 -07001501 } else {
Dan Stoza076ac672016-03-14 10:47:53 -07001502 output << " " << mode;
Dan Stozac6998d22015-09-24 17:03:36 -07001503 }
1504 }
1505 output << '\n';
1506
Dan Stoza076ac672016-03-14 10:47:53 -07001507 output << " " << mConfigs.size() << " Config" <<
1508 (mConfigs.size() == 1 ? "" : "s") << " (* active)\n";
1509 for (const auto& config : mConfigs) {
1510 output << (config == mActiveConfig ? " * " : " ");
1511 output << config->toString(true) << '\n';
1512 }
1513
Dan Stozac6998d22015-09-24 17:03:36 -07001514 output << " " << mLayers.size() << " Layer" <<
1515 (mLayers.size() == 1 ? "" : "s") << '\n';
1516 for (const auto& layer : mLayers) {
1517 output << layer->dump();
1518 }
1519
1520 output << " Client target: " << mClientTarget.getBuffer() << '\n';
1521
1522 if (mOutputBuffer.getBuffer() != nullptr) {
1523 output << " Output buffer: " << mOutputBuffer.getBuffer() << '\n';
1524 }
1525
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001526 if (mHwc1RequestedContents) {
Dan Stozac6998d22015-09-24 17:03:36 -07001527 output << " Last requested HWC1 state\n";
1528 output << to_string(*mHwc1RequestedContents, mDevice.mHwc1MinorVersion);
1529 }
1530
1531 return output.str();
1532}
1533
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001534hwc_rect_t* HWC2On1Adapter::Display::GetRects(size_t numRects) {
1535 if (numRects == 0) {
1536 return nullptr;
1537 }
1538
1539 if (numRects > mNumAvailableRects) {
1540 // This should NEVER happen since we calculated how many rects the
1541 // display would need.
1542 ALOGE("Rect allocation failure! SF is likely to crash soon!");
1543 return nullptr;
1544
1545 }
1546 hwc_rect_t* rects = mNextAvailableRect;
1547 mNextAvailableRect += numRects;
1548 mNumAvailableRects -= numRects;
1549 return rects;
1550}
1551
1552hwc_display_contents_1* HWC2On1Adapter::Display::getDisplayContents() {
1553 return mHwc1RequestedContents.get();
1554}
1555
Dan Stozac6998d22015-09-24 17:03:36 -07001556void HWC2On1Adapter::Display::Config::setAttribute(HWC2::Attribute attribute,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001557 int32_t value) {
Dan Stozac6998d22015-09-24 17:03:36 -07001558 mAttributes[attribute] = value;
1559}
1560
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001561int32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const {
Dan Stozac6998d22015-09-24 17:03:36 -07001562 if (mAttributes.count(attribute) == 0) {
1563 return -1;
1564 }
1565 return mAttributes.at(attribute);
1566}
1567
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001568void HWC2On1Adapter::Display::Config::setHwc1Id(uint32_t id) {
Michael Wright28f24d02016-07-12 13:30:53 -07001569 android_color_mode_t colorMode = static_cast<android_color_mode_t>(getAttribute(ColorMode));
1570 mHwc1Ids.emplace(colorMode, id);
Dan Stoza076ac672016-03-14 10:47:53 -07001571}
1572
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001573bool HWC2On1Adapter::Display::Config::hasHwc1Id(uint32_t id) const {
Dan Stoza076ac672016-03-14 10:47:53 -07001574 for (const auto& idPair : mHwc1Ids) {
1575 if (id == idPair.second) {
1576 return true;
1577 }
1578 }
1579 return false;
1580}
1581
Michael Wright28f24d02016-07-12 13:30:53 -07001582Error HWC2On1Adapter::Display::Config::getColorModeForHwc1Id(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001583 uint32_t id, android_color_mode_t* outMode) const {
Dan Stoza076ac672016-03-14 10:47:53 -07001584 for (const auto& idPair : mHwc1Ids) {
1585 if (id == idPair.second) {
Michael Wright28f24d02016-07-12 13:30:53 -07001586 *outMode = idPair.first;
1587 return Error::None;
Dan Stoza076ac672016-03-14 10:47:53 -07001588 }
1589 }
Michael Wright28f24d02016-07-12 13:30:53 -07001590 ALOGE("Unable to find color mode for HWC ID %" PRIu32 " on config %u", id, mId);
1591 return Error::BadParameter;
Dan Stoza076ac672016-03-14 10:47:53 -07001592}
1593
Michael Wright28f24d02016-07-12 13:30:53 -07001594Error HWC2On1Adapter::Display::Config::getHwc1IdForColorMode(android_color_mode_t mode,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001595 uint32_t* outId) const {
Dan Stoza076ac672016-03-14 10:47:53 -07001596 for (const auto& idPair : mHwc1Ids) {
1597 if (mode == idPair.first) {
1598 *outId = idPair.second;
1599 return Error::None;
1600 }
1601 }
1602 ALOGE("Unable to find HWC1 ID for color mode %d on config %u", mode, mId);
1603 return Error::BadParameter;
1604}
1605
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001606bool HWC2On1Adapter::Display::Config::merge(const Config& other) {
Dan Stoza076ac672016-03-14 10:47:53 -07001607 auto attributes = {HWC2::Attribute::Width, HWC2::Attribute::Height,
1608 HWC2::Attribute::VsyncPeriod, HWC2::Attribute::DpiX,
1609 HWC2::Attribute::DpiY};
1610 for (auto attribute : attributes) {
1611 if (getAttribute(attribute) != other.getAttribute(attribute)) {
1612 return false;
1613 }
1614 }
Michael Wright28f24d02016-07-12 13:30:53 -07001615 android_color_mode_t otherColorMode =
1616 static_cast<android_color_mode_t>(other.getAttribute(ColorMode));
1617 if (mHwc1Ids.count(otherColorMode) != 0) {
Dan Stoza076ac672016-03-14 10:47:53 -07001618 ALOGE("Attempted to merge two configs (%u and %u) which appear to be "
Michael Wright28f24d02016-07-12 13:30:53 -07001619 "identical", mHwc1Ids.at(otherColorMode),
1620 other.mHwc1Ids.at(otherColorMode));
Dan Stoza076ac672016-03-14 10:47:53 -07001621 return false;
1622 }
Michael Wright28f24d02016-07-12 13:30:53 -07001623 mHwc1Ids.emplace(otherColorMode,
1624 other.mHwc1Ids.at(otherColorMode));
Dan Stoza076ac672016-03-14 10:47:53 -07001625 return true;
1626}
1627
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001628std::set<android_color_mode_t> HWC2On1Adapter::Display::Config::getColorModes() const {
Michael Wright28f24d02016-07-12 13:30:53 -07001629 std::set<android_color_mode_t> colorModes;
Dan Stoza076ac672016-03-14 10:47:53 -07001630 for (const auto& idPair : mHwc1Ids) {
Michael Wright28f24d02016-07-12 13:30:53 -07001631 colorModes.emplace(idPair.first);
Dan Stoza076ac672016-03-14 10:47:53 -07001632 }
Michael Wright28f24d02016-07-12 13:30:53 -07001633 return colorModes;
Dan Stoza076ac672016-03-14 10:47:53 -07001634}
1635
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001636std::string HWC2On1Adapter::Display::Config::toString(bool splitLine) const {
Dan Stozac6998d22015-09-24 17:03:36 -07001637 std::string output;
1638
1639 const size_t BUFFER_SIZE = 100;
1640 char buffer[BUFFER_SIZE] = {};
1641 auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
Dan Stoza076ac672016-03-14 10:47:53 -07001642 "%u x %u", mAttributes.at(HWC2::Attribute::Width),
Dan Stozac6998d22015-09-24 17:03:36 -07001643 mAttributes.at(HWC2::Attribute::Height));
1644 output.append(buffer, writtenBytes);
1645
1646 if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
1647 std::memset(buffer, 0, BUFFER_SIZE);
1648 writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
1649 1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
1650 output.append(buffer, writtenBytes);
1651 }
1652
1653 if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
1654 mAttributes.at(HWC2::Attribute::DpiX) != -1) {
1655 std::memset(buffer, 0, BUFFER_SIZE);
1656 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1657 ", DPI: %.1f x %.1f",
1658 mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
1659 mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
1660 output.append(buffer, writtenBytes);
1661 }
1662
Dan Stoza076ac672016-03-14 10:47:53 -07001663 std::memset(buffer, 0, BUFFER_SIZE);
1664 if (splitLine) {
1665 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1666 "\n HWC1 ID/Color transform:");
1667 } else {
1668 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1669 ", HWC1 ID/Color transform:");
1670 }
1671 output.append(buffer, writtenBytes);
1672
1673
1674 for (const auto& id : mHwc1Ids) {
Michael Wright28f24d02016-07-12 13:30:53 -07001675 android_color_mode_t colorMode = id.first;
Dan Stoza076ac672016-03-14 10:47:53 -07001676 uint32_t hwc1Id = id.second;
1677 std::memset(buffer, 0, BUFFER_SIZE);
Michael Wright28f24d02016-07-12 13:30:53 -07001678 if (colorMode == mDisplay.mActiveColorMode) {
Dan Stoza076ac672016-03-14 10:47:53 -07001679 writtenBytes = snprintf(buffer, BUFFER_SIZE, " [%u/%d]", hwc1Id,
Michael Wright28f24d02016-07-12 13:30:53 -07001680 colorMode);
Dan Stoza076ac672016-03-14 10:47:53 -07001681 } else {
1682 writtenBytes = snprintf(buffer, BUFFER_SIZE, " %u/%d", hwc1Id,
Michael Wright28f24d02016-07-12 13:30:53 -07001683 colorMode);
Dan Stoza076ac672016-03-14 10:47:53 -07001684 }
1685 output.append(buffer, writtenBytes);
1686 }
1687
Dan Stozac6998d22015-09-24 17:03:36 -07001688 return output;
1689}
1690
1691std::shared_ptr<const HWC2On1Adapter::Display::Config>
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001692 HWC2On1Adapter::Display::getConfig(hwc2_config_t configId) const {
Dan Stozac6998d22015-09-24 17:03:36 -07001693 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
1694 return nullptr;
1695 }
1696 return mConfigs[configId];
1697}
1698
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001699void HWC2On1Adapter::Display::populateColorModes() {
Michael Wright28f24d02016-07-12 13:30:53 -07001700 mColorModes = mConfigs[0]->getColorModes();
Dan Stoza076ac672016-03-14 10:47:53 -07001701 for (const auto& config : mConfigs) {
Michael Wright28f24d02016-07-12 13:30:53 -07001702 std::set<android_color_mode_t> intersection;
1703 auto configModes = config->getColorModes();
Dan Stoza076ac672016-03-14 10:47:53 -07001704 std::set_intersection(mColorModes.cbegin(), mColorModes.cend(),
1705 configModes.cbegin(), configModes.cend(),
1706 std::inserter(intersection, intersection.begin()));
1707 std::swap(intersection, mColorModes);
1708 }
1709}
1710
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001711void HWC2On1Adapter::Display::initializeActiveConfig() {
Dan Stoza076ac672016-03-14 10:47:53 -07001712 if (mDevice.mHwc1Device->getActiveConfig == nullptr) {
1713 ALOGV("getActiveConfig is null, choosing config 0");
1714 mActiveConfig = mConfigs[0];
Michael Wright28f24d02016-07-12 13:30:53 -07001715 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
Dan Stoza076ac672016-03-14 10:47:53 -07001716 return;
1717 }
1718
1719 auto activeConfig = mDevice.mHwc1Device->getActiveConfig(
1720 mDevice.mHwc1Device, mHwc1Id);
Fabien Sanglardb7432cc2016-11-11 09:40:27 -08001721
1722 // Some devices startup without an activeConfig:
1723 // We need to set one ourselves.
1724 if (activeConfig == HWC_ERROR) {
1725 ALOGV("There is no active configuration: Picking the first one: 0.");
1726 const int defaultIndex = 0;
1727 mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device, mHwc1Id, defaultIndex);
1728 activeConfig = defaultIndex;
1729 }
1730
1731 for (const auto& config : mConfigs) {
1732 if (config->hasHwc1Id(activeConfig)) {
1733 ALOGE("Setting active config to %d for HWC1 config %u", config->getId(), activeConfig);
1734 mActiveConfig = config;
1735 if (config->getColorModeForHwc1Id(activeConfig, &mActiveColorMode) != Error::None) {
1736 // This should never happen since we checked for the config's presence before
1737 // setting it as active.
1738 ALOGE("Unable to find color mode for active HWC1 config %d", config->getId());
1739 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
Dan Stoza076ac672016-03-14 10:47:53 -07001740 }
Fabien Sanglardb7432cc2016-11-11 09:40:27 -08001741 break;
Dan Stoza076ac672016-03-14 10:47:53 -07001742 }
1743 }
Fabien Sanglardb7432cc2016-11-11 09:40:27 -08001744 if (!mActiveConfig) {
1745 ALOGV("Unable to find active HWC1 config %u, defaulting to "
1746 "config 0", activeConfig);
1747 mActiveConfig = mConfigs[0];
1748 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1749 }
1750
1751
1752
1753
Dan Stoza076ac672016-03-14 10:47:53 -07001754}
1755
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001756void HWC2On1Adapter::Display::allocateRequestedContents() {
1757 // What needs to be allocated:
1758 // 1 hwc_display_contents_1_t
1759 // 1 hwc_layer_1_t for each layer
1760 // 1 hwc_rect_t for each layer's surfaceDamage
1761 // 1 hwc_rect_t for each layer's visibleRegion
1762 // 1 hwc_layer_1_t for the framebuffer
1763 // 1 hwc_rect_t for the framebuffer's visibleRegion
1764
1765 // Count # of surfaceDamage
1766 size_t numSurfaceDamages = 0;
1767 for (const auto& layer : mLayers) {
1768 numSurfaceDamages += layer->getNumSurfaceDamages();
1769 }
1770
1771 // Count # of visibleRegions (start at 1 for mandatory framebuffer target
1772 // region)
1773 size_t numVisibleRegion = 1;
1774 for (const auto& layer : mLayers) {
1775 numVisibleRegion += layer->getNumVisibleRegions();
1776 }
1777
1778 size_t numRects = numVisibleRegion + numSurfaceDamages;
Dan Stozac6998d22015-09-24 17:03:36 -07001779 auto numLayers = mLayers.size() + 1;
1780 size_t size = sizeof(hwc_display_contents_1_t) +
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001781 sizeof(hwc_layer_1_t) * numLayers +
1782 sizeof(hwc_rect_t) * numRects;
1783 auto contents = static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1));
Dan Stozac6998d22015-09-24 17:03:36 -07001784 mHwc1RequestedContents.reset(contents);
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001785 mNextAvailableRect = reinterpret_cast<hwc_rect_t*>(&contents->hwLayers[numLayers]);
1786 mNumAvailableRects = numRects;
Dan Stozac6998d22015-09-24 17:03:36 -07001787}
1788
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001789void HWC2On1Adapter::Display::assignHwc1LayerIds() {
Dan Stozac6998d22015-09-24 17:03:36 -07001790 mHwc1LayerMap.clear();
1791 size_t nextHwc1Id = 0;
1792 for (auto& layer : mLayers) {
1793 mHwc1LayerMap[nextHwc1Id] = layer;
1794 layer->setHwc1Id(nextHwc1Id++);
1795 }
1796}
1797
1798void HWC2On1Adapter::Display::updateTypeChanges(const hwc_layer_1_t& hwc1Layer,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001799 const Layer& layer) {
Dan Stozac6998d22015-09-24 17:03:36 -07001800 auto layerId = layer.getId();
1801 switch (hwc1Layer.compositionType) {
1802 case HWC_FRAMEBUFFER:
1803 if (layer.getCompositionType() != Composition::Client) {
1804 mChanges->addTypeChange(layerId, Composition::Client);
1805 }
1806 break;
1807 case HWC_OVERLAY:
1808 if (layer.getCompositionType() != Composition::Device) {
1809 mChanges->addTypeChange(layerId, Composition::Device);
1810 }
1811 break;
1812 case HWC_BACKGROUND:
1813 ALOGE_IF(layer.getCompositionType() != Composition::SolidColor,
1814 "updateTypeChanges: HWC1 requested BACKGROUND, but HWC2"
1815 " wasn't expecting SolidColor");
1816 break;
1817 case HWC_FRAMEBUFFER_TARGET:
1818 // Do nothing, since it shouldn't be modified by HWC1
1819 break;
1820 case HWC_SIDEBAND:
1821 ALOGE_IF(layer.getCompositionType() != Composition::Sideband,
1822 "updateTypeChanges: HWC1 requested SIDEBAND, but HWC2"
1823 " wasn't expecting Sideband");
1824 break;
1825 case HWC_CURSOR_OVERLAY:
1826 ALOGE_IF(layer.getCompositionType() != Composition::Cursor,
1827 "updateTypeChanges: HWC1 requested CURSOR_OVERLAY, but"
1828 " HWC2 wasn't expecting Cursor");
1829 break;
1830 }
1831}
1832
1833void HWC2On1Adapter::Display::updateLayerRequests(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001834 const hwc_layer_1_t& hwc1Layer, const Layer& layer) {
Dan Stozac6998d22015-09-24 17:03:36 -07001835 if ((hwc1Layer.hints & HWC_HINT_CLEAR_FB) != 0) {
1836 mChanges->addLayerRequest(layer.getId(),
1837 LayerRequest::ClearClientTarget);
1838 }
1839}
1840
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001841void HWC2On1Adapter::Display::prepareFramebufferTarget() {
Dan Stozac6998d22015-09-24 17:03:36 -07001842 // We check that mActiveConfig is valid in Display::prepare
1843 int32_t width = mActiveConfig->getAttribute(Attribute::Width);
1844 int32_t height = mActiveConfig->getAttribute(Attribute::Height);
1845
1846 auto& hwc1Target = mHwc1RequestedContents->hwLayers[mLayers.size()];
1847 hwc1Target.compositionType = HWC_FRAMEBUFFER_TARGET;
1848 hwc1Target.releaseFenceFd = -1;
1849 hwc1Target.hints = 0;
1850 hwc1Target.flags = 0;
1851 hwc1Target.transform = 0;
1852 hwc1Target.blending = HWC_BLENDING_PREMULT;
1853 if (mDevice.getHwc1MinorVersion() < 3) {
1854 hwc1Target.sourceCropi = {0, 0, width, height};
1855 } else {
1856 hwc1Target.sourceCropf = {0.0f, 0.0f, static_cast<float>(width),
1857 static_cast<float>(height)};
1858 }
1859 hwc1Target.displayFrame = {0, 0, width, height};
1860 hwc1Target.planeAlpha = 255;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001861
Dan Stozac6998d22015-09-24 17:03:36 -07001862 hwc1Target.visibleRegionScreen.numRects = 1;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001863 hwc_rect_t* rects = GetRects(1);
Dan Stozac6998d22015-09-24 17:03:36 -07001864 rects[0].left = 0;
1865 rects[0].top = 0;
1866 rects[0].right = width;
1867 rects[0].bottom = height;
1868 hwc1Target.visibleRegionScreen.rects = rects;
1869
1870 // We will set this to the correct value in set
1871 hwc1Target.acquireFenceFd = -1;
1872}
1873
1874// Layer functions
1875
1876std::atomic<hwc2_layer_t> HWC2On1Adapter::Layer::sNextId(1);
1877
1878HWC2On1Adapter::Layer::Layer(Display& display)
1879 : mId(sNextId++),
1880 mDisplay(display),
Dan Stozafc4e2022016-02-23 11:43:19 -08001881 mBuffer(),
1882 mSurfaceDamage(),
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001883 mBlendMode(BlendMode::None),
1884 mColor({0, 0, 0, 0}),
1885 mCompositionType(Composition::Invalid),
1886 mDisplayFrame({0, 0, -1, -1}),
1887 mPlaneAlpha(0.0f),
1888 mSidebandStream(nullptr),
1889 mSourceCrop({0.0f, 0.0f, -1.0f, -1.0f}),
1890 mTransform(Transform::None),
1891 mVisibleRegion(),
Dan Stozac6998d22015-09-24 17:03:36 -07001892 mZ(0),
Dan Stozafc4e2022016-02-23 11:43:19 -08001893 mReleaseFence(),
Dan Stozac6998d22015-09-24 17:03:36 -07001894 mHwc1Id(0),
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001895 mHasUnsupportedPlaneAlpha(false) {}
Dan Stozac6998d22015-09-24 17:03:36 -07001896
1897bool HWC2On1Adapter::SortLayersByZ::operator()(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001898 const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs) {
Dan Stozac6998d22015-09-24 17:03:36 -07001899 return lhs->getZ() < rhs->getZ();
1900}
1901
1902Error HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001903 int32_t acquireFence) {
Dan Stozac6998d22015-09-24 17:03:36 -07001904 ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
1905 mBuffer.setBuffer(buffer);
1906 mBuffer.setFence(acquireFence);
1907 return Error::None;
1908}
1909
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001910Error HWC2On1Adapter::Layer::setCursorPosition(int32_t x, int32_t y) {
1911 if (mCompositionType != Composition::Cursor) {
Dan Stozac6998d22015-09-24 17:03:36 -07001912 return Error::BadLayer;
1913 }
1914
1915 if (mDisplay.hasChanges()) {
1916 return Error::NotValidated;
1917 }
1918
1919 auto displayId = mDisplay.getHwc1Id();
1920 auto hwc1Device = mDisplay.getDevice().getHwc1Device();
1921 hwc1Device->setCursorPositionAsync(hwc1Device, displayId, x, y);
1922 return Error::None;
1923}
1924
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001925Error HWC2On1Adapter::Layer::setSurfaceDamage(hwc_region_t damage) {
Fabien Sanglard356bcd42017-02-17 16:14:18 -08001926 // HWC1 supports surface damage starting only with version 1.5.
1927 if (mDisplay.getDevice().mHwc1MinorVersion < 5) {
1928 return Error::None;
1929 }
Dan Stozac6998d22015-09-24 17:03:36 -07001930 mSurfaceDamage.resize(damage.numRects);
1931 std::copy_n(damage.rects, damage.numRects, mSurfaceDamage.begin());
1932 return Error::None;
1933}
1934
1935// Layer state functions
1936
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001937Error HWC2On1Adapter::Layer::setBlendMode(BlendMode mode) {
1938 mBlendMode = mode;
1939 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001940 return Error::None;
1941}
1942
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001943Error HWC2On1Adapter::Layer::setColor(hwc_color_t color) {
1944 mColor = color;
1945 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001946 return Error::None;
1947}
1948
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001949Error HWC2On1Adapter::Layer::setCompositionType(Composition type) {
1950 mCompositionType = type;
1951 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001952 return Error::None;
1953}
1954
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001955Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t) {
Dan Stoza5df2a862016-03-24 16:19:37 -07001956 return Error::None;
1957}
1958
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001959Error HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame) {
1960 mDisplayFrame = frame;
1961 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001962 return Error::None;
1963}
1964
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001965Error HWC2On1Adapter::Layer::setPlaneAlpha(float alpha) {
1966 mPlaneAlpha = alpha;
1967 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001968 return Error::None;
1969}
1970
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001971Error HWC2On1Adapter::Layer::setSidebandStream(const native_handle_t* stream) {
1972 mSidebandStream = stream;
1973 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001974 return Error::None;
1975}
1976
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001977Error HWC2On1Adapter::Layer::setSourceCrop(hwc_frect_t crop) {
1978 mSourceCrop = crop;
1979 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001980 return Error::None;
1981}
1982
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001983Error HWC2On1Adapter::Layer::setTransform(Transform transform) {
1984 mTransform = transform;
1985 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001986 return Error::None;
1987}
1988
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001989Error HWC2On1Adapter::Layer::setVisibleRegion(hwc_region_t visible) {
1990 mVisibleRegion.resize(visible.numRects);
1991 std::copy_n(visible.rects, visible.numRects, mVisibleRegion.begin());
1992 mDisplay.markGeometryChanged();
Dan Stozac6998d22015-09-24 17:03:36 -07001993 return Error::None;
1994}
1995
Fabien Sanglard06e908a2017-02-12 00:08:14 -08001996Error HWC2On1Adapter::Layer::setZ(uint32_t z) {
Dan Stozac6998d22015-09-24 17:03:36 -07001997 mZ = z;
1998 return Error::None;
1999}
2000
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002001void HWC2On1Adapter::Layer::addReleaseFence(int fenceFd) {
Dan Stozac6998d22015-09-24 17:03:36 -07002002 ALOGV("addReleaseFence %d to layer %" PRIu64, fenceFd, mId);
2003 mReleaseFence.add(fenceFd);
2004}
2005
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002006const sp<Fence>& HWC2On1Adapter::Layer::getReleaseFence() const {
Dan Stozac6998d22015-09-24 17:03:36 -07002007 return mReleaseFence.get();
2008}
2009
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002010void HWC2On1Adapter::Layer::applyState(hwc_layer_1_t& hwc1Layer) {
2011 applyCommonState(hwc1Layer);
2012 applyCompositionType(hwc1Layer);
2013 switch (mCompositionType) {
2014 case Composition::SolidColor : applySolidColorState(hwc1Layer); break;
2015 case Composition::Sideband : applySidebandState(hwc1Layer); break;
2016 default: applyBufferState(hwc1Layer); break;
Dan Stozac6998d22015-09-24 17:03:36 -07002017 }
Dan Stozac6998d22015-09-24 17:03:36 -07002018}
2019
Dan Stozac6998d22015-09-24 17:03:36 -07002020static std::string regionStrings(const std::vector<hwc_rect_t>& visibleRegion,
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002021 const std::vector<hwc_rect_t>& surfaceDamage) {
Dan Stozac6998d22015-09-24 17:03:36 -07002022 std::string regions;
2023 regions += " Visible Region";
2024 regions.resize(40, ' ');
2025 regions += "Surface Damage\n";
2026
2027 size_t numPrinted = 0;
2028 size_t maxSize = std::max(visibleRegion.size(), surfaceDamage.size());
2029 while (numPrinted < maxSize) {
2030 std::string line(" ");
2031 if (visibleRegion.empty() && numPrinted == 0) {
2032 line += "None";
2033 } else if (numPrinted < visibleRegion.size()) {
2034 line += rectString(visibleRegion[numPrinted]);
2035 }
2036 line.resize(40, ' ');
2037 if (surfaceDamage.empty() && numPrinted == 0) {
2038 line += "None";
2039 } else if (numPrinted < surfaceDamage.size()) {
2040 line += rectString(surfaceDamage[numPrinted]);
2041 }
2042 line += '\n';
2043 regions += line;
2044 ++numPrinted;
2045 }
2046 return regions;
2047}
2048
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002049std::string HWC2On1Adapter::Layer::dump() const {
Dan Stozac6998d22015-09-24 17:03:36 -07002050 std::stringstream output;
2051 const char* fill = " ";
2052
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002053 output << fill << to_string(mCompositionType);
Dan Stozac6998d22015-09-24 17:03:36 -07002054 output << " Layer HWC2/1: " << mId << "/" << mHwc1Id << " ";
2055 output << "Z: " << mZ;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002056 if (mCompositionType == HWC2::Composition::SolidColor) {
2057 output << " " << colorString(mColor);
2058 } else if (mCompositionType == HWC2::Composition::Sideband) {
2059 output << " Handle: " << mSidebandStream << '\n';
Dan Stozac6998d22015-09-24 17:03:36 -07002060 } else {
2061 output << " Buffer: " << mBuffer.getBuffer() << "/" <<
2062 mBuffer.getFence() << '\n';
2063 output << fill << " Display frame [LTRB]: " <<
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002064 rectString(mDisplayFrame) << '\n';
Dan Stozac6998d22015-09-24 17:03:36 -07002065 output << fill << " Source crop: " <<
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002066 frectString(mSourceCrop) << '\n';
2067 output << fill << " Transform: " << to_string(mTransform);
2068 output << " Blend mode: " << to_string(mBlendMode);
2069 if (mPlaneAlpha != 1.0f) {
Dan Stozac6998d22015-09-24 17:03:36 -07002070 output << " Alpha: " <<
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002071 alphaString(mPlaneAlpha) << '\n';
Dan Stozac6998d22015-09-24 17:03:36 -07002072 } else {
2073 output << '\n';
2074 }
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002075 output << regionStrings(mVisibleRegion, mSurfaceDamage);
Dan Stozac6998d22015-09-24 17:03:36 -07002076 }
2077 return output.str();
2078}
2079
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002080static int getHwc1Blending(HWC2::BlendMode blendMode) {
Dan Stozac6998d22015-09-24 17:03:36 -07002081 switch (blendMode) {
2082 case BlendMode::Coverage: return HWC_BLENDING_COVERAGE;
2083 case BlendMode::Premultiplied: return HWC_BLENDING_PREMULT;
2084 default: return HWC_BLENDING_NONE;
2085 }
2086}
2087
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002088void HWC2On1Adapter::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer) {
Dan Stozac6998d22015-09-24 17:03:36 -07002089 auto minorVersion = mDisplay.getDevice().getHwc1MinorVersion();
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002090 hwc1Layer.blending = getHwc1Blending(mBlendMode);
2091 hwc1Layer.displayFrame = mDisplayFrame;
Dan Stozac6998d22015-09-24 17:03:36 -07002092
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002093 auto pendingAlpha = mPlaneAlpha;
2094 if (minorVersion < 2) {
2095 mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f;
2096 } else {
2097 hwc1Layer.planeAlpha =
2098 static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f);
2099 }
Dan Stozac6998d22015-09-24 17:03:36 -07002100
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002101 if (minorVersion < 3) {
2102 auto pending = mSourceCrop;
2103 hwc1Layer.sourceCropi.left =
2104 static_cast<int32_t>(std::ceil(pending.left));
2105 hwc1Layer.sourceCropi.top =
2106 static_cast<int32_t>(std::ceil(pending.top));
2107 hwc1Layer.sourceCropi.right =
2108 static_cast<int32_t>(std::floor(pending.right));
2109 hwc1Layer.sourceCropi.bottom =
2110 static_cast<int32_t>(std::floor(pending.bottom));
2111 } else {
2112 hwc1Layer.sourceCropf = mSourceCrop;
2113 }
2114
2115 hwc1Layer.transform = static_cast<uint32_t>(mTransform);
2116
2117 auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen;
2118 hwc1VisibleRegion.numRects = mVisibleRegion.size();
2119 hwc_rect_t* rects = mDisplay.GetRects(hwc1VisibleRegion.numRects);
2120 hwc1VisibleRegion.rects = rects;
2121 for (size_t i = 0; i < mVisibleRegion.size(); i++) {
2122 rects[i] = mVisibleRegion[i];
Dan Stozac6998d22015-09-24 17:03:36 -07002123 }
2124}
2125
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002126void HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer) {
2127 // If the device does not support background color it is likely to make
2128 // assumption regarding backgroundColor and handle (both fields occupy
2129 // the same location in hwc_layer_1_t union).
2130 // To not confuse these devices we don't set background color and we
2131 // make sure handle is a null pointer.
2132 if (hasUnsupportedBackgroundColor()) {
2133 hwc1Layer.handle = nullptr;
2134 } else {
2135 hwc1Layer.backgroundColor = mColor;
Dan Stozac6998d22015-09-24 17:03:36 -07002136 }
2137}
2138
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002139void HWC2On1Adapter::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer) {
2140 hwc1Layer.sidebandStream = mSidebandStream;
Dan Stozac6998d22015-09-24 17:03:36 -07002141}
2142
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002143void HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer) {
Dan Stozac6998d22015-09-24 17:03:36 -07002144 hwc1Layer.handle = mBuffer.getBuffer();
2145 hwc1Layer.acquireFenceFd = mBuffer.getFence();
2146}
2147
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002148void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer) {
Dan Stoza5df2a862016-03-24 16:19:37 -07002149 // HWC1 never supports color transforms or dataspaces and only sometimes
2150 // supports plane alpha (depending on the version). These require us to drop
2151 // some or all layers to client composition.
Fabien Sanglard999a7fd2017-02-02 16:59:44 -08002152 if (mHasUnsupportedPlaneAlpha || mDisplay.hasColorTransform() ||
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002153 hasUnsupportedBackgroundColor()) {
Dan Stozac6998d22015-09-24 17:03:36 -07002154 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2155 hwc1Layer.flags = HWC_SKIP_LAYER;
2156 return;
2157 }
2158
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002159 hwc1Layer.flags = 0;
2160 switch (mCompositionType) {
2161 case Composition::Client:
2162 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2163 hwc1Layer.flags |= HWC_SKIP_LAYER;
2164 break;
2165 case Composition::Device:
2166 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2167 break;
2168 case Composition::SolidColor:
2169 // In theory the following line should work, but since the HWC1
2170 // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
2171 // devices may not work correctly. To be on the safe side, we
2172 // fall back to client composition.
2173 //
2174 // hwc1Layer.compositionType = HWC_BACKGROUND;
2175 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2176 hwc1Layer.flags |= HWC_SKIP_LAYER;
2177 break;
2178 case Composition::Cursor:
2179 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2180 if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
2181 hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
2182 }
2183 break;
2184 case Composition::Sideband:
2185 if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
2186 hwc1Layer.compositionType = HWC_SIDEBAND;
2187 } else {
Dan Stozac6998d22015-09-24 17:03:36 -07002188 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2189 hwc1Layer.flags |= HWC_SKIP_LAYER;
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002190 }
2191 break;
2192 default:
2193 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2194 hwc1Layer.flags |= HWC_SKIP_LAYER;
2195 break;
Dan Stozac6998d22015-09-24 17:03:36 -07002196 }
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002197 ALOGV("Layer %" PRIu64 " %s set to %d", mId,
2198 to_string(mCompositionType).c_str(),
2199 hwc1Layer.compositionType);
2200 ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, " and skipping");
Dan Stozac6998d22015-09-24 17:03:36 -07002201}
2202
2203// Adapter helpers
2204
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002205void HWC2On1Adapter::populateCapabilities() {
Dan Stozac6998d22015-09-24 17:03:36 -07002206 if (mHwc1MinorVersion >= 3U) {
2207 int supportedTypes = 0;
2208 auto result = mHwc1Device->query(mHwc1Device,
2209 HWC_DISPLAY_TYPES_SUPPORTED, &supportedTypes);
Fred Fettingerc50c01e2016-06-14 17:53:10 -05002210 if ((result == 0) && ((supportedTypes & HWC_DISPLAY_VIRTUAL_BIT) != 0)) {
Dan Stozac6998d22015-09-24 17:03:36 -07002211 ALOGI("Found support for HWC virtual displays");
2212 mHwc1SupportsVirtualDisplays = true;
2213 }
2214 }
2215 if (mHwc1MinorVersion >= 4U) {
2216 mCapabilities.insert(Capability::SidebandStream);
2217 }
Fabien Sanglardeb3db612016-11-18 16:12:31 -08002218
2219 // Check for HWC background color layer support.
2220 if (mHwc1MinorVersion >= 1U) {
2221 int backgroundColorSupported = 0;
2222 auto result = mHwc1Device->query(mHwc1Device,
2223 HWC_BACKGROUND_LAYER_SUPPORTED,
2224 &backgroundColorSupported);
2225 if ((result == 0) && (backgroundColorSupported == 1)) {
2226 ALOGV("Found support for HWC background color");
2227 mHwc1SupportsBackgroundColor = true;
2228 }
2229 }
Dan Stozac6998d22015-09-24 17:03:36 -07002230}
2231
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002232HWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id) {
Dan Stozafc4e2022016-02-23 11:43:19 -08002233 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002234
2235 auto display = mDisplays.find(id);
2236 if (display == mDisplays.end()) {
2237 return nullptr;
2238 }
2239
2240 return display->second.get();
2241}
2242
2243std::tuple<HWC2On1Adapter::Layer*, Error> HWC2On1Adapter::getLayer(
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002244 hwc2_display_t displayId, hwc2_layer_t layerId) {
Dan Stozac6998d22015-09-24 17:03:36 -07002245 auto display = getDisplay(displayId);
2246 if (!display) {
2247 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
2248 }
2249
2250 auto layerEntry = mLayers.find(layerId);
2251 if (layerEntry == mLayers.end()) {
2252 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2253 }
2254
2255 auto layer = layerEntry->second;
2256 if (layer->getDisplay().getId() != displayId) {
2257 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2258 }
2259 return std::make_tuple(layer.get(), Error::None);
2260}
2261
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002262void HWC2On1Adapter::populatePrimary() {
Dan Stozafc4e2022016-02-23 11:43:19 -08002263 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002264
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002265 auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
Dan Stozac6998d22015-09-24 17:03:36 -07002266 mHwc1DisplayMap[HWC_DISPLAY_PRIMARY] = display->getId();
2267 display->setHwc1Id(HWC_DISPLAY_PRIMARY);
2268 display->populateConfigs();
2269 mDisplays.emplace(display->getId(), std::move(display));
2270}
2271
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002272bool HWC2On1Adapter::prepareAllDisplays() {
Dan Stozac6998d22015-09-24 17:03:36 -07002273 ATRACE_CALL();
2274
Dan Stozafc4e2022016-02-23 11:43:19 -08002275 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002276
2277 for (const auto& displayPair : mDisplays) {
2278 auto& display = displayPair.second;
2279 if (!display->prepare()) {
2280 return false;
2281 }
2282 }
2283
Fabien Sanglard7382ed72017-02-11 22:47:36 -08002284 if (mHwc1DisplayMap.count(HWC_DISPLAY_PRIMARY) == 0) {
Dan Stozac6998d22015-09-24 17:03:36 -07002285 ALOGE("prepareAllDisplays: Unable to find primary HWC1 display");
2286 return false;
2287 }
2288
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002289 // Build an array of hwc_display_contents_1 to call prepare() on HWC1.
2290 mHwc1Contents.clear();
2291
Dan Stozac6998d22015-09-24 17:03:36 -07002292 // Always push the primary display
Dan Stozac6998d22015-09-24 17:03:36 -07002293 auto primaryDisplayId = mHwc1DisplayMap[HWC_DISPLAY_PRIMARY];
2294 auto& primaryDisplay = mDisplays[primaryDisplayId];
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002295 mHwc1Contents.push_back(primaryDisplay->getDisplayContents());
Dan Stozac6998d22015-09-24 17:03:36 -07002296
2297 // Push the external display, if present
2298 if (mHwc1DisplayMap.count(HWC_DISPLAY_EXTERNAL) != 0) {
2299 auto externalDisplayId = mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL];
2300 auto& externalDisplay = mDisplays[externalDisplayId];
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002301 mHwc1Contents.push_back(externalDisplay->getDisplayContents());
Dan Stozac6998d22015-09-24 17:03:36 -07002302 } else {
2303 // Even if an external display isn't present, we still need to send
2304 // at least two displays down to HWC1
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002305 mHwc1Contents.push_back(nullptr);
Dan Stozac6998d22015-09-24 17:03:36 -07002306 }
2307
2308 // Push the hardware virtual display, if supported and present
2309 if (mHwc1MinorVersion >= 3) {
2310 if (mHwc1DisplayMap.count(HWC_DISPLAY_VIRTUAL) != 0) {
2311 auto virtualDisplayId = mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL];
2312 auto& virtualDisplay = mDisplays[virtualDisplayId];
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002313 mHwc1Contents.push_back(virtualDisplay->getDisplayContents());
Dan Stozac6998d22015-09-24 17:03:36 -07002314 } else {
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002315 mHwc1Contents.push_back(nullptr);
Dan Stozac6998d22015-09-24 17:03:36 -07002316 }
2317 }
2318
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002319 for (auto& displayContents : mHwc1Contents) {
Dan Stozac6998d22015-09-24 17:03:36 -07002320 if (!displayContents) {
2321 continue;
2322 }
2323
2324 ALOGV("Display %zd layers:", mHwc1Contents.size() - 1);
2325 for (size_t l = 0; l < displayContents->numHwLayers; ++l) {
2326 auto& layer = displayContents->hwLayers[l];
2327 ALOGV(" %zd: %d", l, layer.compositionType);
2328 }
2329 }
2330
2331 ALOGV("Calling HWC1 prepare");
2332 {
2333 ATRACE_NAME("HWC1 prepare");
2334 mHwc1Device->prepare(mHwc1Device, mHwc1Contents.size(),
2335 mHwc1Contents.data());
2336 }
2337
2338 for (size_t c = 0; c < mHwc1Contents.size(); ++c) {
2339 auto& contents = mHwc1Contents[c];
2340 if (!contents) {
2341 continue;
2342 }
2343 ALOGV("Display %zd layers:", c);
2344 for (size_t l = 0; l < contents->numHwLayers; ++l) {
2345 ALOGV(" %zd: %d", l, contents->hwLayers[l].compositionType);
2346 }
2347 }
2348
2349 // Return the received contents to their respective displays
2350 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2351 if (mHwc1Contents[hwc1Id] == nullptr) {
2352 continue;
2353 }
2354
2355 auto displayId = mHwc1DisplayMap[hwc1Id];
2356 auto& display = mDisplays[displayId];
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002357 display->generateChanges();
Dan Stozac6998d22015-09-24 17:03:36 -07002358 }
2359
2360 return true;
2361}
2362
Fabien Sanglardaf5b6b82017-02-23 11:17:11 -08002363void dumpHWC1Message(hwc_composer_device_1* device, size_t numDisplays,
2364 hwc_display_contents_1_t** displays) {
2365 ALOGV("*****************************");
2366 size_t displayId = 0;
2367 while (displayId < numDisplays) {
2368 hwc_display_contents_1_t* display = displays[displayId];
2369
2370 ALOGV("hwc_display_contents_1_t[%zu] @0x%p", displayId, display);
2371 if (display == nullptr) {
2372 displayId++;
2373 continue;
2374 }
2375 ALOGV(" retirefd:0x%08x", display->retireFenceFd);
2376 ALOGV(" outbuf :0x%p", display->outbuf);
2377 ALOGV(" outbuffd:0x%08x", display->outbufAcquireFenceFd);
2378 ALOGV(" flags :0x%08x", display->flags);
2379 for(size_t layerId=0 ; layerId < display->numHwLayers ; layerId++) {
2380 hwc_layer_1_t& layer = display->hwLayers[layerId];
2381 ALOGV(" Layer[%zu]:", layerId);
2382 ALOGV(" composition : 0x%08x", layer.compositionType);
2383 ALOGV(" hints : 0x%08x", layer.hints);
2384 ALOGV(" flags : 0x%08x", layer.flags);
2385 ALOGV(" handle : 0x%p", layer.handle);
2386 ALOGV(" transform : 0x%08x", layer.transform);
2387 ALOGV(" blending : 0x%08x", layer.blending);
2388 ALOGV(" sourceCropf : %f, %f, %f, %f",
2389 layer.sourceCropf.left,
2390 layer.sourceCropf.top,
2391 layer.sourceCropf.right,
2392 layer.sourceCropf.bottom);
2393 ALOGV(" displayFrame : %d, %d, %d, %d",
2394 layer.displayFrame.left,
2395 layer.displayFrame.left,
2396 layer.displayFrame.left,
2397 layer.displayFrame.left);
2398 hwc_region_t& visReg = layer.visibleRegionScreen;
2399 ALOGV(" visibleRegionScreen: #0x%08zx[@0x%p]",
2400 visReg.numRects,
2401 visReg.rects);
2402 for (size_t visRegId=0; visRegId < visReg.numRects ; visRegId++) {
2403 if (layer.visibleRegionScreen.rects == nullptr) {
2404 ALOGV(" null");
2405 } else {
2406 ALOGV(" visibleRegionScreen[%zu] %d, %d, %d, %d",
2407 visRegId,
2408 visReg.rects[visRegId].left,
2409 visReg.rects[visRegId].top,
2410 visReg.rects[visRegId].right,
2411 visReg.rects[visRegId].bottom);
2412 }
2413 }
2414 ALOGV(" acquireFenceFd : 0x%08x", layer.acquireFenceFd);
2415 ALOGV(" releaseFenceFd : 0x%08x", layer.releaseFenceFd);
2416 ALOGV(" planeAlpha : 0x%08x", layer.planeAlpha);
2417 if (getMinorVersion(device) < 5)
2418 continue;
2419 ALOGV(" surfaceDamage : #0x%08zx[@0x%p]",
2420 layer.surfaceDamage.numRects,
2421 layer.surfaceDamage.rects);
2422 for (size_t sdId=0; sdId < layer.surfaceDamage.numRects ; sdId++) {
2423 if (layer.surfaceDamage.rects == nullptr) {
2424 ALOGV(" null");
2425 } else {
2426 ALOGV(" surfaceDamage[%zu] %d, %d, %d, %d",
2427 sdId,
2428 layer.surfaceDamage.rects[sdId].left,
2429 layer.surfaceDamage.rects[sdId].top,
2430 layer.surfaceDamage.rects[sdId].right,
2431 layer.surfaceDamage.rects[sdId].bottom);
2432 }
2433 }
2434 }
2435 displayId++;
2436 }
2437 ALOGV("-----------------------------");
2438}
2439
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002440Error HWC2On1Adapter::setAllDisplays() {
Dan Stozac6998d22015-09-24 17:03:36 -07002441 ATRACE_CALL();
2442
Dan Stozafc4e2022016-02-23 11:43:19 -08002443 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002444
2445 // Make sure we're ready to validate
2446 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2447 if (mHwc1Contents[hwc1Id] == nullptr) {
2448 continue;
2449 }
2450
2451 auto displayId = mHwc1DisplayMap[hwc1Id];
2452 auto& display = mDisplays[displayId];
2453 Error error = display->set(*mHwc1Contents[hwc1Id]);
2454 if (error != Error::None) {
2455 ALOGE("setAllDisplays: Failed to set display %zd: %s", hwc1Id,
2456 to_string(error).c_str());
2457 return error;
2458 }
2459 }
2460
2461 ALOGV("Calling HWC1 set");
2462 {
2463 ATRACE_NAME("HWC1 set");
Fabien Sanglardaf5b6b82017-02-23 11:17:11 -08002464 //dumpHWC1Message(mHwc1Device, mHwc1Contents.size(), mHwc1Contents.data());
Dan Stozac6998d22015-09-24 17:03:36 -07002465 mHwc1Device->set(mHwc1Device, mHwc1Contents.size(),
2466 mHwc1Contents.data());
2467 }
2468
2469 // Add retire and release fences
2470 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2471 if (mHwc1Contents[hwc1Id] == nullptr) {
2472 continue;
2473 }
2474
2475 auto displayId = mHwc1DisplayMap[hwc1Id];
2476 auto& display = mDisplays[displayId];
2477 auto retireFenceFd = mHwc1Contents[hwc1Id]->retireFenceFd;
2478 ALOGV("setAllDisplays: Adding retire fence %d to display %zd",
2479 retireFenceFd, hwc1Id);
2480 display->addRetireFence(mHwc1Contents[hwc1Id]->retireFenceFd);
2481 display->addReleaseFences(*mHwc1Contents[hwc1Id]);
2482 }
2483
2484 return Error::None;
2485}
2486
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002487void HWC2On1Adapter::hwc1Invalidate() {
Dan Stozac6998d22015-09-24 17:03:36 -07002488 ALOGV("Received hwc1Invalidate");
2489
Dan Stozafc4e2022016-02-23 11:43:19 -08002490 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002491
2492 // If the HWC2-side callback hasn't been registered yet, buffer this until
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002493 // it is registered.
Dan Stozac6998d22015-09-24 17:03:36 -07002494 if (mCallbacks.count(Callback::Refresh) == 0) {
2495 mHasPendingInvalidate = true;
2496 return;
2497 }
2498
2499 const auto& callbackInfo = mCallbacks[Callback::Refresh];
2500 std::vector<hwc2_display_t> displays;
2501 for (const auto& displayPair : mDisplays) {
2502 displays.emplace_back(displayPair.first);
2503 }
2504
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002505 // Call back without the state lock held.
Dan Stozac6998d22015-09-24 17:03:36 -07002506 lock.unlock();
2507
2508 auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(callbackInfo.pointer);
2509 for (auto display : displays) {
2510 refresh(callbackInfo.data, display);
2511 }
2512}
2513
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002514void HWC2On1Adapter::hwc1Vsync(int hwc1DisplayId, int64_t timestamp) {
Dan Stozac6998d22015-09-24 17:03:36 -07002515 ALOGV("Received hwc1Vsync(%d, %" PRId64 ")", hwc1DisplayId, timestamp);
2516
Dan Stozafc4e2022016-02-23 11:43:19 -08002517 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002518
2519 // If the HWC2-side callback hasn't been registered yet, buffer this until
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002520 // it is registered.
Dan Stozac6998d22015-09-24 17:03:36 -07002521 if (mCallbacks.count(Callback::Vsync) == 0) {
2522 mPendingVsyncs.emplace_back(hwc1DisplayId, timestamp);
2523 return;
2524 }
2525
2526 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2527 ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", hwc1DisplayId);
2528 return;
2529 }
2530
2531 const auto& callbackInfo = mCallbacks[Callback::Vsync];
2532 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
2533
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002534 // Call back without the state lock held.
Dan Stozac6998d22015-09-24 17:03:36 -07002535 lock.unlock();
2536
2537 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
2538 vsync(callbackInfo.data, displayId, timestamp);
2539}
2540
Fabien Sanglard06e908a2017-02-12 00:08:14 -08002541void HWC2On1Adapter::hwc1Hotplug(int hwc1DisplayId, int connected) {
Dan Stozac6998d22015-09-24 17:03:36 -07002542 ALOGV("Received hwc1Hotplug(%d, %d)", hwc1DisplayId, connected);
2543
2544 if (hwc1DisplayId != HWC_DISPLAY_EXTERNAL) {
2545 ALOGE("hwc1Hotplug: Received hotplug for non-external display");
2546 return;
2547 }
2548
Dan Stozafc4e2022016-02-23 11:43:19 -08002549 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
Dan Stozac6998d22015-09-24 17:03:36 -07002550
2551 // If the HWC2-side callback hasn't been registered yet, buffer this until
2552 // it is registered
2553 if (mCallbacks.count(Callback::Hotplug) == 0) {
2554 mPendingHotplugs.emplace_back(hwc1DisplayId, connected);
2555 return;
2556 }
2557
2558 hwc2_display_t displayId = UINT64_MAX;
2559 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2560 if (connected == 0) {
2561 ALOGW("hwc1Hotplug: Received disconnect for unconnected display");
2562 return;
2563 }
2564
2565 // Create a new display on connect
2566 auto display = std::make_shared<HWC2On1Adapter::Display>(*this,
2567 HWC2::DisplayType::Physical);
2568 display->setHwc1Id(HWC_DISPLAY_EXTERNAL);
2569 display->populateConfigs();
2570 displayId = display->getId();
2571 mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL] = displayId;
2572 mDisplays.emplace(displayId, std::move(display));
2573 } else {
2574 if (connected != 0) {
2575 ALOGW("hwc1Hotplug: Received connect for previously connected "
2576 "display");
2577 return;
2578 }
2579
2580 // Disconnect an existing display
2581 displayId = mHwc1DisplayMap[hwc1DisplayId];
2582 mHwc1DisplayMap.erase(HWC_DISPLAY_EXTERNAL);
2583 mDisplays.erase(displayId);
2584 }
2585
2586 const auto& callbackInfo = mCallbacks[Callback::Hotplug];
2587
2588 // Call back without the state lock held
2589 lock.unlock();
2590
2591 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(callbackInfo.pointer);
2592 auto hwc2Connected = (connected == 0) ?
2593 HWC2::Connection::Disconnected : HWC2::Connection::Connected;
2594 hotplug(callbackInfo.data, displayId, static_cast<int32_t>(hwc2Connected));
2595}
Dan Stozac6998d22015-09-24 17:03:36 -07002596} // namespace android