1 /*
2 * Copyright 2017 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 #include "HWC2.h"
18
19 //#define LOG_NDEBUG 0
20
21 #undef LOG_TAG
22 #define LOG_TAG "CfHWC2"
23 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
24
25 #include <inttypes.h>
26
27 #include <chrono>
28 #include <cstdlib>
29 #include <sstream>
30
31 #include <hardware/hwcomposer.h>
32 #include <log/log.h>
33 #include <utils/Trace.h>
34
35 #include "guest/hals/hwcomposer/common/hwcomposer.h"
36 #include "guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.h"
37
38 using namespace std::chrono_literals;
39
getMinorVersion(struct hwc_composer_device_1 * device)40 static uint8_t getMinorVersion(struct hwc_composer_device_1* device)
41 {
42 auto version = device->common.version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
43 return (version >> 16) & 0xF;
44 }
45
46 template <typename PFN, typename T>
asFP(T function)47 static hwc2_function_pointer_t asFP(T function)
48 {
49 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
50 return reinterpret_cast<hwc2_function_pointer_t>(function);
51 }
52
53 using namespace HWC2;
54
55 static constexpr Attribute ColorMode = static_cast<Attribute>(6);
56
57 namespace android {
58
59 class CfHWC2::Callbacks : public hwc_procs_t {
60 public:
Callbacks(CfHWC2 & adapter)61 explicit Callbacks(CfHWC2& adapter) : mAdapter(adapter) {
62 invalidate = &invalidateHook;
63 vsync = &vsyncHook;
64 hotplug = &hotplugHook;
65 }
66
invalidateHook(const hwc_procs_t * procs)67 static void invalidateHook(const hwc_procs_t* procs) {
68 auto callbacks = static_cast<const Callbacks*>(procs);
69 callbacks->mAdapter.hwc1Invalidate();
70 }
71
vsyncHook(const hwc_procs_t * procs,int display,int64_t timestamp)72 static void vsyncHook(const hwc_procs_t* procs, int display,
73 int64_t timestamp) {
74 auto callbacks = static_cast<const Callbacks*>(procs);
75 callbacks->mAdapter.hwc1Vsync(display, timestamp);
76 }
77
hotplugHook(const hwc_procs_t * procs,int display,int connected)78 static void hotplugHook(const hwc_procs_t* procs, int display,
79 int connected) {
80 auto callbacks = static_cast<const Callbacks*>(procs);
81 callbacks->mAdapter.hwc1Hotplug(display, connected);
82 }
83
84 private:
85 CfHWC2& mAdapter;
86 };
87
closeHook(hw_device_t *)88 static int closeHook(hw_device_t* /*device*/)
89 {
90 // Do nothing, since the real work is done in the class destructor, but we
91 // need to provide a valid function pointer for hwc2_close to call
92 return 0;
93 }
94
CfHWC2(hwc_composer_device_1_t * hwc1Device)95 CfHWC2::CfHWC2(hwc_composer_device_1_t* hwc1Device)
96 : mDumpString(),
97 mHwc1Device(hwc1Device),
98 mHwc1MinorVersion(getMinorVersion(hwc1Device)),
99 mHwc1SupportsVirtualDisplays(false),
100 mHwc1SupportsBackgroundColor(false),
101 mHwc1Callbacks(std::make_unique<Callbacks>(*this)),
102 mCapabilities(),
103 mLayers(),
104 mHwc1VirtualDisplay(),
105 mStateMutex(),
106 mCallbacks(),
107 mHasPendingInvalidate(false),
108 mPendingVsyncs(),
109 mPendingHotplugs(),
110 mDisplays(),
111 mHwc1DisplayMap()
112 {
113 common.tag = HARDWARE_DEVICE_TAG;
114 common.version = HWC_DEVICE_API_VERSION_2_0;
115 common.close = closeHook;
116 getCapabilities = getCapabilitiesHook;
117 getFunction = getFunctionHook;
118 populateCapabilities();
119 populatePrimary();
120 mHwc1Device->registerProcs(mHwc1Device,
121 static_cast<const hwc_procs_t*>(mHwc1Callbacks.get()));
122 }
123
~CfHWC2()124 CfHWC2::~CfHWC2() {
125 hwc_close_1(mHwc1Device);
126 }
127
doGetCapabilities(uint32_t * outCount,int32_t * outCapabilities)128 void CfHWC2::doGetCapabilities(uint32_t* outCount,
129 int32_t* outCapabilities) {
130 if (outCapabilities == nullptr) {
131 *outCount = mCapabilities.size();
132 return;
133 }
134
135 auto capabilityIter = mCapabilities.cbegin();
136 for (size_t written = 0; written < *outCount; ++written) {
137 if (capabilityIter == mCapabilities.cend()) {
138 return;
139 }
140 outCapabilities[written] = static_cast<int32_t>(*capabilityIter);
141 ++capabilityIter;
142 }
143 }
144
doGetFunction(FunctionDescriptor descriptor)145 hwc2_function_pointer_t CfHWC2::doGetFunction(
146 FunctionDescriptor descriptor) {
147 switch (descriptor) {
148 // Device functions
149 case FunctionDescriptor::CreateVirtualDisplay:
150 return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
151 createVirtualDisplayHook);
152 case FunctionDescriptor::DestroyVirtualDisplay:
153 return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
154 destroyVirtualDisplayHook);
155 case FunctionDescriptor::Dump:
156 return asFP<HWC2_PFN_DUMP>(dumpHook);
157 case FunctionDescriptor::GetMaxVirtualDisplayCount:
158 return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
159 getMaxVirtualDisplayCountHook);
160 case FunctionDescriptor::RegisterCallback:
161 return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
162
163 // Display functions
164 case FunctionDescriptor::AcceptDisplayChanges:
165 return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
166 displayHook<decltype(&Display::acceptChanges),
167 &Display::acceptChanges>);
168 case FunctionDescriptor::CreateLayer:
169 return asFP<HWC2_PFN_CREATE_LAYER>(
170 displayHook<decltype(&Display::createLayer),
171 &Display::createLayer, hwc2_layer_t*>);
172 case FunctionDescriptor::DestroyLayer:
173 return asFP<HWC2_PFN_DESTROY_LAYER>(
174 displayHook<decltype(&Display::destroyLayer),
175 &Display::destroyLayer, hwc2_layer_t>);
176 case FunctionDescriptor::GetActiveConfig:
177 return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
178 displayHook<decltype(&Display::getActiveConfig),
179 &Display::getActiveConfig, hwc2_config_t*>);
180 case FunctionDescriptor::GetChangedCompositionTypes:
181 return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
182 displayHook<decltype(&Display::getChangedCompositionTypes),
183 &Display::getChangedCompositionTypes, uint32_t*,
184 hwc2_layer_t*, int32_t*>);
185 case FunctionDescriptor::GetColorModes:
186 return asFP<HWC2_PFN_GET_COLOR_MODES>(
187 displayHook<decltype(&Display::getColorModes),
188 &Display::getColorModes, uint32_t*, int32_t*>);
189 case FunctionDescriptor::GetDisplayAttribute:
190 return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
191 getDisplayAttributeHook);
192 case FunctionDescriptor::GetDisplayConfigs:
193 return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
194 displayHook<decltype(&Display::getConfigs),
195 &Display::getConfigs, uint32_t*, hwc2_config_t*>);
196 case FunctionDescriptor::GetDisplayName:
197 return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
198 displayHook<decltype(&Display::getName),
199 &Display::getName, uint32_t*, char*>);
200 case FunctionDescriptor::GetDisplayRequests:
201 return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
202 displayHook<decltype(&Display::getRequests),
203 &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*,
204 int32_t*>);
205 case FunctionDescriptor::GetDisplayType:
206 return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
207 displayHook<decltype(&Display::getType),
208 &Display::getType, int32_t*>);
209 case FunctionDescriptor::GetDozeSupport:
210 return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
211 displayHook<decltype(&Display::getDozeSupport),
212 &Display::getDozeSupport, int32_t*>);
213 case FunctionDescriptor::GetHdrCapabilities:
214 return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
215 displayHook<decltype(&Display::getHdrCapabilities),
216 &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
217 float*, float*>);
218 case FunctionDescriptor::GetReleaseFences:
219 return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
220 displayHook<decltype(&Display::getReleaseFences),
221 &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
222 int32_t*>);
223 case FunctionDescriptor::PresentDisplay:
224 return asFP<HWC2_PFN_PRESENT_DISPLAY>(
225 displayHook<decltype(&Display::present),
226 &Display::present, int32_t*>);
227 case FunctionDescriptor::SetActiveConfig:
228 return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
229 displayHook<decltype(&Display::setActiveConfig),
230 &Display::setActiveConfig, hwc2_config_t>);
231 case FunctionDescriptor::SetClientTarget:
232 return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
233 displayHook<decltype(&Display::setClientTarget),
234 &Display::setClientTarget, buffer_handle_t, int32_t,
235 int32_t, hwc_region_t>);
236 case FunctionDescriptor::SetColorMode:
237 return asFP<HWC2_PFN_SET_COLOR_MODE>(setColorModeHook);
238 case FunctionDescriptor::SetColorTransform:
239 return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
240 case FunctionDescriptor::SetOutputBuffer:
241 return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
242 displayHook<decltype(&Display::setOutputBuffer),
243 &Display::setOutputBuffer, buffer_handle_t, int32_t>);
244 case FunctionDescriptor::SetPowerMode:
245 return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
246 case FunctionDescriptor::SetVsyncEnabled:
247 return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook);
248 case FunctionDescriptor::ValidateDisplay:
249 return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
250 displayHook<decltype(&Display::validate),
251 &Display::validate, uint32_t*, uint32_t*>);
252 case FunctionDescriptor::GetClientTargetSupport:
253 return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
254 displayHook<decltype(&Display::getClientTargetSupport),
255 &Display::getClientTargetSupport, uint32_t, uint32_t,
256 int32_t, int32_t>);
257
258 // 2.3 required functions
259 case FunctionDescriptor::GetDisplayIdentificationData:
260 return asFP<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
261 displayHook<decltype(&Display::getDisplayIdentificationData),
262 &Display::getDisplayIdentificationData, uint8_t*, uint32_t*, uint8_t*>);
263 case FunctionDescriptor::GetDisplayCapabilities:
264 return asFP<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
265 displayHook<decltype(&Display::getDisplayCapabilities),
266 &Display::getDisplayCapabilities, uint32_t*, uint32_t*>);
267 case FunctionDescriptor::GetDisplayBrightnessSupport:
268 return asFP<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
269 displayHook<decltype(&Display::getDisplayBrightnessSupport),
270 &Display::getDisplayBrightnessSupport, bool*>);
271 case FunctionDescriptor::SetDisplayBrightness:
272 return asFP<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
273 displayHook<decltype(&Display::setDisplayBrightness),
274 &Display::setDisplayBrightness, float>);
275
276 // Layer functions
277 case FunctionDescriptor::SetCursorPosition:
278 return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
279 layerHook<decltype(&Layer::setCursorPosition),
280 &Layer::setCursorPosition, int32_t, int32_t>);
281 case FunctionDescriptor::SetLayerBuffer:
282 return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
283 layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
284 buffer_handle_t, int32_t>);
285 case FunctionDescriptor::SetLayerSurfaceDamage:
286 return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
287 layerHook<decltype(&Layer::setSurfaceDamage),
288 &Layer::setSurfaceDamage, hwc_region_t>);
289
290 // Layer state functions
291 case FunctionDescriptor::SetLayerBlendMode:
292 return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
293 setLayerBlendModeHook);
294 case FunctionDescriptor::SetLayerColor:
295 return asFP<HWC2_PFN_SET_LAYER_COLOR>(
296 layerHook<decltype(&Layer::setColor), &Layer::setColor,
297 hwc_color_t>);
298 case FunctionDescriptor::SetLayerCompositionType:
299 return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
300 setLayerCompositionTypeHook);
301 case FunctionDescriptor::SetLayerDataspace:
302 return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerDataspaceHook);
303 case FunctionDescriptor::SetLayerDisplayFrame:
304 return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
305 layerHook<decltype(&Layer::setDisplayFrame),
306 &Layer::setDisplayFrame, hwc_rect_t>);
307 case FunctionDescriptor::SetLayerPlaneAlpha:
308 return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
309 layerHook<decltype(&Layer::setPlaneAlpha),
310 &Layer::setPlaneAlpha, float>);
311 case FunctionDescriptor::SetLayerSidebandStream:
312 return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
313 layerHook<decltype(&Layer::setSidebandStream),
314 &Layer::setSidebandStream, const native_handle_t*>);
315 case FunctionDescriptor::SetLayerSourceCrop:
316 return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
317 layerHook<decltype(&Layer::setSourceCrop),
318 &Layer::setSourceCrop, hwc_frect_t>);
319 case FunctionDescriptor::SetLayerTransform:
320 return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerTransformHook);
321 case FunctionDescriptor::SetLayerVisibleRegion:
322 return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
323 layerHook<decltype(&Layer::setVisibleRegion),
324 &Layer::setVisibleRegion, hwc_region_t>);
325 case FunctionDescriptor::SetLayerZOrder:
326 return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerZOrderHook);
327
328 default:
329 ALOGE("doGetFunction: Unknown function descriptor: %d (%s)",
330 static_cast<int32_t>(descriptor),
331 to_string(descriptor).c_str());
332 return nullptr;
333 }
334 }
335
336 // Device functions
337
createVirtualDisplay(uint32_t width,uint32_t height,hwc2_display_t * outDisplay)338 Error CfHWC2::createVirtualDisplay(uint32_t width,
339 uint32_t height, hwc2_display_t* outDisplay) {
340 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
341
342 if (mHwc1VirtualDisplay) {
343 // We have already allocated our only HWC1 virtual display
344 ALOGE("createVirtualDisplay: HWC1 virtual display already allocated");
345 return Error::NoResources;
346 }
347
348 mHwc1VirtualDisplay = std::make_shared<CfHWC2::Display>(*this,
349 HWC2::DisplayType::Virtual);
350 mHwc1VirtualDisplay->populateConfigs(width, height);
351 const auto displayId = mHwc1VirtualDisplay->getId();
352 mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL] = displayId;
353 mHwc1VirtualDisplay->setHwc1Id(HWC_DISPLAY_VIRTUAL);
354 mDisplays.emplace(displayId, mHwc1VirtualDisplay);
355 *outDisplay = displayId;
356
357 return Error::None;
358 }
359
destroyVirtualDisplay(hwc2_display_t displayId)360 Error CfHWC2::destroyVirtualDisplay(hwc2_display_t displayId) {
361 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
362
363 if (!mHwc1VirtualDisplay || (mHwc1VirtualDisplay->getId() != displayId)) {
364 return Error::BadDisplay;
365 }
366
367 mHwc1VirtualDisplay.reset();
368 mHwc1DisplayMap.erase(HWC_DISPLAY_VIRTUAL);
369 mDisplays.erase(displayId);
370
371 return Error::None;
372 }
373
dump(uint32_t * outSize,char * outBuffer)374 void CfHWC2::dump(uint32_t* outSize, char* outBuffer) {
375 if (outBuffer != nullptr) {
376 auto copiedBytes = mDumpString.copy(outBuffer, *outSize);
377 *outSize = static_cast<uint32_t>(copiedBytes);
378 return;
379 }
380
381 std::stringstream output;
382
383 output << "-- CfHWC2 --\n";
384
385 output << "Adapting to a HWC 1." << static_cast<int>(mHwc1MinorVersion) <<
386 " device\n";
387
388 // Attempt to acquire the lock for 1 second, but proceed without the lock
389 // after that, so we can still get some information if we're deadlocked
390 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex,
391 std::defer_lock);
392 lock.try_lock_for(1s);
393
394 if (mCapabilities.empty()) {
395 output << "Capabilities: None\n";
396 } else {
397 output << "Capabilities:\n";
398 for (auto capability : mCapabilities) {
399 output << " " << to_string(capability) << '\n';
400 }
401 }
402
403 output << "Displays:\n";
404 for (const auto& element : mDisplays) {
405 const auto& display = element.second;
406 output << display->dump();
407 }
408 output << '\n';
409
410 // Release the lock before calling into HWC1, and since we no longer require
411 // mutual exclusion to access mCapabilities or mDisplays
412 lock.unlock();
413
414 if (mHwc1Device->dump) {
415 output << "HWC1 dump:\n";
416 std::vector<char> hwc1Dump(4096);
417 // Call with size - 1 to preserve a null character at the end
418 mHwc1Device->dump(mHwc1Device, hwc1Dump.data(),
419 static_cast<int>(hwc1Dump.size() - 1));
420 output << hwc1Dump.data();
421 }
422
423 mDumpString = output.str();
424 *outSize = static_cast<uint32_t>(mDumpString.size());
425 }
426
getMaxVirtualDisplayCount()427 uint32_t CfHWC2::getMaxVirtualDisplayCount() {
428 return mHwc1SupportsVirtualDisplays ? 1 : 0;
429 }
430
isValid(Callback descriptor)431 static bool isValid(Callback descriptor) {
432 switch (descriptor) {
433 case Callback::Hotplug: // Fall-through
434 case Callback::Refresh: // Fall-through
435 case Callback::Vsync: return true;
436 default: return false;
437 }
438 }
439
registerCallback(Callback descriptor,hwc2_callback_data_t callbackData,hwc2_function_pointer_t pointer)440 Error CfHWC2::registerCallback(Callback descriptor,
441 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
442 if (!isValid(descriptor)) {
443 return Error::BadParameter;
444 }
445
446 ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(),
447 callbackData, pointer);
448
449 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
450
451 if (pointer != nullptr) {
452 mCallbacks[descriptor] = {callbackData, pointer};
453 } else {
454 ALOGI("unregisterCallback(%s)", to_string(descriptor).c_str());
455 mCallbacks.erase(descriptor);
456 return Error::None;
457 }
458
459 bool hasPendingInvalidate = false;
460 std::vector<hwc2_display_t> displayIds;
461 std::vector<std::pair<hwc2_display_t, int64_t>> pendingVsyncs;
462 std::vector<std::pair<hwc2_display_t, int>> pendingHotplugs;
463
464 if (descriptor == Callback::Refresh) {
465 hasPendingInvalidate = mHasPendingInvalidate;
466 if (hasPendingInvalidate) {
467 for (auto& displayPair : mDisplays) {
468 displayIds.emplace_back(displayPair.first);
469 }
470 }
471 mHasPendingInvalidate = false;
472 } else if (descriptor == Callback::Vsync) {
473 for (auto pending : mPendingVsyncs) {
474 auto hwc1DisplayId = pending.first;
475 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
476 ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d",
477 hwc1DisplayId);
478 continue;
479 }
480 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
481 auto timestamp = pending.second;
482 pendingVsyncs.emplace_back(displayId, timestamp);
483 }
484 mPendingVsyncs.clear();
485 } else if (descriptor == Callback::Hotplug) {
486 // Hotplug the primary display
487 pendingHotplugs.emplace_back(mHwc1DisplayMap[HWC_DISPLAY_PRIMARY],
488 static_cast<int32_t>(Connection::Connected));
489
490 for (auto pending : mPendingHotplugs) {
491 auto hwc1DisplayId = pending.first;
492 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
493 ALOGE("hwc1Hotplug: Couldn't find display for HWC1 id %d",
494 hwc1DisplayId);
495 continue;
496 }
497 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
498 auto connected = pending.second;
499 pendingHotplugs.emplace_back(displayId, connected);
500 }
501 }
502
503 // Call pending callbacks without the state lock held
504 lock.unlock();
505
506 if (hasPendingInvalidate) {
507 auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
508 for (auto displayId : displayIds) {
509 refresh(callbackData, displayId);
510 }
511 }
512 if (!pendingVsyncs.empty()) {
513 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
514 for (auto& pendingVsync : pendingVsyncs) {
515 vsync(callbackData, pendingVsync.first, pendingVsync.second);
516 }
517 }
518 if (!pendingHotplugs.empty()) {
519 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
520 for (auto& pendingHotplug : pendingHotplugs) {
521 hotplug(callbackData, pendingHotplug.first, pendingHotplug.second);
522 }
523 }
524 return Error::None;
525 }
526
527 // Display functions
528
529 std::atomic<hwc2_display_t> CfHWC2::Display::sNextId(1);
530
Display(CfHWC2 & device,HWC2::DisplayType type)531 CfHWC2::Display::Display(CfHWC2& device, HWC2::DisplayType type)
532 : mId(sNextId++),
533 mDevice(device),
534 mStateMutex(),
535 mHwc1RequestedContents(nullptr),
536 mRetireFence(),
537 mChanges(),
538 mHwc1Id(-1),
539 mConfigs(),
540 mActiveConfig(nullptr),
541 mActiveColorMode(static_cast<android_color_mode_t>(-1)),
542 mName(),
543 mType(type),
544 mPowerMode(PowerMode::Off),
545 mVsyncEnabled(Vsync::Invalid),
546 mClientTarget(),
547 mOutputBuffer(),
548 mHasColorTransform(false),
549 mLayers(),
550 mHwc1LayerMap(),
551 mNumAvailableRects(0),
552 mNextAvailableRect(nullptr),
553 mGeometryChanged(false)
554 {}
555
acceptChanges()556 Error CfHWC2::Display::acceptChanges() {
557 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
558
559 if (!mChanges) {
560 ALOGV("[%" PRIu64 "] acceptChanges failed, not validated", mId);
561 return Error::NotValidated;
562 }
563
564 ALOGV("[%" PRIu64 "] acceptChanges", mId);
565
566 for (auto& change : mChanges->getTypeChanges()) {
567 auto layerId = change.first;
568 auto type = change.second;
569 if (mDevice.mLayers.count(layerId) == 0) {
570 // This should never happen but somehow does.
571 ALOGW("Cannot accept change for unknown layer (%" PRIu64 ")",
572 layerId);
573 continue;
574 }
575 auto layer = mDevice.mLayers[layerId];
576 layer->setCompositionType(type);
577 }
578
579 mChanges->clearTypeChanges();
580
581 return Error::None;
582 }
583
createLayer(hwc2_layer_t * outLayerId)584 Error CfHWC2::Display::createLayer(hwc2_layer_t* outLayerId) {
585 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
586
587 auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
588 mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
589 *outLayerId = layer->getId();
590 ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId);
591 markGeometryChanged();
592 return Error::None;
593 }
594
destroyLayer(hwc2_layer_t layerId)595 Error CfHWC2::Display::destroyLayer(hwc2_layer_t layerId) {
596 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
597
598 const auto mapLayer = mDevice.mLayers.find(layerId);
599 if (mapLayer == mDevice.mLayers.end()) {
600 ALOGV("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer",
601 mId, layerId);
602 return Error::BadLayer;
603 }
604 const auto layer = mapLayer->second;
605 mDevice.mLayers.erase(mapLayer);
606 const auto zRange = mLayers.equal_range(layer);
607 for (auto current = zRange.first; current != zRange.second; ++current) {
608 if (**current == *layer) {
609 current = mLayers.erase(current);
610 break;
611 }
612 }
613 ALOGV("[%" PRIu64 "] destroyed layer %" PRIu64, mId, layerId);
614 markGeometryChanged();
615 return Error::None;
616 }
617
getActiveConfig(hwc2_config_t * outConfig)618 Error CfHWC2::Display::getActiveConfig(hwc2_config_t* outConfig) {
619 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
620
621 if (!mActiveConfig) {
622 ALOGV("[%" PRIu64 "] getActiveConfig --> %s", mId,
623 to_string(Error::BadConfig).c_str());
624 return Error::BadConfig;
625 }
626 auto configId = mActiveConfig->getId();
627 ALOGV("[%" PRIu64 "] getActiveConfig --> %u", mId, configId);
628 *outConfig = configId;
629 return Error::None;
630 }
631
getAttribute(hwc2_config_t configId,Attribute attribute,int32_t * outValue)632 Error CfHWC2::Display::getAttribute(hwc2_config_t configId,
633 Attribute attribute, int32_t* outValue) {
634 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
635
636 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
637 ALOGV("[%" PRIu64 "] getAttribute failed: bad config (%u)", mId,
638 configId);
639 return Error::BadConfig;
640 }
641 *outValue = mConfigs[configId]->getAttribute(attribute);
642 ALOGV("[%" PRIu64 "] getAttribute(%u, %s) --> %d", mId, configId,
643 to_string(attribute).c_str(), *outValue);
644 return Error::None;
645 }
646
getChangedCompositionTypes(uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outTypes)647 Error CfHWC2::Display::getChangedCompositionTypes(
648 uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) {
649 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
650
651 if (!mChanges) {
652 ALOGE("[%" PRIu64 "] getChangedCompositionTypes failed: not validated",
653 mId);
654 return Error::NotValidated;
655 }
656
657 if ((outLayers == nullptr) || (outTypes == nullptr)) {
658 *outNumElements = mChanges->getTypeChanges().size();
659 return Error::None;
660 }
661
662 uint32_t numWritten = 0;
663 for (const auto& element : mChanges->getTypeChanges()) {
664 if (numWritten == *outNumElements) {
665 break;
666 }
667 auto layerId = element.first;
668 auto intType = static_cast<int32_t>(element.second);
669 ALOGV("Adding %" PRIu64 " %s", layerId,
670 to_string(element.second).c_str());
671 outLayers[numWritten] = layerId;
672 outTypes[numWritten] = intType;
673 ++numWritten;
674 }
675 *outNumElements = numWritten;
676
677 return Error::None;
678 }
679
getColorModes(uint32_t * outNumModes,int32_t * outModes)680 Error CfHWC2::Display::getColorModes(uint32_t* outNumModes,
681 int32_t* outModes) {
682 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
683
684 if (!outModes) {
685 *outNumModes = mColorModes.size();
686 return Error::None;
687 }
688 uint32_t numModes = std::min(*outNumModes,
689 static_cast<uint32_t>(mColorModes.size()));
690 std::copy_n(mColorModes.cbegin(), numModes, outModes);
691 *outNumModes = numModes;
692 return Error::None;
693 }
694
getConfigs(uint32_t * outNumConfigs,hwc2_config_t * outConfigs)695 Error CfHWC2::Display::getConfigs(uint32_t* outNumConfigs,
696 hwc2_config_t* outConfigs) {
697 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
698
699 if (!outConfigs) {
700 *outNumConfigs = mConfigs.size();
701 return Error::None;
702 }
703 uint32_t numWritten = 0;
704 for (const auto& config : mConfigs) {
705 if (numWritten == *outNumConfigs) {
706 break;
707 }
708 outConfigs[numWritten] = config->getId();
709 ++numWritten;
710 }
711 *outNumConfigs = numWritten;
712 return Error::None;
713 }
714
getDozeSupport(int32_t * outSupport)715 Error CfHWC2::Display::getDozeSupport(int32_t* outSupport) {
716 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
717
718 if (mDevice.mHwc1MinorVersion < 4 || mHwc1Id != 0) {
719 *outSupport = 0;
720 } else {
721 *outSupport = 1;
722 }
723 return Error::None;
724 }
725
getHdrCapabilities(uint32_t * outNumTypes,int32_t *,float *,float *,float *)726 Error CfHWC2::Display::getHdrCapabilities(uint32_t* outNumTypes,
727 int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
728 float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
729 // This isn't supported on HWC1, so per the HWC2 header, return numTypes = 0
730 *outNumTypes = 0;
731 return Error::None;
732 }
733
getName(uint32_t * outSize,char * outName)734 Error CfHWC2::Display::getName(uint32_t* outSize, char* outName) {
735 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
736
737 if (!outName) {
738 *outSize = mName.size();
739 return Error::None;
740 }
741 auto numCopied = mName.copy(outName, *outSize);
742 *outSize = numCopied;
743 return Error::None;
744 }
745
getReleaseFences(uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outFences)746 Error CfHWC2::Display::getReleaseFences(uint32_t* outNumElements,
747 hwc2_layer_t* outLayers, int32_t* outFences) {
748 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
749
750 uint32_t numWritten = 0;
751 bool outputsNonNull = (outLayers != nullptr) && (outFences != nullptr);
752 for (const auto& layer : mLayers) {
753 if (outputsNonNull && (numWritten == *outNumElements)) {
754 break;
755 }
756
757 auto releaseFence = layer->getReleaseFence();
758 if (releaseFence != MiniFence::NO_FENCE) {
759 if (outputsNonNull) {
760 outLayers[numWritten] = layer->getId();
761 outFences[numWritten] = releaseFence->dup();
762 }
763 ++numWritten;
764 }
765 }
766 *outNumElements = numWritten;
767
768 return Error::None;
769 }
770
getRequests(int32_t * outDisplayRequests,uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outLayerRequests)771 Error CfHWC2::Display::getRequests(int32_t* outDisplayRequests,
772 uint32_t* outNumElements, hwc2_layer_t* outLayers,
773 int32_t* outLayerRequests) {
774 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
775
776 if (!mChanges) {
777 return Error::NotValidated;
778 }
779
780 if (outLayers == nullptr || outLayerRequests == nullptr) {
781 *outNumElements = mChanges->getNumLayerRequests();
782 return Error::None;
783 }
784
785 // Display requests (HWC2::DisplayRequest) are not supported by hwc1:
786 // A hwc1 has always zero requests for the client.
787 *outDisplayRequests = 0;
788
789 uint32_t numWritten = 0;
790 for (const auto& request : mChanges->getLayerRequests()) {
791 if (numWritten == *outNumElements) {
792 break;
793 }
794 outLayers[numWritten] = request.first;
795 outLayerRequests[numWritten] = static_cast<int32_t>(request.second);
796 ++numWritten;
797 }
798
799 return Error::None;
800 }
801
getType(int32_t * outType)802 Error CfHWC2::Display::getType(int32_t* outType) {
803 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
804
805 *outType = static_cast<int32_t>(mType);
806 return Error::None;
807 }
808
present(int32_t * outRetireFence)809 Error CfHWC2::Display::present(int32_t* outRetireFence) {
810 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
811
812 if (mChanges) {
813 Error error = mDevice.setAllDisplays();
814 if (error != Error::None) {
815 ALOGE("[%" PRIu64 "] present: setAllDisplaysFailed (%s)", mId,
816 to_string(error).c_str());
817 return error;
818 }
819 }
820
821 *outRetireFence = mRetireFence.get()->dup();
822 ALOGV("[%" PRIu64 "] present returning retire fence %d", mId,
823 *outRetireFence);
824
825 return Error::None;
826 }
827
setActiveConfig(hwc2_config_t configId)828 Error CfHWC2::Display::setActiveConfig(hwc2_config_t configId) {
829 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
830
831 auto config = getConfig(configId);
832 if (!config) {
833 return Error::BadConfig;
834 }
835 if (config == mActiveConfig) {
836 return Error::None;
837 }
838
839 if (mDevice.mHwc1MinorVersion >= 4) {
840 uint32_t hwc1Id = 0;
841 auto error = config->getHwc1IdForColorMode(mActiveColorMode, &hwc1Id);
842 if (error != Error::None) {
843 return error;
844 }
845
846 int intError = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
847 mHwc1Id, static_cast<int>(hwc1Id));
848 if (intError != 0) {
849 ALOGE("setActiveConfig: Failed to set active config on HWC1 (%d)",
850 intError);
851 return Error::BadConfig;
852 }
853 mActiveConfig = config;
854 }
855
856 return Error::None;
857 }
858
setClientTarget(buffer_handle_t target,int32_t acquireFence,int32_t,hwc_region_t)859 Error CfHWC2::Display::setClientTarget(buffer_handle_t target,
860 int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
861 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
862
863 ALOGV("[%" PRIu64 "] setClientTarget(%p, %d)", mId, target, acquireFence);
864 mClientTarget.setBuffer(target);
865 mClientTarget.setFence(acquireFence);
866 // dataspace and damage can't be used by HWC1, so ignore them
867 return Error::None;
868 }
869
setColorMode(android_color_mode_t mode)870 Error CfHWC2::Display::setColorMode(android_color_mode_t mode) {
871 std::unique_lock<std::recursive_mutex> lock (mStateMutex);
872
873 ALOGV("[%" PRIu64 "] setColorMode(%d)", mId, mode);
874
875 if (mode == mActiveColorMode) {
876 return Error::None;
877 }
878 if (mColorModes.count(mode) == 0) {
879 ALOGE("[%" PRIu64 "] Mode %d not found in mColorModes", mId, mode);
880 return Error::Unsupported;
881 }
882
883 if (mDevice.mHwc1MinorVersion >= 4) {
884 uint32_t hwc1Config = 0;
885 auto error = mActiveConfig->getHwc1IdForColorMode(mode, &hwc1Config);
886 if (error != Error::None) {
887 return error;
888 }
889
890 ALOGV("[%" PRIu64 "] Setting HWC1 config %u", mId, hwc1Config);
891 int intError =
892 mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device, mHwc1Id, hwc1Config);
893 if (intError != 0) {
894 ALOGE("[%" PRIu64 "] Failed to set HWC1 config (%d)", mId, intError);
895 return Error::Unsupported;
896 }
897 }
898
899 mActiveColorMode = mode;
900 return Error::None;
901 }
902
setColorTransform(android_color_transform_t hint)903 Error CfHWC2::Display::setColorTransform(android_color_transform_t hint) {
904 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
905
906 ALOGV("%" PRIu64 "] setColorTransform(%d)", mId,
907 static_cast<int32_t>(hint));
908 mHasColorTransform = (hint != HAL_COLOR_TRANSFORM_IDENTITY);
909 return Error::None;
910 }
911
setOutputBuffer(buffer_handle_t buffer,int32_t releaseFence)912 Error CfHWC2::Display::setOutputBuffer(buffer_handle_t buffer,
913 int32_t releaseFence) {
914 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
915
916 ALOGV("[%" PRIu64 "] setOutputBuffer(%p, %d)", mId, buffer, releaseFence);
917 mOutputBuffer.setBuffer(buffer);
918 mOutputBuffer.setFence(releaseFence);
919 return Error::None;
920 }
921
isValid(PowerMode mode)922 static bool isValid(PowerMode mode) {
923 switch (mode) {
924 case PowerMode::Off: // Fall-through
925 case PowerMode::DozeSuspend: // Fall-through
926 case PowerMode::Doze: // Fall-through
927 case PowerMode::On: return true;
928 }
929 }
930
getHwc1PowerMode(PowerMode mode)931 static int getHwc1PowerMode(PowerMode mode) {
932 switch (mode) {
933 case PowerMode::Off: return HWC_POWER_MODE_OFF;
934 case PowerMode::DozeSuspend: return HWC_POWER_MODE_DOZE_SUSPEND;
935 case PowerMode::Doze: return HWC_POWER_MODE_DOZE;
936 case PowerMode::On: return HWC_POWER_MODE_NORMAL;
937 }
938 }
939
setPowerMode(PowerMode mode)940 Error CfHWC2::Display::setPowerMode(PowerMode mode) {
941 if (!isValid(mode)) {
942 return Error::BadParameter;
943 }
944 if (mode == mPowerMode) {
945 return Error::None;
946 }
947
948 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
949
950 int error = 0;
951 if (mDevice.mHwc1MinorVersion < 4) {
952 error = mDevice.mHwc1Device->blank(mDevice.mHwc1Device, mHwc1Id,
953 mode == PowerMode::Off);
954 } else {
955 error = mDevice.mHwc1Device->setPowerMode(mDevice.mHwc1Device,
956 mHwc1Id, getHwc1PowerMode(mode));
957 }
958 ALOGE_IF(error != 0, "setPowerMode: Failed to set power mode on HWC1 (%d)",
959 error);
960
961 ALOGV("[%" PRIu64 "] setPowerMode(%s)", mId, to_string(mode).c_str());
962 mPowerMode = mode;
963 return Error::None;
964 }
965
isValid(Vsync enable)966 static bool isValid(Vsync enable) {
967 switch (enable) {
968 case Vsync::Enable: // Fall-through
969 case Vsync::Disable: return true;
970 case Vsync::Invalid: return false;
971 }
972 }
973
setVsyncEnabled(Vsync enable)974 Error CfHWC2::Display::setVsyncEnabled(Vsync enable) {
975 if (!isValid(enable)) {
976 return Error::BadParameter;
977 }
978 if (enable == mVsyncEnabled) {
979 return Error::None;
980 }
981
982 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
983
984 int error = mDevice.mHwc1Device->eventControl(mDevice.mHwc1Device,
985 mHwc1Id, HWC_EVENT_VSYNC, enable == Vsync::Enable);
986 ALOGE_IF(error != 0, "setVsyncEnabled: Failed to set vsync on HWC1 (%d)",
987 error);
988
989 mVsyncEnabled = enable;
990 return Error::None;
991 }
992
validate(uint32_t * outNumTypes,uint32_t * outNumRequests)993 Error CfHWC2::Display::validate(uint32_t* outNumTypes,
994 uint32_t* outNumRequests) {
995 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
996
997 if (!mChanges) {
998 if (!mDevice.prepareAllDisplays()) {
999 return Error::BadDisplay;
1000 }
1001 } else {
1002 ALOGE("Validate was called more than once!");
1003 }
1004
1005 *outNumTypes = mChanges->getNumTypes();
1006 *outNumRequests = mChanges->getNumLayerRequests();
1007 ALOGV("[%" PRIu64 "] validate --> %u types, %u requests", mId, *outNumTypes,
1008 *outNumRequests);
1009 for (auto request : mChanges->getTypeChanges()) {
1010 ALOGV("Layer %" PRIu64 " --> %s", request.first,
1011 to_string(request.second).c_str());
1012 }
1013 return *outNumTypes > 0 ? Error::HasChanges : Error::None;
1014 }
1015
updateLayerZ(hwc2_layer_t layerId,uint32_t z)1016 Error CfHWC2::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
1017 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1018
1019 const auto mapLayer = mDevice.mLayers.find(layerId);
1020 if (mapLayer == mDevice.mLayers.end()) {
1021 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer", mId);
1022 return Error::BadLayer;
1023 }
1024
1025 const auto layer = mapLayer->second;
1026 const auto zRange = mLayers.equal_range(layer);
1027 bool layerOnDisplay = false;
1028 for (auto current = zRange.first; current != zRange.second; ++current) {
1029 if (**current == *layer) {
1030 if ((*current)->getZ() == z) {
1031 // Don't change anything if the Z hasn't changed
1032 return Error::None;
1033 }
1034 current = mLayers.erase(current);
1035 layerOnDisplay = true;
1036 break;
1037 }
1038 }
1039
1040 if (!layerOnDisplay) {
1041 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display",
1042 mId);
1043 return Error::BadLayer;
1044 }
1045
1046 layer->setZ(z);
1047 mLayers.emplace(std::move(layer));
1048 markGeometryChanged();
1049
1050 return Error::None;
1051 }
1052
getClientTargetSupport(uint32_t width,uint32_t height,int32_t format,int32_t dataspace)1053 Error CfHWC2::Display::getClientTargetSupport(uint32_t width, uint32_t height,
1054 int32_t format, int32_t dataspace){
1055 if (mActiveConfig == nullptr) {
1056 return Error::Unsupported;
1057 }
1058
1059 if (width == mActiveConfig->getAttribute(Attribute::Width) &&
1060 height == mActiveConfig->getAttribute(Attribute::Height) &&
1061 format == HAL_PIXEL_FORMAT_RGBA_8888 &&
1062 dataspace == HAL_DATASPACE_UNKNOWN) {
1063 return Error::None;
1064 }
1065
1066 return Error::Unsupported;
1067 }
1068
1069 // thess EDIDs are carefully generated according to the EDID spec version 1.3, more info
1070 // can be found from the following file:
1071 // frameworks/native/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
1072 // approved pnp ids can be found here: https://uefi.org/pnp_id_list
1073 // pnp id: GGL, name: EMU_display_0, last byte is checksum
1074 // display id is local:8141603649153536
1075 static const uint8_t sEDID0[] = {
1076 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
1077 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27,
1078 0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1079 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
1080 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1081 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1082 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
1083 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x30, 0x00, 0x4b
1084 };
1085
1086 // pnp id: GGL, name: EMU_display_1
1087 // display id is local:8140900251843329
1088 static const uint8_t sEDID1[] = {
1089 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
1090 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27,
1091 0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1092 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
1093 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1094 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1095 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
1096 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x00, 0x3b
1097 };
1098
1099 // pnp id: GGL, name: EMU_display_2
1100 // display id is local:8140940453066754
1101 static const uint8_t sEDID2[] = {
1102 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
1103 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27,
1104 0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1105 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
1106 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
1109 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x00, 0x49
1110 };
1111
1112 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
1113
getDisplayIdentificationData(uint8_t * outPort,uint32_t * outDataSize,uint8_t * outData)1114 Error CfHWC2::Display::getDisplayIdentificationData(uint8_t* outPort,
1115 uint32_t* outDataSize, uint8_t* outData) {
1116 ALOGV("%s DisplayId %u", __FUNCTION__, (uint32_t)mId);
1117 if (outPort == nullptr || outDataSize == nullptr)
1118 return Error::BadParameter;
1119
1120 uint32_t len = std::min(*outDataSize, (uint32_t)ARRAY_SIZE(sEDID0));
1121 if (outData != nullptr && len < (uint32_t)ARRAY_SIZE(sEDID0)) {
1122 ALOGW("%s DisplayId %u, small buffer size: %u is specified",
1123 __FUNCTION__, (uint32_t)mId, len);
1124 }
1125 *outDataSize = ARRAY_SIZE(sEDID0);
1126 switch (mId) {
1127 case 0:
1128 *outPort = 0;
1129 if (outData)
1130 memcpy(outData, sEDID0, len);
1131 break;
1132
1133 case 1:
1134 *outPort = 1;
1135 if (outData)
1136 memcpy(outData, sEDID1, len);
1137 break;
1138
1139 case 2:
1140 *outPort = 2;
1141 if (outData)
1142 memcpy(outData, sEDID2, len);
1143 break;
1144
1145 default:
1146 *outPort = (uint8_t)mId;
1147 if (outData) {
1148 memcpy(outData, sEDID2, len);
1149 uint32_t size = ARRAY_SIZE(sEDID0);
1150 // change the name to EMU_display_<mID>
1151 // note the 3rd char from back is the number, _0, _1, _2, etc.
1152 if (len >= size - 2)
1153 outData[size-3] = '0' + (uint8_t)mId;
1154 if (len >= size) {
1155 // update the last byte, which is checksum byte
1156 uint8_t checksum = -(uint8_t)std::accumulate(
1157 outData, outData + size - 1, static_cast<uint8_t>(0));
1158 outData[size - 1] = checksum;
1159 }
1160 }
1161 break;
1162 }
1163
1164 return Error::None;
1165 }
1166
getDisplayCapabilities(uint32_t * outNumCapabilities,uint32_t * outCapabilities)1167 Error CfHWC2::Display::getDisplayCapabilities(uint32_t* outNumCapabilities,
1168 uint32_t* outCapabilities) {
1169 ALOGV("%s DisplayId %u", __FUNCTION__, (uint32_t)mId);
1170 if (outNumCapabilities == nullptr) {
1171 return Error::None;
1172 }
1173
1174 bool brightness_support = true;
1175 bool doze_support = true;
1176
1177 uint32_t count = 1 + static_cast<uint32_t>(doze_support) + (brightness_support ? 1 : 0);
1178 int index = 0;
1179 if (outCapabilities != nullptr && (*outNumCapabilities >= count)) {
1180 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
1181 if (doze_support) {
1182 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_DOZE;
1183 }
1184 if (brightness_support) {
1185 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_BRIGHTNESS;
1186 }
1187 }
1188
1189 *outNumCapabilities = count;
1190 return Error::None;
1191 }
1192
getDisplayBrightnessSupport(bool * out_support)1193 Error CfHWC2::Display::getDisplayBrightnessSupport(bool *out_support) {
1194 *out_support = false;
1195 return Error::None;
1196 }
1197
setDisplayBrightness(float brightness)1198 Error CfHWC2::Display::setDisplayBrightness(float brightness) {
1199 ALOGW("TODO: setDisplayBrightness() is not implemented yet: brightness=%f", brightness);
1200 return Error::None;
1201 }
1202
1203 static constexpr uint32_t ATTRIBUTES_WITH_COLOR[] = {
1204 HWC_DISPLAY_VSYNC_PERIOD,
1205 HWC_DISPLAY_WIDTH,
1206 HWC_DISPLAY_HEIGHT,
1207 HWC_DISPLAY_DPI_X,
1208 HWC_DISPLAY_DPI_Y,
1209 HWC_DISPLAY_COLOR_TRANSFORM,
1210 HWC_DISPLAY_NO_ATTRIBUTE,
1211 };
1212
1213 static constexpr uint32_t ATTRIBUTES_WITHOUT_COLOR[] = {
1214 HWC_DISPLAY_VSYNC_PERIOD,
1215 HWC_DISPLAY_WIDTH,
1216 HWC_DISPLAY_HEIGHT,
1217 HWC_DISPLAY_DPI_X,
1218 HWC_DISPLAY_DPI_Y,
1219 HWC_DISPLAY_NO_ATTRIBUTE,
1220 };
1221
1222 static constexpr size_t NUM_ATTRIBUTES_WITH_COLOR =
1223 sizeof(ATTRIBUTES_WITH_COLOR) / sizeof(uint32_t);
1224 static_assert(sizeof(ATTRIBUTES_WITH_COLOR) > sizeof(ATTRIBUTES_WITHOUT_COLOR),
1225 "Attribute tables have unexpected sizes");
1226
1227 static constexpr uint32_t ATTRIBUTE_MAP_WITH_COLOR[] = {
1228 6, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1229 0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1230 1, // HWC_DISPLAY_WIDTH = 2,
1231 2, // HWC_DISPLAY_HEIGHT = 3,
1232 3, // HWC_DISPLAY_DPI_X = 4,
1233 4, // HWC_DISPLAY_DPI_Y = 5,
1234 5, // HWC_DISPLAY_COLOR_TRANSFORM = 6,
1235 };
1236
1237 static constexpr uint32_t ATTRIBUTE_MAP_WITHOUT_COLOR[] = {
1238 5, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1239 0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1240 1, // HWC_DISPLAY_WIDTH = 2,
1241 2, // HWC_DISPLAY_HEIGHT = 3,
1242 3, // HWC_DISPLAY_DPI_X = 4,
1243 4, // HWC_DISPLAY_DPI_Y = 5,
1244 };
1245
1246 template <uint32_t attribute>
attributesMatch()1247 static constexpr bool attributesMatch()
1248 {
1249 bool match = (attribute ==
1250 ATTRIBUTES_WITH_COLOR[ATTRIBUTE_MAP_WITH_COLOR[attribute]]);
1251 if (attribute == HWC_DISPLAY_COLOR_TRANSFORM) {
1252 return match;
1253 }
1254
1255 return match && (attribute ==
1256 ATTRIBUTES_WITHOUT_COLOR[ATTRIBUTE_MAP_WITHOUT_COLOR[attribute]]);
1257 }
1258 static_assert(attributesMatch<HWC_DISPLAY_VSYNC_PERIOD>(),
1259 "Tables out of sync");
1260 static_assert(attributesMatch<HWC_DISPLAY_WIDTH>(), "Tables out of sync");
1261 static_assert(attributesMatch<HWC_DISPLAY_HEIGHT>(), "Tables out of sync");
1262 static_assert(attributesMatch<HWC_DISPLAY_DPI_X>(), "Tables out of sync");
1263 static_assert(attributesMatch<HWC_DISPLAY_DPI_Y>(), "Tables out of sync");
1264 static_assert(attributesMatch<HWC_DISPLAY_COLOR_TRANSFORM>(),
1265 "Tables out of sync");
1266
populateConfigs()1267 void CfHWC2::Display::populateConfigs() {
1268 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1269
1270 ALOGV("[%" PRIu64 "] populateConfigs", mId);
1271
1272 if (mHwc1Id == -1) {
1273 ALOGE("populateConfigs: HWC1 ID not set");
1274 return;
1275 }
1276
1277 const size_t MAX_NUM_CONFIGS = 128;
1278 uint32_t configs[MAX_NUM_CONFIGS] = {};
1279 size_t numConfigs = MAX_NUM_CONFIGS;
1280 mDevice.mHwc1Device->getDisplayConfigs(mDevice.mHwc1Device, mHwc1Id,
1281 configs, &numConfigs);
1282
1283 for (size_t c = 0; c < numConfigs; ++c) {
1284 uint32_t hwc1ConfigId = configs[c];
1285 auto newConfig = std::make_shared<Config>(*this);
1286
1287 int32_t values[NUM_ATTRIBUTES_WITH_COLOR] = {};
1288 bool hasColor = true;
1289 auto result = mDevice.mHwc1Device->getDisplayAttributes(
1290 mDevice.mHwc1Device, mHwc1Id, hwc1ConfigId,
1291 ATTRIBUTES_WITH_COLOR, values);
1292 if (result != 0) {
1293 mDevice.mHwc1Device->getDisplayAttributes(mDevice.mHwc1Device,
1294 mHwc1Id, hwc1ConfigId, ATTRIBUTES_WITHOUT_COLOR, values);
1295 hasColor = false;
1296 }
1297
1298 auto attributeMap = hasColor ?
1299 ATTRIBUTE_MAP_WITH_COLOR : ATTRIBUTE_MAP_WITHOUT_COLOR;
1300
1301 newConfig->setAttribute(Attribute::VsyncPeriod,
1302 values[attributeMap[HWC_DISPLAY_VSYNC_PERIOD]]);
1303 newConfig->setAttribute(Attribute::Width,
1304 values[attributeMap[HWC_DISPLAY_WIDTH]]);
1305 newConfig->setAttribute(Attribute::Height,
1306 values[attributeMap[HWC_DISPLAY_HEIGHT]]);
1307 newConfig->setAttribute(Attribute::DpiX,
1308 values[attributeMap[HWC_DISPLAY_DPI_X]]);
1309 newConfig->setAttribute(Attribute::DpiY,
1310 values[attributeMap[HWC_DISPLAY_DPI_Y]]);
1311 if (hasColor) {
1312 // In HWC1, color modes are referred to as color transforms. To avoid confusion with
1313 // the HWC2 concept of color transforms, we internally refer to them as color modes for
1314 // both HWC1 and 2.
1315 newConfig->setAttribute(ColorMode,
1316 values[attributeMap[HWC_DISPLAY_COLOR_TRANSFORM]]);
1317 }
1318
1319 // We can only do this after attempting to read the color mode
1320 newConfig->setHwc1Id(hwc1ConfigId);
1321
1322 for (auto& existingConfig : mConfigs) {
1323 if (existingConfig->merge(*newConfig)) {
1324 ALOGV("Merged config %d with existing config %u: %s",
1325 hwc1ConfigId, existingConfig->getId(),
1326 existingConfig->toString().c_str());
1327 newConfig.reset();
1328 break;
1329 }
1330 }
1331
1332 // If it wasn't merged with any existing config, add it to the end
1333 if (newConfig) {
1334 newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
1335 ALOGV("Found new config %u: %s", newConfig->getId(),
1336 newConfig->toString().c_str());
1337 mConfigs.emplace_back(std::move(newConfig));
1338 }
1339 }
1340
1341 initializeActiveConfig();
1342 populateColorModes();
1343 }
1344
populateConfigs(uint32_t width,uint32_t height)1345 void CfHWC2::Display::populateConfigs(uint32_t width, uint32_t height) {
1346 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1347
1348 mConfigs.emplace_back(std::make_shared<Config>(*this));
1349 auto& config = mConfigs[0];
1350
1351 config->setAttribute(Attribute::Width, static_cast<int32_t>(width));
1352 config->setAttribute(Attribute::Height, static_cast<int32_t>(height));
1353 config->setHwc1Id(0);
1354 config->setId(0);
1355 mActiveConfig = config;
1356 }
1357
prepare()1358 bool CfHWC2::Display::prepare() {
1359 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1360
1361 // Only prepare display contents for displays HWC1 knows about
1362 if (mHwc1Id == -1) {
1363 return true;
1364 }
1365
1366 // It doesn't make sense to prepare a display for which there is no active
1367 // config, so return early
1368 if (!mActiveConfig) {
1369 ALOGE("[%" PRIu64 "] Attempted to prepare, but no config active", mId);
1370 return false;
1371 }
1372
1373 allocateRequestedContents();
1374 assignHwc1LayerIds();
1375
1376 mHwc1RequestedContents->retireFenceFd = -1;
1377 mHwc1RequestedContents->flags = 0;
1378 if (mGeometryChanged) {
1379 mHwc1RequestedContents->flags |= HWC_GEOMETRY_CHANGED;
1380 }
1381 mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer();
1382 mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence();
1383
1384 // +1 is for framebuffer target layer.
1385 mHwc1RequestedContents->numHwLayers = mLayers.size() + 1;
1386 for (auto& layer : mLayers) {
1387 auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
1388 hwc1Layer.releaseFenceFd = -1;
1389 hwc1Layer.acquireFenceFd = -1;
1390 ALOGV("Applying states for layer %" PRIu64 " ", layer->getId());
1391 layer->applyState(hwc1Layer);
1392 }
1393
1394 prepareFramebufferTarget();
1395
1396 resetGeometryMarker();
1397
1398 return true;
1399 }
1400
generateChanges()1401 void CfHWC2::Display::generateChanges() {
1402 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1403
1404 mChanges.reset(new Changes);
1405
1406 size_t numLayers = mHwc1RequestedContents->numHwLayers;
1407 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1408 const auto& receivedLayer = mHwc1RequestedContents->hwLayers[hwc1Id];
1409 if (mHwc1LayerMap.count(hwc1Id) == 0) {
1410 ALOGE_IF(receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET,
1411 "generateChanges: HWC1 layer %zd doesn't have a"
1412 " matching HWC2 layer, and isn't the framebuffer target",
1413 hwc1Id);
1414 continue;
1415 }
1416
1417 Layer& layer = *mHwc1LayerMap[hwc1Id];
1418 updateTypeChanges(receivedLayer, layer);
1419 updateLayerRequests(receivedLayer, layer);
1420 }
1421 }
1422
hasChanges() const1423 bool CfHWC2::Display::hasChanges() const {
1424 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1425 return mChanges != nullptr;
1426 }
1427
set(hwc_display_contents_1 & hwcContents)1428 Error CfHWC2::Display::set(hwc_display_contents_1& hwcContents) {
1429 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1430
1431 if (!mChanges || (mChanges->getNumTypes() > 0)) {
1432 ALOGE("[%" PRIu64 "] set failed: not validated", mId);
1433 return Error::NotValidated;
1434 }
1435
1436 // Set up the client/framebuffer target
1437 auto numLayers = hwcContents.numHwLayers;
1438
1439 // Close acquire fences on FRAMEBUFFER layers, since they will not be used
1440 // by HWC
1441 for (size_t l = 0; l < numLayers - 1; ++l) {
1442 auto& layer = hwcContents.hwLayers[l];
1443 if (layer.compositionType == HWC_FRAMEBUFFER) {
1444 ALOGV("Closing fence %d for layer %zd", layer.acquireFenceFd, l);
1445 close(layer.acquireFenceFd);
1446 layer.acquireFenceFd = -1;
1447 }
1448 }
1449
1450 auto& clientTargetLayer = hwcContents.hwLayers[numLayers - 1];
1451 if (clientTargetLayer.compositionType == HWC_FRAMEBUFFER_TARGET) {
1452 clientTargetLayer.handle = mClientTarget.getBuffer();
1453 clientTargetLayer.acquireFenceFd = mClientTarget.getFence();
1454 } else {
1455 ALOGE("[%" PRIu64 "] set: last HWC layer wasn't FRAMEBUFFER_TARGET",
1456 mId);
1457 }
1458
1459 mChanges.reset();
1460
1461 return Error::None;
1462 }
1463
addRetireFence(int fenceFd)1464 void CfHWC2::Display::addRetireFence(int fenceFd) {
1465 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1466 mRetireFence.add(fenceFd);
1467 }
1468
addReleaseFences(const hwc_display_contents_1_t & hwcContents)1469 void CfHWC2::Display::addReleaseFences(
1470 const hwc_display_contents_1_t& hwcContents) {
1471 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1472
1473 size_t numLayers = hwcContents.numHwLayers;
1474 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1475 const auto& receivedLayer = hwcContents.hwLayers[hwc1Id];
1476 if (mHwc1LayerMap.count(hwc1Id) == 0) {
1477 if (receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET) {
1478 ALOGE("addReleaseFences: HWC1 layer %zd doesn't have a"
1479 " matching HWC2 layer, and isn't the framebuffer"
1480 " target", hwc1Id);
1481 }
1482 // Close the framebuffer target release fence since we will use the
1483 // display retire fence instead
1484 if (receivedLayer.releaseFenceFd != -1) {
1485 close(receivedLayer.releaseFenceFd);
1486 }
1487 continue;
1488 }
1489
1490 Layer& layer = *mHwc1LayerMap[hwc1Id];
1491 ALOGV("Adding release fence %d to layer %" PRIu64,
1492 receivedLayer.releaseFenceFd, layer.getId());
1493 layer.addReleaseFence(receivedLayer.releaseFenceFd);
1494 }
1495 }
1496
hasColorTransform() const1497 bool CfHWC2::Display::hasColorTransform() const {
1498 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1499 return mHasColorTransform;
1500 }
1501
hwc1CompositionString(int32_t type)1502 static std::string hwc1CompositionString(int32_t type) {
1503 switch (type) {
1504 case HWC_FRAMEBUFFER: return "Framebuffer";
1505 case HWC_OVERLAY: return "Overlay";
1506 case HWC_BACKGROUND: return "Background";
1507 case HWC_FRAMEBUFFER_TARGET: return "FramebufferTarget";
1508 case HWC_SIDEBAND: return "Sideband";
1509 case HWC_CURSOR_OVERLAY: return "CursorOverlay";
1510 default:
1511 return std::string("Unknown (") + std::to_string(type) + ")";
1512 }
1513 }
1514
hwc1TransformString(int32_t transform)1515 static std::string hwc1TransformString(int32_t transform) {
1516 switch (transform) {
1517 case 0: return "None";
1518 case HWC_TRANSFORM_FLIP_H: return "FlipH";
1519 case HWC_TRANSFORM_FLIP_V: return "FlipV";
1520 case HWC_TRANSFORM_ROT_90: return "Rotate90";
1521 case HWC_TRANSFORM_ROT_180: return "Rotate180";
1522 case HWC_TRANSFORM_ROT_270: return "Rotate270";
1523 case HWC_TRANSFORM_FLIP_H_ROT_90: return "FlipHRotate90";
1524 case HWC_TRANSFORM_FLIP_V_ROT_90: return "FlipVRotate90";
1525 default:
1526 return std::string("Unknown (") + std::to_string(transform) + ")";
1527 }
1528 }
1529
hwc1BlendModeString(int32_t mode)1530 static std::string hwc1BlendModeString(int32_t mode) {
1531 switch (mode) {
1532 case HWC_BLENDING_NONE: return "None";
1533 case HWC_BLENDING_PREMULT: return "Premultiplied";
1534 case HWC_BLENDING_COVERAGE: return "Coverage";
1535 default:
1536 return std::string("Unknown (") + std::to_string(mode) + ")";
1537 }
1538 }
1539
rectString(hwc_rect_t rect)1540 static std::string rectString(hwc_rect_t rect) {
1541 std::stringstream output;
1542 output << "[" << rect.left << ", " << rect.top << ", ";
1543 output << rect.right << ", " << rect.bottom << "]";
1544 return output.str();
1545 }
1546
approximateFloatString(float f)1547 static std::string approximateFloatString(float f) {
1548 if (static_cast<float>(static_cast<int32_t>(f)) == f) {
1549 return std::to_string(static_cast<int32_t>(f));
1550 }
1551 int32_t truncated = static_cast<int32_t>(f * 10);
1552 bool approximate = (static_cast<float>(truncated) != f * 10);
1553 const size_t BUFFER_SIZE = 32;
1554 char buffer[BUFFER_SIZE] = {};
1555 auto bytesWritten = snprintf(buffer, BUFFER_SIZE,
1556 "%s%.1f", approximate ? "~" : "", f);
1557 return std::string(buffer, bytesWritten);
1558 }
1559
frectString(hwc_frect_t frect)1560 static std::string frectString(hwc_frect_t frect) {
1561 std::stringstream output;
1562 output << "[" << approximateFloatString(frect.left) << ", ";
1563 output << approximateFloatString(frect.top) << ", ";
1564 output << approximateFloatString(frect.right) << ", ";
1565 output << approximateFloatString(frect.bottom) << "]";
1566 return output.str();
1567 }
1568
colorString(hwc_color_t color)1569 static std::string colorString(hwc_color_t color) {
1570 std::stringstream output;
1571 output << "RGBA [";
1572 output << static_cast<int32_t>(color.r) << ", ";
1573 output << static_cast<int32_t>(color.g) << ", ";
1574 output << static_cast<int32_t>(color.b) << ", ";
1575 output << static_cast<int32_t>(color.a) << "]";
1576 return output.str();
1577 }
1578
alphaString(float f)1579 static std::string alphaString(float f) {
1580 const size_t BUFFER_SIZE = 8;
1581 char buffer[BUFFER_SIZE] = {};
1582 auto bytesWritten = snprintf(buffer, BUFFER_SIZE, "%.3f", f);
1583 return std::string(buffer, bytesWritten);
1584 }
1585
to_string(const hwc_layer_1_t & hwcLayer,int32_t hwc1MinorVersion)1586 static std::string to_string(const hwc_layer_1_t& hwcLayer,
1587 int32_t hwc1MinorVersion) {
1588 const char* fill = " ";
1589
1590 std::stringstream output;
1591
1592 output << " Composition: " <<
1593 hwc1CompositionString(hwcLayer.compositionType);
1594
1595 if (hwcLayer.compositionType == HWC_BACKGROUND) {
1596 output << " Color: " << colorString(hwcLayer.backgroundColor) << '\n';
1597 } else if (hwcLayer.compositionType == HWC_SIDEBAND) {
1598 output << " Stream: " << hwcLayer.sidebandStream << '\n';
1599 } else {
1600 output << " Buffer: " << hwcLayer.handle << "/" <<
1601 hwcLayer.acquireFenceFd << '\n';
1602 }
1603
1604 output << fill << "Display frame: " << rectString(hwcLayer.displayFrame) <<
1605 '\n';
1606
1607 output << fill << "Source crop: ";
1608 if (hwc1MinorVersion >= 3) {
1609 output << frectString(hwcLayer.sourceCropf) << '\n';
1610 } else {
1611 output << rectString(hwcLayer.sourceCropi) << '\n';
1612 }
1613
1614 output << fill << "Transform: " << hwc1TransformString(hwcLayer.transform);
1615 output << " Blend mode: " << hwc1BlendModeString(hwcLayer.blending);
1616 if (hwcLayer.planeAlpha != 0xFF) {
1617 output << " Alpha: " << alphaString(hwcLayer.planeAlpha / 255.0f);
1618 }
1619 output << '\n';
1620
1621 if (hwcLayer.hints != 0) {
1622 output << fill << "Hints:";
1623 if ((hwcLayer.hints & HWC_HINT_TRIPLE_BUFFER) != 0) {
1624 output << " TripleBuffer";
1625 }
1626 if ((hwcLayer.hints & HWC_HINT_CLEAR_FB) != 0) {
1627 output << " ClearFB";
1628 }
1629 output << '\n';
1630 }
1631
1632 if (hwcLayer.flags != 0) {
1633 output << fill << "Flags:";
1634 if ((hwcLayer.flags & HWC_SKIP_LAYER) != 0) {
1635 output << " SkipLayer";
1636 }
1637 if ((hwcLayer.flags & HWC_IS_CURSOR_LAYER) != 0) {
1638 output << " IsCursorLayer";
1639 }
1640 output << '\n';
1641 }
1642
1643 return output.str();
1644 }
1645
to_string(const hwc_display_contents_1_t & hwcContents,int32_t hwc1MinorVersion)1646 static std::string to_string(const hwc_display_contents_1_t& hwcContents,
1647 int32_t hwc1MinorVersion) {
1648 const char* fill = " ";
1649
1650 std::stringstream output;
1651 output << fill << "Geometry changed: " <<
1652 ((hwcContents.flags & HWC_GEOMETRY_CHANGED) != 0 ? "Y\n" : "N\n");
1653
1654 output << fill << hwcContents.numHwLayers << " Layer" <<
1655 ((hwcContents.numHwLayers == 1) ? "\n" : "s\n");
1656 for (size_t layer = 0; layer < hwcContents.numHwLayers; ++layer) {
1657 output << fill << " Layer " << layer;
1658 output << to_string(hwcContents.hwLayers[layer], hwc1MinorVersion);
1659 }
1660
1661 if (hwcContents.outbuf != nullptr) {
1662 output << fill << "Output buffer: " << hwcContents.outbuf << "/" <<
1663 hwcContents.outbufAcquireFenceFd << '\n';
1664 }
1665
1666 return output.str();
1667 }
1668
dump() const1669 std::string CfHWC2::Display::dump() const {
1670 std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1671
1672 std::stringstream output;
1673
1674 output << " Display " << mId << ": ";
1675 output << to_string(mType) << " ";
1676 output << "HWC1 ID: " << mHwc1Id << " ";
1677 output << "Power mode: " << to_string(mPowerMode) << " ";
1678 output << "Vsync: " << to_string(mVsyncEnabled) << '\n';
1679
1680 output << " Color modes [active]:";
1681 for (const auto& mode : mColorModes) {
1682 if (mode == mActiveColorMode) {
1683 output << " [" << mode << ']';
1684 } else {
1685 output << " " << mode;
1686 }
1687 }
1688 output << '\n';
1689
1690 output << " " << mConfigs.size() << " Config" <<
1691 (mConfigs.size() == 1 ? "" : "s") << " (* active)\n";
1692 for (const auto& config : mConfigs) {
1693 output << (config == mActiveConfig ? " * " : " ");
1694 output << config->toString(true) << '\n';
1695 }
1696
1697 output << " " << mLayers.size() << " Layer" <<
1698 (mLayers.size() == 1 ? "" : "s") << '\n';
1699 for (const auto& layer : mLayers) {
1700 output << layer->dump();
1701 }
1702
1703 output << " Client target: " << mClientTarget.getBuffer() << '\n';
1704
1705 if (mOutputBuffer.getBuffer() != nullptr) {
1706 output << " Output buffer: " << mOutputBuffer.getBuffer() << '\n';
1707 }
1708
1709 if (mHwc1RequestedContents) {
1710 output << " Last requested HWC1 state\n";
1711 output << to_string(*mHwc1RequestedContents, mDevice.mHwc1MinorVersion);
1712 }
1713
1714 return output.str();
1715 }
1716
GetRects(size_t numRects)1717 hwc_rect_t* CfHWC2::Display::GetRects(size_t numRects) {
1718 if (numRects == 0) {
1719 return nullptr;
1720 }
1721
1722 if (numRects > mNumAvailableRects) {
1723 // This should NEVER happen since we calculated how many rects the
1724 // display would need.
1725 ALOGE("Rect allocation failure! SF is likely to crash soon!");
1726 return nullptr;
1727
1728 }
1729 hwc_rect_t* rects = mNextAvailableRect;
1730 mNextAvailableRect += numRects;
1731 mNumAvailableRects -= numRects;
1732 return rects;
1733 }
1734
getDisplayContents()1735 hwc_display_contents_1* CfHWC2::Display::getDisplayContents() {
1736 return mHwc1RequestedContents.get();
1737 }
1738
setAttribute(HWC2::Attribute attribute,int32_t value)1739 void CfHWC2::Display::Config::setAttribute(HWC2::Attribute attribute,
1740 int32_t value) {
1741 mAttributes[attribute] = value;
1742 }
1743
getAttribute(Attribute attribute) const1744 int32_t CfHWC2::Display::Config::getAttribute(Attribute attribute) const {
1745 if (mAttributes.count(attribute) == 0) {
1746 return -1;
1747 }
1748 return mAttributes.at(attribute);
1749 }
1750
setHwc1Id(uint32_t id)1751 void CfHWC2::Display::Config::setHwc1Id(uint32_t id) {
1752 android_color_mode_t colorMode = static_cast<android_color_mode_t>(getAttribute(ColorMode));
1753 mHwc1Ids.emplace(colorMode, id);
1754 }
1755
hasHwc1Id(uint32_t id) const1756 bool CfHWC2::Display::Config::hasHwc1Id(uint32_t id) const {
1757 for (const auto& idPair : mHwc1Ids) {
1758 if (id == idPair.second) {
1759 return true;
1760 }
1761 }
1762 return false;
1763 }
1764
getColorModeForHwc1Id(uint32_t id,android_color_mode_t * outMode) const1765 Error CfHWC2::Display::Config::getColorModeForHwc1Id(
1766 uint32_t id, android_color_mode_t* outMode) const {
1767 for (const auto& idPair : mHwc1Ids) {
1768 if (id == idPair.second) {
1769 *outMode = idPair.first;
1770 return Error::None;
1771 }
1772 }
1773 ALOGE("Unable to find color mode for HWC ID %" PRIu32 " on config %u", id, mId);
1774 return Error::BadParameter;
1775 }
1776
getHwc1IdForColorMode(android_color_mode_t mode,uint32_t * outId) const1777 Error CfHWC2::Display::Config::getHwc1IdForColorMode(android_color_mode_t mode,
1778 uint32_t* outId) const {
1779 for (const auto& idPair : mHwc1Ids) {
1780 if (mode == idPair.first) {
1781 *outId = idPair.second;
1782 return Error::None;
1783 }
1784 }
1785 ALOGE("Unable to find HWC1 ID for color mode %d on config %u", mode, mId);
1786 return Error::BadParameter;
1787 }
1788
merge(const Config & other)1789 bool CfHWC2::Display::Config::merge(const Config& other) {
1790 auto attributes = {HWC2::Attribute::Width, HWC2::Attribute::Height,
1791 HWC2::Attribute::VsyncPeriod, HWC2::Attribute::DpiX,
1792 HWC2::Attribute::DpiY};
1793 for (auto attribute : attributes) {
1794 if (getAttribute(attribute) != other.getAttribute(attribute)) {
1795 return false;
1796 }
1797 }
1798 android_color_mode_t otherColorMode =
1799 static_cast<android_color_mode_t>(other.getAttribute(ColorMode));
1800 if (mHwc1Ids.count(otherColorMode) != 0) {
1801 ALOGE("Attempted to merge two configs (%u and %u) which appear to be "
1802 "identical", mHwc1Ids.at(otherColorMode),
1803 other.mHwc1Ids.at(otherColorMode));
1804 return false;
1805 }
1806 mHwc1Ids.emplace(otherColorMode,
1807 other.mHwc1Ids.at(otherColorMode));
1808 return true;
1809 }
1810
getColorModes() const1811 std::set<android_color_mode_t> CfHWC2::Display::Config::getColorModes() const {
1812 std::set<android_color_mode_t> colorModes;
1813 for (const auto& idPair : mHwc1Ids) {
1814 colorModes.emplace(idPair.first);
1815 }
1816 return colorModes;
1817 }
1818
toString(bool splitLine) const1819 std::string CfHWC2::Display::Config::toString(bool splitLine) const {
1820 std::string output;
1821
1822 const size_t BUFFER_SIZE = 100;
1823 char buffer[BUFFER_SIZE] = {};
1824 auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
1825 "%u x %u", mAttributes.at(HWC2::Attribute::Width),
1826 mAttributes.at(HWC2::Attribute::Height));
1827 output.append(buffer, writtenBytes);
1828
1829 if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
1830 std::memset(buffer, 0, BUFFER_SIZE);
1831 writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
1832 1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
1833 output.append(buffer, writtenBytes);
1834 }
1835
1836 if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
1837 mAttributes.at(HWC2::Attribute::DpiX) != -1) {
1838 std::memset(buffer, 0, BUFFER_SIZE);
1839 writtenBytes =
1840 snprintf(buffer, BUFFER_SIZE, ", DPI: %.1f x %.1f",
1841 static_cast<float>(mAttributes.at(HWC2::Attribute::DpiX)) / 1000.0f,
1842 static_cast<float>(mAttributes.at(HWC2::Attribute::DpiY)) / 1000.0f);
1843 output.append(buffer, writtenBytes);
1844 }
1845
1846 std::memset(buffer, 0, BUFFER_SIZE);
1847 if (splitLine) {
1848 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1849 "\n HWC1 ID/Color transform:");
1850 } else {
1851 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1852 ", HWC1 ID/Color transform:");
1853 }
1854 output.append(buffer, writtenBytes);
1855
1856
1857 for (const auto& id : mHwc1Ids) {
1858 android_color_mode_t colorMode = id.first;
1859 uint32_t hwc1Id = id.second;
1860 std::memset(buffer, 0, BUFFER_SIZE);
1861 if (colorMode == mDisplay.mActiveColorMode) {
1862 writtenBytes = snprintf(buffer, BUFFER_SIZE, " [%u/%d]", hwc1Id,
1863 colorMode);
1864 } else {
1865 writtenBytes = snprintf(buffer, BUFFER_SIZE, " %u/%d", hwc1Id,
1866 colorMode);
1867 }
1868 output.append(buffer, writtenBytes);
1869 }
1870
1871 return output;
1872 }
1873
1874 std::shared_ptr<const CfHWC2::Display::Config>
getConfig(hwc2_config_t configId) const1875 CfHWC2::Display::getConfig(hwc2_config_t configId) const {
1876 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
1877 return nullptr;
1878 }
1879 return mConfigs[configId];
1880 }
1881
populateColorModes()1882 void CfHWC2::Display::populateColorModes() {
1883 mColorModes = mConfigs[0]->getColorModes();
1884 for (const auto& config : mConfigs) {
1885 std::set<android_color_mode_t> intersection;
1886 auto configModes = config->getColorModes();
1887 std::set_intersection(mColorModes.cbegin(), mColorModes.cend(),
1888 configModes.cbegin(), configModes.cend(),
1889 std::inserter(intersection, intersection.begin()));
1890 std::swap(intersection, mColorModes);
1891 }
1892 }
1893
initializeActiveConfig()1894 void CfHWC2::Display::initializeActiveConfig() {
1895 if (mDevice.mHwc1Device->getActiveConfig == nullptr) {
1896 ALOGV("getActiveConfig is null, choosing config 0");
1897 mActiveConfig = mConfigs[0];
1898 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1899 return;
1900 }
1901
1902 auto activeConfig = mDevice.mHwc1Device->getActiveConfig(
1903 mDevice.mHwc1Device, mHwc1Id);
1904
1905 // Some devices startup without an activeConfig:
1906 // We need to set one ourselves.
1907 if (activeConfig == HWC_ERROR) {
1908 ALOGV("There is no active configuration: Picking the first one: 0.");
1909 const int defaultIndex = 0;
1910 mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device, mHwc1Id, defaultIndex);
1911 activeConfig = defaultIndex;
1912 }
1913
1914 for (const auto& config : mConfigs) {
1915 if (config->hasHwc1Id(activeConfig)) {
1916 ALOGE("Setting active config to %d for HWC1 config %u", config->getId(), activeConfig);
1917 mActiveConfig = config;
1918 if (config->getColorModeForHwc1Id(activeConfig, &mActiveColorMode) != Error::None) {
1919 // This should never happen since we checked for the config's presence before
1920 // setting it as active.
1921 ALOGE("Unable to find color mode for active HWC1 config %d", config->getId());
1922 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1923 }
1924 break;
1925 }
1926 }
1927 if (!mActiveConfig) {
1928 ALOGV("Unable to find active HWC1 config %u, defaulting to "
1929 "config 0", activeConfig);
1930 mActiveConfig = mConfigs[0];
1931 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1932 }
1933
1934
1935
1936
1937 }
1938
allocateRequestedContents()1939 void CfHWC2::Display::allocateRequestedContents() {
1940 // What needs to be allocated:
1941 // 1 hwc_display_contents_1_t
1942 // 1 hwc_layer_1_t for each layer
1943 // 1 hwc_rect_t for each layer's surfaceDamage
1944 // 1 hwc_rect_t for each layer's visibleRegion
1945 // 1 hwc_layer_1_t for the framebuffer
1946 // 1 hwc_rect_t for the framebuffer's visibleRegion
1947
1948 // Count # of surfaceDamage
1949 size_t numSurfaceDamages = 0;
1950 for (const auto& layer : mLayers) {
1951 numSurfaceDamages += layer->getNumSurfaceDamages();
1952 }
1953
1954 // Count # of visibleRegions (start at 1 for mandatory framebuffer target
1955 // region)
1956 size_t numVisibleRegion = 1;
1957 for (const auto& layer : mLayers) {
1958 numVisibleRegion += layer->getNumVisibleRegions();
1959 }
1960
1961 size_t numRects = numVisibleRegion + numSurfaceDamages;
1962 auto numLayers = mLayers.size() + 1;
1963 size_t size = sizeof(hwc_display_contents_1_t) +
1964 sizeof(hwc_layer_1_t) * numLayers +
1965 sizeof(hwc_rect_t) * numRects;
1966 auto contents = static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1));
1967 mHwc1RequestedContents.reset(contents);
1968 mNextAvailableRect = reinterpret_cast<hwc_rect_t*>(&contents->hwLayers[numLayers]);
1969 mNumAvailableRects = numRects;
1970 }
1971
assignHwc1LayerIds()1972 void CfHWC2::Display::assignHwc1LayerIds() {
1973 mHwc1LayerMap.clear();
1974 size_t nextHwc1Id = 0;
1975 for (auto& layer : mLayers) {
1976 mHwc1LayerMap[nextHwc1Id] = layer;
1977 layer->setHwc1Id(nextHwc1Id++);
1978 }
1979 }
1980
updateTypeChanges(const hwc_layer_1_t & hwc1Layer,const Layer & layer)1981 void CfHWC2::Display::updateTypeChanges(const hwc_layer_1_t& hwc1Layer,
1982 const Layer& layer) {
1983 auto layerId = layer.getId();
1984 switch (hwc1Layer.compositionType) {
1985 case HWC_FRAMEBUFFER:
1986 if (layer.getCompositionType() != Composition::Client) {
1987 mChanges->addTypeChange(layerId, Composition::Client);
1988 }
1989 break;
1990 case HWC_OVERLAY:
1991 if (layer.getCompositionType() != Composition::Device) {
1992 mChanges->addTypeChange(layerId, Composition::Device);
1993 }
1994 break;
1995 case HWC_BACKGROUND:
1996 ALOGE_IF(layer.getCompositionType() != Composition::SolidColor,
1997 "updateTypeChanges: HWC1 requested BACKGROUND, but HWC2"
1998 " wasn't expecting SolidColor");
1999 break;
2000 case HWC_FRAMEBUFFER_TARGET:
2001 // Do nothing, since it shouldn't be modified by HWC1
2002 break;
2003 case HWC_SIDEBAND:
2004 ALOGE_IF(layer.getCompositionType() != Composition::Sideband,
2005 "updateTypeChanges: HWC1 requested SIDEBAND, but HWC2"
2006 " wasn't expecting Sideband");
2007 break;
2008 case HWC_CURSOR_OVERLAY:
2009 ALOGE_IF(layer.getCompositionType() != Composition::Cursor,
2010 "updateTypeChanges: HWC1 requested CURSOR_OVERLAY, but"
2011 " HWC2 wasn't expecting Cursor");
2012 break;
2013 }
2014 }
2015
updateLayerRequests(const hwc_layer_1_t & hwc1Layer,const Layer & layer)2016 void CfHWC2::Display::updateLayerRequests(
2017 const hwc_layer_1_t& hwc1Layer, const Layer& layer) {
2018 if ((hwc1Layer.hints & HWC_HINT_CLEAR_FB) != 0) {
2019 mChanges->addLayerRequest(layer.getId(),
2020 LayerRequest::ClearClientTarget);
2021 }
2022 }
2023
prepareFramebufferTarget()2024 void CfHWC2::Display::prepareFramebufferTarget() {
2025 // We check that mActiveConfig is valid in Display::prepare
2026 int32_t width = mActiveConfig->getAttribute(Attribute::Width);
2027 int32_t height = mActiveConfig->getAttribute(Attribute::Height);
2028
2029 auto& hwc1Target = mHwc1RequestedContents->hwLayers[mLayers.size()];
2030 hwc1Target.compositionType = HWC_FRAMEBUFFER_TARGET;
2031 hwc1Target.releaseFenceFd = -1;
2032 hwc1Target.hints = 0;
2033 hwc1Target.flags = 0;
2034 hwc1Target.transform = 0;
2035 hwc1Target.blending = HWC_BLENDING_PREMULT;
2036 if (mDevice.getHwc1MinorVersion() < 3) {
2037 hwc1Target.sourceCropi = {0, 0, width, height};
2038 } else {
2039 hwc1Target.sourceCropf = {0.0f, 0.0f, static_cast<float>(width),
2040 static_cast<float>(height)};
2041 }
2042 hwc1Target.displayFrame = {0, 0, width, height};
2043 hwc1Target.planeAlpha = 255;
2044
2045 hwc1Target.visibleRegionScreen.numRects = 1;
2046 hwc_rect_t* rects = GetRects(1);
2047 rects[0].left = 0;
2048 rects[0].top = 0;
2049 rects[0].right = width;
2050 rects[0].bottom = height;
2051 hwc1Target.visibleRegionScreen.rects = rects;
2052
2053 // We will set this to the correct value in set
2054 hwc1Target.acquireFenceFd = -1;
2055 }
2056
2057 // Layer functions
2058
2059 std::atomic<hwc2_layer_t> CfHWC2::Layer::sNextId(1);
2060
Layer(Display & display)2061 CfHWC2::Layer::Layer(Display& display)
2062 : mId(sNextId++),
2063 mDisplay(display),
2064 mBuffer(),
2065 mSurfaceDamage(),
2066 mBlendMode(BlendMode::None),
2067 mColor({0, 0, 0, 0}),
2068 mCompositionType(Composition::Invalid),
2069 mDisplayFrame({0, 0, -1, -1}),
2070 mPlaneAlpha(0.0f),
2071 mSidebandStream(nullptr),
2072 mSourceCrop({0.0f, 0.0f, -1.0f, -1.0f}),
2073 mTransform(Transform::None),
2074 mVisibleRegion(),
2075 mZ(0),
2076 mReleaseFence(),
2077 mHwc1Id(0),
2078 mHasUnsupportedPlaneAlpha(false) {}
2079
operator ()(const std::shared_ptr<Layer> & lhs,const std::shared_ptr<Layer> & rhs) const2080 bool CfHWC2::SortLayersByZ::operator()(const std::shared_ptr<Layer>& lhs,
2081 const std::shared_ptr<Layer>& rhs) const {
2082 return lhs->getZ() < rhs->getZ();
2083 }
2084
setBuffer(buffer_handle_t buffer,int32_t acquireFence)2085 Error CfHWC2::Layer::setBuffer(buffer_handle_t buffer,
2086 int32_t acquireFence) {
2087 ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
2088 mBuffer.setBuffer(buffer);
2089 mBuffer.setFence(acquireFence);
2090 return Error::None;
2091 }
2092
setCursorPosition(int32_t x,int32_t y)2093 Error CfHWC2::Layer::setCursorPosition(int32_t x, int32_t y) {
2094 if (mCompositionType != Composition::Cursor) {
2095 return Error::BadLayer;
2096 }
2097
2098 if (mDisplay.hasChanges()) {
2099 return Error::NotValidated;
2100 }
2101
2102 auto displayId = mDisplay.getHwc1Id();
2103 auto hwc1Device = mDisplay.getDevice().getHwc1Device();
2104 hwc1Device->setCursorPositionAsync(hwc1Device, displayId, x, y);
2105 return Error::None;
2106 }
2107
setSurfaceDamage(hwc_region_t damage)2108 Error CfHWC2::Layer::setSurfaceDamage(hwc_region_t damage) {
2109 // HWC1 supports surface damage starting only with version 1.5.
2110 if (mDisplay.getDevice().mHwc1MinorVersion < 5) {
2111 return Error::None;
2112 }
2113 mSurfaceDamage.resize(damage.numRects);
2114 std::copy_n(damage.rects, damage.numRects, mSurfaceDamage.begin());
2115 return Error::None;
2116 }
2117
2118 // Layer state functions
2119
setBlendMode(BlendMode mode)2120 Error CfHWC2::Layer::setBlendMode(BlendMode mode) {
2121 mBlendMode = mode;
2122 mDisplay.markGeometryChanged();
2123 return Error::None;
2124 }
2125
setColor(hwc_color_t color)2126 Error CfHWC2::Layer::setColor(hwc_color_t color) {
2127 mColor = color;
2128 mDisplay.markGeometryChanged();
2129 return Error::None;
2130 }
2131
setCompositionType(Composition type)2132 Error CfHWC2::Layer::setCompositionType(Composition type) {
2133 mCompositionType = type;
2134 mDisplay.markGeometryChanged();
2135 return Error::None;
2136 }
2137
setDataspace(android_dataspace_t)2138 Error CfHWC2::Layer::setDataspace(android_dataspace_t) {
2139 return Error::None;
2140 }
2141
setDisplayFrame(hwc_rect_t frame)2142 Error CfHWC2::Layer::setDisplayFrame(hwc_rect_t frame) {
2143 mDisplayFrame = frame;
2144 mDisplay.markGeometryChanged();
2145 return Error::None;
2146 }
2147
setPlaneAlpha(float alpha)2148 Error CfHWC2::Layer::setPlaneAlpha(float alpha) {
2149 mPlaneAlpha = alpha;
2150 mDisplay.markGeometryChanged();
2151 return Error::None;
2152 }
2153
setSidebandStream(const native_handle_t * stream)2154 Error CfHWC2::Layer::setSidebandStream(const native_handle_t* stream) {
2155 mSidebandStream = stream;
2156 mDisplay.markGeometryChanged();
2157 return Error::None;
2158 }
2159
setSourceCrop(hwc_frect_t crop)2160 Error CfHWC2::Layer::setSourceCrop(hwc_frect_t crop) {
2161 mSourceCrop = crop;
2162 mDisplay.markGeometryChanged();
2163 return Error::None;
2164 }
2165
setTransform(Transform transform)2166 Error CfHWC2::Layer::setTransform(Transform transform) {
2167 mTransform = transform;
2168 mDisplay.markGeometryChanged();
2169 return Error::None;
2170 }
2171
compareRects(const hwc_rect_t & rect1,const hwc_rect_t & rect2)2172 static bool compareRects(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
2173 return rect1.left == rect2.left &&
2174 rect1.right == rect2.right &&
2175 rect1.top == rect2.top &&
2176 rect1.bottom == rect2.bottom;
2177 }
2178
setVisibleRegion(hwc_region_t visible)2179 Error CfHWC2::Layer::setVisibleRegion(hwc_region_t visible) {
2180 if ((getNumVisibleRegions() != visible.numRects) ||
2181 !std::equal(mVisibleRegion.begin(), mVisibleRegion.end(), visible.rects,
2182 compareRects)) {
2183 mVisibleRegion.resize(visible.numRects);
2184 std::copy_n(visible.rects, visible.numRects, mVisibleRegion.begin());
2185 mDisplay.markGeometryChanged();
2186 }
2187 return Error::None;
2188 }
2189
setZ(uint32_t z)2190 Error CfHWC2::Layer::setZ(uint32_t z) {
2191 mZ = z;
2192 return Error::None;
2193 }
2194
addReleaseFence(int fenceFd)2195 void CfHWC2::Layer::addReleaseFence(int fenceFd) {
2196 ALOGV("addReleaseFence %d to layer %" PRIu64, fenceFd, mId);
2197 mReleaseFence.add(fenceFd);
2198 }
2199
getReleaseFence() const2200 const sp<MiniFence>& CfHWC2::Layer::getReleaseFence() const {
2201 return mReleaseFence.get();
2202 }
2203
applyState(hwc_layer_1_t & hwc1Layer)2204 void CfHWC2::Layer::applyState(hwc_layer_1_t& hwc1Layer) {
2205 applyCommonState(hwc1Layer);
2206 applyCompositionType(hwc1Layer);
2207 switch (mCompositionType) {
2208 case Composition::SolidColor : applySolidColorState(hwc1Layer); break;
2209 case Composition::Sideband : applySidebandState(hwc1Layer); break;
2210 default: applyBufferState(hwc1Layer); break;
2211 }
2212 }
2213
regionStrings(const std::vector<hwc_rect_t> & visibleRegion,const std::vector<hwc_rect_t> & surfaceDamage)2214 static std::string regionStrings(const std::vector<hwc_rect_t>& visibleRegion,
2215 const std::vector<hwc_rect_t>& surfaceDamage) {
2216 std::string regions;
2217 regions += " Visible Region";
2218 regions.resize(40, ' ');
2219 regions += "Surface Damage\n";
2220
2221 size_t numPrinted = 0;
2222 size_t maxSize = std::max(visibleRegion.size(), surfaceDamage.size());
2223 while (numPrinted < maxSize) {
2224 std::string line(" ");
2225 if (visibleRegion.empty() && numPrinted == 0) {
2226 line += "None";
2227 } else if (numPrinted < visibleRegion.size()) {
2228 line += rectString(visibleRegion[numPrinted]);
2229 }
2230 line.resize(40, ' ');
2231 if (surfaceDamage.empty() && numPrinted == 0) {
2232 line += "None";
2233 } else if (numPrinted < surfaceDamage.size()) {
2234 line += rectString(surfaceDamage[numPrinted]);
2235 }
2236 line += '\n';
2237 regions += line;
2238 ++numPrinted;
2239 }
2240 return regions;
2241 }
2242
dump() const2243 std::string CfHWC2::Layer::dump() const {
2244 std::stringstream output;
2245 const char* fill = " ";
2246
2247 output << fill << to_string(mCompositionType);
2248 output << " Layer HWC2/1: " << mId << "/" << mHwc1Id << " ";
2249 output << "Z: " << mZ;
2250 if (mCompositionType == HWC2::Composition::SolidColor) {
2251 output << " " << colorString(mColor);
2252 } else if (mCompositionType == HWC2::Composition::Sideband) {
2253 output << " Handle: " << mSidebandStream << '\n';
2254 } else {
2255 output << " Buffer: " << mBuffer.getBuffer() << '\n';
2256 output << fill << " Display frame [LTRB]: " <<
2257 rectString(mDisplayFrame) << '\n';
2258 output << fill << " Source crop: " <<
2259 frectString(mSourceCrop) << '\n';
2260 output << fill << " Transform: " << to_string(mTransform);
2261 output << " Blend mode: " << to_string(mBlendMode);
2262 if (mPlaneAlpha != 1.0f) {
2263 output << " Alpha: " <<
2264 alphaString(mPlaneAlpha) << '\n';
2265 } else {
2266 output << '\n';
2267 }
2268 output << regionStrings(mVisibleRegion, mSurfaceDamage);
2269 }
2270 return output.str();
2271 }
2272
getHwc1Blending(HWC2::BlendMode blendMode)2273 static int getHwc1Blending(HWC2::BlendMode blendMode) {
2274 switch (blendMode) {
2275 case BlendMode::Coverage: return HWC_BLENDING_COVERAGE;
2276 case BlendMode::Premultiplied: return HWC_BLENDING_PREMULT;
2277 default: return HWC_BLENDING_NONE;
2278 }
2279 }
2280
applyCommonState(hwc_layer_1_t & hwc1Layer)2281 void CfHWC2::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer) {
2282 auto minorVersion = mDisplay.getDevice().getHwc1MinorVersion();
2283 hwc1Layer.blending = getHwc1Blending(mBlendMode);
2284 hwc1Layer.displayFrame = mDisplayFrame;
2285
2286 auto pendingAlpha = mPlaneAlpha;
2287 if (minorVersion < 2) {
2288 mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f;
2289 } else {
2290 hwc1Layer.planeAlpha =
2291 static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f);
2292 }
2293
2294 if (minorVersion < 3) {
2295 auto pending = mSourceCrop;
2296 hwc1Layer.sourceCropi.left =
2297 static_cast<int32_t>(std::ceil(pending.left));
2298 hwc1Layer.sourceCropi.top =
2299 static_cast<int32_t>(std::ceil(pending.top));
2300 hwc1Layer.sourceCropi.right =
2301 static_cast<int32_t>(std::floor(pending.right));
2302 hwc1Layer.sourceCropi.bottom =
2303 static_cast<int32_t>(std::floor(pending.bottom));
2304 } else {
2305 hwc1Layer.sourceCropf = mSourceCrop;
2306 }
2307
2308 hwc1Layer.transform = static_cast<uint32_t>(mTransform);
2309
2310 auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen;
2311 hwc1VisibleRegion.numRects = mVisibleRegion.size();
2312 hwc_rect_t* rects = mDisplay.GetRects(hwc1VisibleRegion.numRects);
2313 hwc1VisibleRegion.rects = rects;
2314 for (size_t i = 0; i < mVisibleRegion.size(); i++) {
2315 rects[i] = mVisibleRegion[i];
2316 }
2317 }
2318
applySolidColorState(hwc_layer_1_t & hwc1Layer)2319 void CfHWC2::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer) {
2320 // If the device does not support background color it is likely to make
2321 // assumption regarding backgroundColor and handle (both fields occupy
2322 // the same location in hwc_layer_1_t union).
2323 // To not confuse these devices we don't set background color and we
2324 // make sure handle is a null pointer.
2325 if (hasUnsupportedBackgroundColor()) {
2326 hwc1Layer.handle = nullptr;
2327 } else {
2328 hwc1Layer.backgroundColor = mColor;
2329 }
2330 }
2331
applySidebandState(hwc_layer_1_t & hwc1Layer)2332 void CfHWC2::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer) {
2333 hwc1Layer.sidebandStream = mSidebandStream;
2334 }
2335
applyBufferState(hwc_layer_1_t & hwc1Layer)2336 void CfHWC2::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer) {
2337 hwc1Layer.handle = mBuffer.getBuffer();
2338 hwc1Layer.acquireFenceFd = mBuffer.getFence();
2339 }
2340
applyCompositionType(hwc_layer_1_t & hwc1Layer)2341 void CfHWC2::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer) {
2342 // HWC1 never supports color transforms or dataspaces and only sometimes
2343 // supports plane alpha (depending on the version). These require us to drop
2344 // some or all layers to client composition.
2345 if (mHasUnsupportedPlaneAlpha || mDisplay.hasColorTransform() ||
2346 hasUnsupportedBackgroundColor()) {
2347 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2348 hwc1Layer.flags = HWC_SKIP_LAYER;
2349 return;
2350 }
2351
2352 hwc1Layer.flags = 0;
2353 switch (mCompositionType) {
2354 case Composition::Client:
2355 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2356 hwc1Layer.flags |= HWC_SKIP_LAYER;
2357 break;
2358 case Composition::Device:
2359 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2360 break;
2361 case Composition::SolidColor:
2362 // In theory the following line should work, but since the HWC1
2363 // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
2364 // devices may not work correctly. To be on the safe side, we
2365 // fall back to client composition.
2366 //
2367 // hwc1Layer.compositionType = HWC_BACKGROUND;
2368 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2369 hwc1Layer.flags |= HWC_SKIP_LAYER;
2370 break;
2371 case Composition::Cursor:
2372 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2373 if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
2374 hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
2375 }
2376 break;
2377 case Composition::Sideband:
2378 if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
2379 hwc1Layer.compositionType = HWC_SIDEBAND;
2380 } else {
2381 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2382 hwc1Layer.flags |= HWC_SKIP_LAYER;
2383 }
2384 break;
2385 default:
2386 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2387 hwc1Layer.flags |= HWC_SKIP_LAYER;
2388 break;
2389 }
2390 ALOGV("Layer %" PRIu64 " %s set to %d", mId,
2391 to_string(mCompositionType).c_str(),
2392 hwc1Layer.compositionType);
2393 ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, " and skipping");
2394 }
2395
2396 // Adapter helpers
2397
populateCapabilities()2398 void CfHWC2::populateCapabilities() {
2399 if (mHwc1MinorVersion >= 3U) {
2400 int supportedTypes = 0;
2401 auto result = mHwc1Device->query(mHwc1Device,
2402 HWC_DISPLAY_TYPES_SUPPORTED, &supportedTypes);
2403 if ((result == 0) && ((supportedTypes & HWC_DISPLAY_VIRTUAL_BIT) != 0)) {
2404 ALOGI("Found support for HWC virtual displays");
2405 mHwc1SupportsVirtualDisplays = true;
2406 }
2407 }
2408 if (mHwc1MinorVersion >= 4U) {
2409 mCapabilities.insert(Capability::SidebandStream);
2410 }
2411
2412 // Check for HWC background color layer support.
2413 if (mHwc1MinorVersion >= 1U) {
2414 int backgroundColorSupported = 0;
2415 auto result = mHwc1Device->query(mHwc1Device,
2416 HWC_BACKGROUND_LAYER_SUPPORTED,
2417 &backgroundColorSupported);
2418 if ((result == 0) && (backgroundColorSupported == 1)) {
2419 ALOGV("Found support for HWC background color");
2420 mHwc1SupportsBackgroundColor = true;
2421 }
2422 }
2423
2424 // Some devices might have HWC1 retire fences that accurately emulate
2425 // HWC2 present fences when they are deferred, but it's not very reliable.
2426 // To be safe, we indicate PresentFenceIsNotReliable for all HWC1 devices.
2427 //mCapabilities.insert(Capability::PresentFenceIsNotReliable);
2428 }
2429
getDisplay(hwc2_display_t id)2430 CfHWC2::Display* CfHWC2::getDisplay(hwc2_display_t id) {
2431 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2432
2433 auto display = mDisplays.find(id);
2434 if (display == mDisplays.end()) {
2435 return nullptr;
2436 }
2437
2438 return display->second.get();
2439 }
2440
getLayer(hwc2_display_t displayId,hwc2_layer_t layerId)2441 std::tuple<CfHWC2::Layer*, Error> CfHWC2::getLayer(
2442 hwc2_display_t displayId, hwc2_layer_t layerId) {
2443 auto display = getDisplay(displayId);
2444 if (!display) {
2445 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
2446 }
2447
2448 auto layerEntry = mLayers.find(layerId);
2449 if (layerEntry == mLayers.end()) {
2450 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2451 }
2452
2453 auto layer = layerEntry->second;
2454 if (layer->getDisplay().getId() != displayId) {
2455 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2456 }
2457 return std::make_tuple(layer.get(), Error::None);
2458 }
2459
populatePrimary()2460 void CfHWC2::populatePrimary() {
2461 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2462
2463 auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
2464 mHwc1DisplayMap[HWC_DISPLAY_PRIMARY] = display->getId();
2465 display->setHwc1Id(HWC_DISPLAY_PRIMARY);
2466 display->populateConfigs();
2467 mDisplays.emplace(display->getId(), std::move(display));
2468 }
2469
prepareAllDisplays()2470 bool CfHWC2::prepareAllDisplays() {
2471 ATRACE_CALL();
2472
2473 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2474
2475 for (const auto& displayPair : mDisplays) {
2476 auto& display = displayPair.second;
2477 if (!display->prepare()) {
2478 return false;
2479 }
2480 }
2481
2482 if (mHwc1DisplayMap.count(HWC_DISPLAY_PRIMARY) == 0) {
2483 ALOGE("prepareAllDisplays: Unable to find primary HWC1 display");
2484 return false;
2485 }
2486
2487 // Build an array of hwc_display_contents_1 to call prepare() on HWC1.
2488 mHwc1Contents.clear();
2489
2490 // Always push the primary display
2491 auto primaryDisplayId = mHwc1DisplayMap[HWC_DISPLAY_PRIMARY];
2492 auto& primaryDisplay = mDisplays[primaryDisplayId];
2493 mHwc1Contents.push_back(primaryDisplay->getDisplayContents());
2494
2495 // Push the external display, if present
2496 if (mHwc1DisplayMap.count(HWC_DISPLAY_EXTERNAL) != 0) {
2497 auto externalDisplayId = mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL];
2498 auto& externalDisplay = mDisplays[externalDisplayId];
2499 mHwc1Contents.push_back(externalDisplay->getDisplayContents());
2500 } else {
2501 // Even if an external display isn't present, we still need to send
2502 // at least two displays down to HWC1
2503 mHwc1Contents.push_back(nullptr);
2504 }
2505
2506 // Push the hardware virtual display, if supported and present
2507 if (mHwc1MinorVersion >= 3) {
2508 if (mHwc1DisplayMap.count(HWC_DISPLAY_VIRTUAL) != 0) {
2509 auto virtualDisplayId = mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL];
2510 auto& virtualDisplay = mDisplays[virtualDisplayId];
2511 mHwc1Contents.push_back(virtualDisplay->getDisplayContents());
2512 } else {
2513 mHwc1Contents.push_back(nullptr);
2514 }
2515 }
2516
2517 for (auto& displayContents : mHwc1Contents) {
2518 if (!displayContents) {
2519 continue;
2520 }
2521
2522 ALOGV("Display %zd layers:", mHwc1Contents.size() - 1);
2523 for (size_t l = 0; l < displayContents->numHwLayers; ++l) {
2524 auto& layer = displayContents->hwLayers[l];
2525 ALOGV(" %zd: %d", l, layer.compositionType);
2526 }
2527 }
2528
2529 ALOGV("Calling HWC1 prepare");
2530 {
2531 ATRACE_NAME("HWC1 prepare");
2532 mHwc1Device->prepare(mHwc1Device, mHwc1Contents.size(),
2533 mHwc1Contents.data());
2534 }
2535
2536 for (size_t c = 0; c < mHwc1Contents.size(); ++c) {
2537 auto& contents = mHwc1Contents[c];
2538 if (!contents) {
2539 continue;
2540 }
2541 ALOGV("Display %zd layers:", c);
2542 for (size_t l = 0; l < contents->numHwLayers; ++l) {
2543 ALOGV(" %zd: %d", l, contents->hwLayers[l].compositionType);
2544 }
2545 }
2546
2547 // Return the received contents to their respective displays
2548 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2549 if (mHwc1Contents[hwc1Id] == nullptr) {
2550 continue;
2551 }
2552
2553 auto displayId = mHwc1DisplayMap[hwc1Id];
2554 auto& display = mDisplays[displayId];
2555 display->generateChanges();
2556 }
2557
2558 return true;
2559 }
2560
dumpHWC1Message(hwc_composer_device_1 * device,size_t numDisplays,hwc_display_contents_1_t ** displays)2561 void dumpHWC1Message(hwc_composer_device_1* device, size_t numDisplays,
2562 hwc_display_contents_1_t** displays) {
2563 ALOGV("*****************************");
2564 size_t displayId = 0;
2565 while (displayId < numDisplays) {
2566 hwc_display_contents_1_t* display = displays[displayId];
2567
2568 ALOGV("hwc_display_contents_1_t[%zu] @0x%p", displayId, display);
2569 if (display == nullptr) {
2570 displayId++;
2571 continue;
2572 }
2573 ALOGV(" retirefd:0x%08x", display->retireFenceFd);
2574 ALOGV(" outbuf :0x%p", display->outbuf);
2575 ALOGV(" outbuffd:0x%08x", display->outbufAcquireFenceFd);
2576 ALOGV(" flags :0x%08x", display->flags);
2577 for(size_t layerId=0 ; layerId < display->numHwLayers ; layerId++) {
2578 hwc_layer_1_t& layer = display->hwLayers[layerId];
2579 ALOGV(" Layer[%zu]:", layerId);
2580 ALOGV(" composition : 0x%08x", layer.compositionType);
2581 ALOGV(" hints : 0x%08x", layer.hints);
2582 ALOGV(" flags : 0x%08x", layer.flags);
2583 ALOGV(" handle : 0x%p", layer.handle);
2584 ALOGV(" transform : 0x%08x", layer.transform);
2585 ALOGV(" blending : 0x%08x", layer.blending);
2586 ALOGV(" sourceCropf : %f, %f, %f, %f",
2587 layer.sourceCropf.left,
2588 layer.sourceCropf.top,
2589 layer.sourceCropf.right,
2590 layer.sourceCropf.bottom);
2591 ALOGV(" displayFrame : %d, %d, %d, %d",
2592 layer.displayFrame.left,
2593 layer.displayFrame.left,
2594 layer.displayFrame.left,
2595 layer.displayFrame.left);
2596 hwc_region_t& visReg = layer.visibleRegionScreen;
2597 ALOGV(" visibleRegionScreen: #0x%08zx[@0x%p]",
2598 visReg.numRects,
2599 visReg.rects);
2600 for (size_t visRegId=0; visRegId < visReg.numRects ; visRegId++) {
2601 if (layer.visibleRegionScreen.rects == nullptr) {
2602 ALOGV(" null");
2603 } else {
2604 ALOGV(" visibleRegionScreen[%zu] %d, %d, %d, %d",
2605 visRegId,
2606 visReg.rects[visRegId].left,
2607 visReg.rects[visRegId].top,
2608 visReg.rects[visRegId].right,
2609 visReg.rects[visRegId].bottom);
2610 }
2611 }
2612 ALOGV(" acquireFenceFd : 0x%08x", layer.acquireFenceFd);
2613 ALOGV(" releaseFenceFd : 0x%08x", layer.releaseFenceFd);
2614 ALOGV(" planeAlpha : 0x%08x", layer.planeAlpha);
2615 if (getMinorVersion(device) < 5)
2616 continue;
2617 ALOGV(" surfaceDamage : #0x%08zx[@0x%p]",
2618 layer.surfaceDamage.numRects,
2619 layer.surfaceDamage.rects);
2620 for (size_t sdId=0; sdId < layer.surfaceDamage.numRects ; sdId++) {
2621 if (layer.surfaceDamage.rects == nullptr) {
2622 ALOGV(" null");
2623 } else {
2624 ALOGV(" surfaceDamage[%zu] %d, %d, %d, %d",
2625 sdId,
2626 layer.surfaceDamage.rects[sdId].left,
2627 layer.surfaceDamage.rects[sdId].top,
2628 layer.surfaceDamage.rects[sdId].right,
2629 layer.surfaceDamage.rects[sdId].bottom);
2630 }
2631 }
2632 }
2633 displayId++;
2634 }
2635 ALOGV("-----------------------------");
2636 }
2637
setAllDisplays()2638 Error CfHWC2::setAllDisplays() {
2639 ATRACE_CALL();
2640
2641 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2642
2643 // Make sure we're ready to validate
2644 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2645 if (mHwc1Contents[hwc1Id] == nullptr) {
2646 continue;
2647 }
2648
2649 auto displayId = mHwc1DisplayMap[hwc1Id];
2650 auto& display = mDisplays[displayId];
2651 Error error = display->set(*mHwc1Contents[hwc1Id]);
2652 if (error != Error::None) {
2653 ALOGE("setAllDisplays: Failed to set display %zd: %s", hwc1Id,
2654 to_string(error).c_str());
2655 return error;
2656 }
2657 }
2658
2659 ALOGV("Calling HWC1 set");
2660 {
2661 ATRACE_NAME("HWC1 set");
2662 //dumpHWC1Message(mHwc1Device, mHwc1Contents.size(), mHwc1Contents.data());
2663 mHwc1Device->set(mHwc1Device, mHwc1Contents.size(),
2664 mHwc1Contents.data());
2665 }
2666
2667 // Add retire and release fences
2668 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2669 if (mHwc1Contents[hwc1Id] == nullptr) {
2670 continue;
2671 }
2672
2673 auto displayId = mHwc1DisplayMap[hwc1Id];
2674 auto& display = mDisplays[displayId];
2675 auto retireFenceFd = mHwc1Contents[hwc1Id]->retireFenceFd;
2676 ALOGV("setAllDisplays: Adding retire fence %d to display %zd",
2677 retireFenceFd, hwc1Id);
2678 display->addRetireFence(mHwc1Contents[hwc1Id]->retireFenceFd);
2679 display->addReleaseFences(*mHwc1Contents[hwc1Id]);
2680 }
2681
2682 return Error::None;
2683 }
2684
hwc1Invalidate()2685 void CfHWC2::hwc1Invalidate() {
2686 ALOGV("Received hwc1Invalidate");
2687
2688 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2689
2690 // If the HWC2-side callback hasn't been registered yet, buffer this until
2691 // it is registered.
2692 if (mCallbacks.count(Callback::Refresh) == 0) {
2693 mHasPendingInvalidate = true;
2694 return;
2695 }
2696
2697 const auto& callbackInfo = mCallbacks[Callback::Refresh];
2698 std::vector<hwc2_display_t> displays;
2699 for (const auto& displayPair : mDisplays) {
2700 displays.emplace_back(displayPair.first);
2701 }
2702
2703 // Call back without the state lock held.
2704 lock.unlock();
2705
2706 auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(callbackInfo.pointer);
2707 for (auto display : displays) {
2708 refresh(callbackInfo.data, display);
2709 }
2710 }
2711
hwc1Vsync(int hwc1DisplayId,int64_t timestamp)2712 void CfHWC2::hwc1Vsync(int hwc1DisplayId, int64_t timestamp) {
2713 ALOGV("Received hwc1Vsync(%d, %" PRId64 ")", hwc1DisplayId, timestamp);
2714
2715 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2716
2717 // If the HWC2-side callback hasn't been registered yet, buffer this until
2718 // it is registered.
2719 if (mCallbacks.count(Callback::Vsync) == 0) {
2720 mPendingVsyncs.emplace_back(hwc1DisplayId, timestamp);
2721 return;
2722 }
2723
2724 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2725 ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", hwc1DisplayId);
2726 return;
2727 }
2728
2729 const auto& callbackInfo = mCallbacks[Callback::Vsync];
2730 auto displayId = mHwc1DisplayMap[hwc1DisplayId];
2731
2732 // Call back without the state lock held.
2733 lock.unlock();
2734
2735 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
2736 vsync(callbackInfo.data, displayId, timestamp);
2737 }
2738
hwc1Hotplug(int hwc1DisplayId,int connected)2739 void CfHWC2::hwc1Hotplug(int hwc1DisplayId, int connected) {
2740 ALOGV("Received hwc1Hotplug(%d, %d)", hwc1DisplayId, connected);
2741
2742 if (hwc1DisplayId != HWC_DISPLAY_EXTERNAL) {
2743 ALOGE("hwc1Hotplug: Received hotplug for non-external display");
2744 return;
2745 }
2746
2747 std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2748
2749 hwc2_display_t displayId = UINT64_MAX;
2750 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2751 if (connected == 0) {
2752 ALOGW("hwc1Hotplug: Received disconnect for unconnected display");
2753 return;
2754 }
2755
2756 // Create a new display on connect
2757 auto display = std::make_shared<CfHWC2::Display>(*this,
2758 HWC2::DisplayType::Physical);
2759 display->setHwc1Id(HWC_DISPLAY_EXTERNAL);
2760 display->populateConfigs();
2761 displayId = display->getId();
2762 mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL] = displayId;
2763 mDisplays.emplace(displayId, std::move(display));
2764 } else {
2765 if (connected != 0) {
2766 ALOGW("hwc1Hotplug: Received connect for previously connected "
2767 "display");
2768 return;
2769 }
2770
2771 // Disconnect an existing display
2772 displayId = mHwc1DisplayMap[hwc1DisplayId];
2773 mHwc1DisplayMap.erase(HWC_DISPLAY_EXTERNAL);
2774 mDisplays.erase(displayId);
2775 }
2776
2777 // If the HWC2-side callback hasn't been registered yet, buffer this until
2778 // it is registered
2779 if (mCallbacks.count(Callback::Hotplug) == 0) {
2780 mPendingHotplugs.emplace_back(hwc1DisplayId, connected);
2781 return;
2782 }
2783
2784 const auto& callbackInfo = mCallbacks[Callback::Hotplug];
2785
2786 // Call back without the state lock held
2787 lock.unlock();
2788
2789 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(callbackInfo.pointer);
2790 auto hwc2Connected = (connected == 0) ?
2791 HWC2::Connection::Disconnected : HWC2::Connection::Connected;
2792 hotplug(callbackInfo.data, displayId, static_cast<int32_t>(hwc2Connected));
2793 }
2794
hwc2DevOpen(const struct hw_module_t * module,const char * name,struct hw_device_t ** dev)2795 static int hwc2DevOpen(const struct hw_module_t *module, const char *name,
2796 struct hw_device_t **dev) {
2797 ALOGV("%s()", __FUNCTION__);
2798 if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
2799 ALOGE("Invalid module name- %s", name);
2800 return -EINVAL;
2801 }
2802
2803 std::unique_ptr<cuttlefish::ScreenView> screen_view(new cuttlefish::VsocketScreenView());
2804 if (!screen_view) {
2805 ALOGE("Failed to instantiate screen view");
2806 return -1;
2807 }
2808
2809 hw_device_t* device;
2810 int error = cuttlefish::cvd_hwc_open(std::move(screen_view), module, name, &device);
2811 if (error) {
2812 ALOGE("failed to open hwcomposer device: %s", strerror(-error));
2813 return -1;
2814 }
2815
2816 int major = (device->version >> 24) & 0xf;
2817 ALOGV("%s(): major=%d", __FUNCTION__, major);
2818 if (major < 2) {
2819 CfHWC2* hwc2 = new CfHWC2(std::move(reinterpret_cast<hwc_composer_device_1*>(device)));
2820 hwc2->common.module = const_cast<hw_module_t *>(module);
2821 *dev = &hwc2->common;
2822 } else {
2823 *dev = device;
2824 }
2825
2826 return 0;
2827 }
2828
2829 } // namespace android
2830
2831 static struct hw_module_methods_t hwc2_module_methods = {
2832 .open = android::hwc2DevOpen
2833 };
2834
2835 hw_module_t HAL_MODULE_INFO_SYM = {
2836 .tag = HARDWARE_MODULE_TAG,
2837 .version_major = 2,
2838 .version_minor = 0,
2839 .id = HWC_HARDWARE_MODULE_ID,
2840 .name = "CuttleFish HWC2 module",
2841 .author = "Google",
2842 .methods = &hwc2_module_methods,
2843 .dso = NULL,
2844 .reserved = {0},
2845 };
2846