1 /*
2 * Copyright 2018 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 "EmuHWC2.h"
18 //#define LOG_NDEBUG 0
19 //#define LOG_NNDEBUG 0
20 #undef LOG_TAG
21 #define LOG_TAG "EmuHWC2"
22
23 #include <errno.h>
24 #include <cutils/properties.h>
25 #include <log/log.h>
26 #include <sync/sync.h>
27
28 #include <EGL/egl.h>
29 #include <EGL/eglext.h>
30 #include <ui/GraphicBuffer.h>
31 #include <ui/GraphicBufferAllocator.h>
32
33 #include "../egl/goldfish_sync.h"
34
35 #include "ThreadInfo.h"
36
37 #if defined(LOG_NNDEBUG) && LOG_NNDEBUG == 0
38 #define ALOGVV ALOGV
39 #else
40 #define ALOGVV(...) ((void)0)
41 #endif
42
43 template <typename PFN, typename T>
asFP(T function)44 static hwc2_function_pointer_t asFP(T function)
45 {
46 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
47 return reinterpret_cast<hwc2_function_pointer_t>(function);
48 }
49
50 static std::unique_ptr<HostConnection> sHostCon;
51
createOrGetHostConnection()52 static HostConnection* createOrGetHostConnection() {
53 if (!sHostCon) {
54 sHostCon = HostConnection::createUnique();
55 }
56 return sHostCon.get();
57 }
58
59 #define DEFINE_AND_VALIDATE_HOST_CONNECTION \
60 HostConnection *hostCon = createOrGetHostConnection(); \
61 if (!hostCon) { \
62 ALOGE("EmuHWC2: Failed to get host connection\n"); \
63 return Error::NoResources; \
64 } \
65 ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
66 if (!rcEnc) { \
67 ALOGE("EmuHWC2: Failed to get renderControl encoder context\n"); \
68 return Error::NoResources; \
69 }
70
71 using namespace HWC2;
72
73 namespace android {
74
EmuHWC2()75 EmuHWC2::EmuHWC2()
76 : mStateMutex()
77 {
78 common.tag = HARDWARE_DEVICE_TAG;
79 common.version = HWC_DEVICE_API_VERSION_2_0;
80 common.close = closeHook;
81 getCapabilities = getCapabilitiesHook;
82 getFunction = getFunctionHook;
83 populateCapabilities();
84 initDisplayParameters();
85 }
86
initDisplayParameters()87 Error EmuHWC2::initDisplayParameters() {
88 DEFINE_AND_VALIDATE_HOST_CONNECTION
89 hostCon->lock();
90
91 mDisplayWidth = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
92 mDisplayHeight = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
93 mDisplayDpiX = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
94 mDisplayDpiY = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
95
96 hostCon->unlock();
97
98 return HWC2::Error::None;
99 }
100
doGetCapabilities(uint32_t * outCount,int32_t * outCapabilities)101 void EmuHWC2::doGetCapabilities(uint32_t* outCount, int32_t* outCapabilities) {
102 if (outCapabilities == nullptr) {
103 *outCount = mCapabilities.size();
104 return;
105 }
106
107 auto capabilityIter = mCapabilities.cbegin();
108 for (size_t i = 0; i < *outCount; ++i) {
109 if (capabilityIter == mCapabilities.cend()) {
110 return;
111 }
112 outCapabilities[i] = static_cast<int32_t>(*capabilityIter);
113 ++capabilityIter;
114 }
115 }
116
doGetFunction(FunctionDescriptor descriptor)117 hwc2_function_pointer_t EmuHWC2::doGetFunction(
118 FunctionDescriptor descriptor) {
119 switch(descriptor) {
120 case FunctionDescriptor::CreateVirtualDisplay:
121 return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
122 createVirtualDisplayHook);
123 case FunctionDescriptor::DestroyVirtualDisplay:
124 return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
125 destroyVirtualDisplayHook);
126 case FunctionDescriptor::Dump:
127 return asFP<HWC2_PFN_DUMP>(dumpHook);
128 case FunctionDescriptor::GetMaxVirtualDisplayCount:
129 return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
130 getMaxVirtualDisplayCountHook);
131 case FunctionDescriptor::RegisterCallback:
132 return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
133
134 // Display functions
135 case FunctionDescriptor::AcceptDisplayChanges:
136 return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
137 displayHook<decltype(&Display::acceptChanges),
138 &Display::acceptChanges>);
139 case FunctionDescriptor::CreateLayer:
140 return asFP<HWC2_PFN_CREATE_LAYER>(
141 displayHook<decltype(&Display::createLayer),
142 &Display::createLayer, hwc2_layer_t*>);
143 case FunctionDescriptor::DestroyLayer:
144 return asFP<HWC2_PFN_DESTROY_LAYER>(
145 displayHook<decltype(&Display::destroyLayer),
146 &Display::destroyLayer, hwc2_layer_t>);
147 case FunctionDescriptor::GetActiveConfig:
148 return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
149 displayHook<decltype(&Display::getActiveConfig),
150 &Display::getActiveConfig, hwc2_config_t*>);
151 case FunctionDescriptor::GetChangedCompositionTypes:
152 return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
153 displayHook<decltype(&Display::getChangedCompositionTypes),
154 &Display::getChangedCompositionTypes, uint32_t*,
155 hwc2_layer_t*, int32_t*>);
156 case FunctionDescriptor::GetColorModes:
157 return asFP<HWC2_PFN_GET_COLOR_MODES>(
158 displayHook<decltype(&Display::getColorModes),
159 &Display::getColorModes, uint32_t*, int32_t*>);
160 case FunctionDescriptor::GetDisplayAttribute:
161 return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
162 displayHook<decltype(&Display::getDisplayAttribute),
163 &Display::getDisplayAttribute, hwc2_config_t,
164 int32_t, int32_t*>);
165 case FunctionDescriptor::GetDisplayConfigs:
166 return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
167 displayHook<decltype(&Display::getConfigs),
168 &Display::getConfigs, uint32_t*, hwc2_config_t*>);
169 case FunctionDescriptor::GetDisplayName:
170 return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
171 displayHook<decltype(&Display::getName),
172 &Display::getName, uint32_t*, char*>);
173 case FunctionDescriptor::GetDisplayRequests:
174 return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
175 displayHook<decltype(&Display::getRequests),
176 &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*,
177 int32_t*>);
178 case FunctionDescriptor::GetDisplayType:
179 return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
180 displayHook<decltype(&Display::getType),
181 &Display::getType, int32_t*>);
182 case FunctionDescriptor::GetDozeSupport:
183 return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
184 displayHook<decltype(&Display::getDozeSupport),
185 &Display::getDozeSupport, int32_t*>);
186 case FunctionDescriptor::GetHdrCapabilities:
187 return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
188 displayHook<decltype(&Display::getHdrCapabilities),
189 &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
190 float*, float*>);
191 case FunctionDescriptor::GetReleaseFences:
192 return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
193 displayHook<decltype(&Display::getReleaseFences),
194 &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
195 int32_t*>);
196 case FunctionDescriptor::PresentDisplay:
197 return asFP<HWC2_PFN_PRESENT_DISPLAY>(
198 displayHook<decltype(&Display::present),
199 &Display::present, int32_t*>);
200 case FunctionDescriptor::SetActiveConfig:
201 return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
202 displayHook<decltype(&Display::setActiveConfig),
203 &Display::setActiveConfig, hwc2_config_t>);
204 case FunctionDescriptor::SetClientTarget:
205 return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
206 displayHook<decltype(&Display::setClientTarget),
207 &Display::setClientTarget, buffer_handle_t, int32_t,
208 int32_t, hwc_region_t>);
209 case FunctionDescriptor::SetColorMode:
210 return asFP<HWC2_PFN_SET_COLOR_MODE>(
211 displayHook<decltype(&Display::setColorMode),
212 &Display::setColorMode, int32_t>);
213 case FunctionDescriptor::SetColorTransform:
214 return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(
215 displayHook<decltype(&Display::setColorTransform),
216 &Display::setColorTransform, const float*, int32_t>);
217 case FunctionDescriptor::SetOutputBuffer:
218 return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
219 displayHook<decltype(&Display::setOutputBuffer),
220 &Display::setOutputBuffer, buffer_handle_t, int32_t>);
221 case FunctionDescriptor::SetPowerMode:
222 return asFP<HWC2_PFN_SET_POWER_MODE>(
223 displayHook<decltype(&Display::setPowerMode),
224 &Display::setPowerMode, int32_t>);
225 case FunctionDescriptor::SetVsyncEnabled:
226 return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(
227 displayHook<decltype(&Display::setVsyncEnabled),
228 &Display::setVsyncEnabled, int32_t>);
229 case FunctionDescriptor::ValidateDisplay:
230 return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
231 displayHook<decltype(&Display::validate),
232 &Display::validate, uint32_t*, uint32_t*>);
233 case FunctionDescriptor::GetClientTargetSupport:
234 return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
235 displayHook<decltype(&Display::getClientTargetSupport),
236 &Display::getClientTargetSupport, uint32_t, uint32_t,
237 int32_t, int32_t>);
238 // 2.3 required functions
239 case FunctionDescriptor::GetDisplayIdentificationData:
240 return asFP<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
241 displayHook<decltype(&Display::getDisplayIdentificationData),
242 &Display::getDisplayIdentificationData, uint8_t*, uint32_t*, uint8_t*>);
243 case FunctionDescriptor::GetDisplayCapabilities:
244 return asFP<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
245 displayHook<decltype(&Display::getDisplayCapabilities),
246 &Display::getDisplayCapabilities, uint32_t*, uint32_t*>);
247 case FunctionDescriptor::GetDisplayBrightnessSupport:
248 return asFP<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
249 displayHook<decltype(&Display::getDisplayBrightnessSupport),
250 &Display::getDisplayBrightnessSupport, bool*>);
251 case FunctionDescriptor::SetDisplayBrightness:
252 return asFP<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
253 displayHook<decltype(&Display::setDisplayBrightness),
254 &Display::setDisplayBrightness, float>);
255 // Layer functions
256 case FunctionDescriptor::SetCursorPosition:
257 return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
258 layerHook<decltype(&Layer::setCursorPosition),
259 &Layer::setCursorPosition, int32_t, int32_t>);
260 case FunctionDescriptor::SetLayerBuffer:
261 return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
262 layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
263 buffer_handle_t, int32_t>);
264 case FunctionDescriptor::SetLayerSurfaceDamage:
265 return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
266 layerHook<decltype(&Layer::setSurfaceDamage),
267 &Layer::setSurfaceDamage, hwc_region_t>);
268
269 // Layer state functions
270 case FunctionDescriptor::SetLayerBlendMode:
271 return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
272 layerHook<decltype(&Layer::setBlendMode),
273 &Layer::setBlendMode, int32_t>);
274 case FunctionDescriptor::SetLayerColor:
275 return asFP<HWC2_PFN_SET_LAYER_COLOR>(
276 layerHook<decltype(&Layer::setColor), &Layer::setColor,
277 hwc_color_t>);
278 case FunctionDescriptor::SetLayerCompositionType:
279 return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
280 layerHook<decltype(&Layer::setCompositionType),
281 &Layer::setCompositionType, int32_t>);
282 case FunctionDescriptor::SetLayerDataspace:
283 return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(
284 layerHook<decltype(&Layer::setDataspace),
285 &Layer::setDataspace, int32_t>);
286 case FunctionDescriptor::SetLayerDisplayFrame:
287 return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
288 layerHook<decltype(&Layer::setDisplayFrame),
289 &Layer::setDisplayFrame, hwc_rect_t>);
290 case FunctionDescriptor::SetLayerPlaneAlpha:
291 return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
292 layerHook<decltype(&Layer::setPlaneAlpha),
293 &Layer::setPlaneAlpha, float>);
294 case FunctionDescriptor::SetLayerSidebandStream:
295 return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
296 layerHook<decltype(&Layer::setSidebandStream),
297 &Layer::setSidebandStream, const native_handle_t*>);
298 case FunctionDescriptor::SetLayerSourceCrop:
299 return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
300 layerHook<decltype(&Layer::setSourceCrop),
301 &Layer::setSourceCrop, hwc_frect_t>);
302 case FunctionDescriptor::SetLayerTransform:
303 return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(
304 layerHook<decltype(&Layer::setTransform),
305 &Layer::setTransform, int32_t>);
306 case FunctionDescriptor::SetLayerVisibleRegion:
307 return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
308 layerHook<decltype(&Layer::setVisibleRegion),
309 &Layer::setVisibleRegion, hwc_region_t>);
310 case FunctionDescriptor::SetLayerZOrder:
311 return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(
312 displayHook<decltype(&Display::updateLayerZ),
313 &Display::updateLayerZ, hwc2_layer_t, uint32_t>);
314
315 default:
316 ALOGE("doGetFunction: Unknown function descriptor: %d (%s)",
317 static_cast<int32_t>(descriptor),
318 to_string(descriptor).c_str());
319 return nullptr;
320 }
321 }
322
323
324 // Device functions
325
createVirtualDisplay(uint32_t,uint32_t,int32_t *,hwc2_display_t *)326 Error EmuHWC2::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/,
327 int32_t* /*format*/, hwc2_display_t* /*outDisplay*/) {
328 ALOGVV("%s", __FUNCTION__);
329 //TODO: VirtualDisplay support
330 return Error::None;
331 }
332
destroyVirtualDisplay(hwc2_display_t)333 Error EmuHWC2::destroyVirtualDisplay(hwc2_display_t /*displayId*/) {
334 ALOGVV("%s", __FUNCTION__);
335 //TODO: VirtualDisplay support
336 return Error::None;
337 }
338
dump(uint32_t *,char *)339 void EmuHWC2::dump(uint32_t* /*outSize*/, char* /*outBuffer*/) {
340 ALOGVV("%s", __FUNCTION__);
341 //TODO:
342 return;
343 }
344
getMaxVirtualDisplayCount()345 uint32_t EmuHWC2::getMaxVirtualDisplayCount() {
346 ALOGVV("%s", __FUNCTION__);
347 //TODO: VirtualDisplay support
348 return 0;
349 }
350
isValid(Callback descriptor)351 static bool isValid(Callback descriptor) {
352 switch (descriptor) {
353 case Callback::Hotplug: // Fall-through
354 case Callback::Refresh: // Fall-through
355 case Callback::Vsync: return true;
356 default: return false;
357 }
358 }
359
registerCallback(Callback descriptor,hwc2_callback_data_t callbackData,hwc2_function_pointer_t pointer)360 Error EmuHWC2::registerCallback(Callback descriptor,
361 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
362 ALOGVV("%s", __FUNCTION__);
363 if (!isValid(descriptor)) {
364 ALOGE("registerCallback: Unkown function descriptor: %d",
365 static_cast<int32_t>(descriptor));
366 return Error::BadParameter;
367 }
368 ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(),
369 callbackData, pointer);
370
371 std::unique_lock<std::mutex> lock(mStateMutex);
372
373 if (pointer != nullptr) {
374 mCallbacks[descriptor] = {callbackData, pointer};
375 }
376 else {
377 ALOGV("unregisterCallback(%s)", to_string(descriptor).c_str());
378 mCallbacks.erase(descriptor);
379 return Error::None;
380 }
381
382 // Callback without the state lock held
383 if (descriptor == Callback::Hotplug) {
384 lock.unlock();
385 auto hotplug = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
386 for (const auto& iter : mDisplays) {
387 hotplug(callbackData, iter.first, static_cast<int32_t>(Connection::Connected));
388 }
389 }
390
391 return Error::None;
392 }
393
allocateDisplayColorBuffer(int width,int height)394 const native_handle_t* EmuHWC2::allocateDisplayColorBuffer(int width, int height) {
395 const uint32_t layerCount = 1;
396 const uint64_t graphicBufferId = 0; // not used
397
398 buffer_handle_t h;
399 uint32_t stride;
400
401 if (GraphicBufferAllocator::get().allocate(
402 width, height,
403 PIXEL_FORMAT_RGBA_8888,
404 layerCount,
405 (GraphicBuffer::USAGE_HW_COMPOSER | GraphicBuffer::USAGE_HW_RENDER),
406 &h, &stride,
407 graphicBufferId, "EmuHWC2") == OK) {
408 return static_cast<const native_handle_t*>(h);
409 } else {
410 return nullptr;
411 }
412 }
413
freeDisplayColorBuffer(const native_handle_t * h)414 void EmuHWC2::freeDisplayColorBuffer(const native_handle_t* h) {
415 GraphicBufferAllocator::get().free(h);
416 }
417
418 // Display functions
419
420 #define VSYNC_PERIOD_PROP "ro.kernel.qemu.vsync"
421
getVsyncPeriodFromProperty()422 static int getVsyncPeriodFromProperty() {
423 char displaysValue[PROPERTY_VALUE_MAX] = "";
424 property_get(VSYNC_PERIOD_PROP, displaysValue, "");
425 bool isValid = displaysValue[0] != '\0';
426
427 if (!isValid) return 60;
428
429 long vsyncPeriodParsed = strtol(displaysValue, 0, 10);
430
431 // On failure, strtol returns 0. Also, there's no reason to have 0
432 // as the vsync period.
433 if (!vsyncPeriodParsed) return 60;
434
435 return static_cast<int>(vsyncPeriodParsed);
436 }
437
438 std::atomic<hwc2_display_t> EmuHWC2::Display::sNextId(0);
439
Display(EmuHWC2 & device,DisplayType type,int width,int height)440 EmuHWC2::Display::Display(EmuHWC2& device, DisplayType type, int width, int height)
441 : mDevice(device),
442 mId(sNextId++),
443 mHostDisplayId(0),
444 mName(),
445 mType(type),
446 mPowerMode(PowerMode::Off),
447 mVsyncEnabled(Vsync::Invalid),
448 mVsyncPeriod(1000*1000*1000/getVsyncPeriodFromProperty()), // vsync is 60 hz
449 mVsyncThread(*this),
450 mClientTarget(),
451 mChanges(),
452 mLayers(),
453 mReleaseLayerIds(),
454 mReleaseFences(),
455 mConfigs(),
456 mActiveConfig(nullptr),
457 mColorModes(),
458 mSetColorTransform(false),
459 mStateMutex() {
460 mVsyncThread.run("", ANDROID_PRIORITY_URGENT_DISPLAY);
461 mTargetCb = device.allocateDisplayColorBuffer(width, height);
462 }
463
~Display()464 EmuHWC2::Display::~Display() {
465 mDevice.freeDisplayColorBuffer(mTargetCb);
466 }
467
acceptChanges()468 Error EmuHWC2::Display::acceptChanges() {
469 ALOGVV("%s: displayId %u", __FUNCTION__, (uint32_t)mId);
470 std::unique_lock<std::mutex> lock(mStateMutex);
471
472 if (!mChanges) {
473 ALOGW("%s: displayId %u acceptChanges failed, not validated",
474 __FUNCTION__, (uint32_t)mId);
475 return Error::NotValidated;
476 }
477
478
479 for (auto& change : mChanges->getTypeChanges()) {
480 auto layerId = change.first;
481 auto type = change.second;
482 if (mDevice.mLayers.count(layerId) == 0) {
483 // This should never happen but somehow does.
484 ALOGW("Cannot accept change for unknown layer %u",
485 (uint32_t)layerId);
486 continue;
487 }
488 auto layer = mDevice.mLayers[layerId];
489 layer->setCompositionType((int32_t)type);
490 }
491
492 mChanges->clearTypeChanges();
493 return Error::None;
494 }
495
createLayer(hwc2_layer_t * outLayerId)496 Error EmuHWC2::Display::createLayer(hwc2_layer_t* outLayerId) {
497 ALOGVV("%s", __FUNCTION__);
498 std::unique_lock<std::mutex> lock(mStateMutex);
499
500 auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
501 mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
502 *outLayerId = layer->getId();
503 ALOGV("%s: Display %u created layer %u", __FUNCTION__, (uint32_t)mId,
504 (uint32_t)(*outLayerId));
505 return Error::None;
506 }
507
destroyLayer(hwc2_layer_t layerId)508 Error EmuHWC2::Display::destroyLayer(hwc2_layer_t layerId) {
509 ALOGVV("%s", __FUNCTION__);
510 std::unique_lock<std::mutex> lock(mStateMutex);
511
512 const auto mapLayer = mDevice.mLayers.find(layerId);
513 if (mapLayer == mDevice.mLayers.end()) {
514 ALOGW("%s failed: no such layer, displayId %u layerId %u",
515 __FUNCTION__, (uint32_t)mId, (uint32_t)layerId);
516 return Error::BadLayer;
517 }
518 const auto layer = mapLayer->second;
519 mDevice.mLayers.erase(mapLayer);
520 const auto zRange = mLayers.equal_range(layer);
521 for (auto current = zRange.first; current != zRange.second; ++current) {
522 if (**current == *layer) {
523 current = mLayers.erase(current);
524 break;
525 }
526 }
527 ALOGV("%s: displayId %d layerId %d", __FUNCTION__, (uint32_t)mId,
528 (uint32_t)layerId);
529 return Error::None;
530 }
531
getActiveConfig(hwc2_config_t * outConfig)532 Error EmuHWC2::Display::getActiveConfig(hwc2_config_t* outConfig) {
533 ALOGVV("%s", __FUNCTION__);
534 std::unique_lock<std::mutex> lock(mStateMutex);
535
536 if (!mActiveConfig) {
537 ALOGW("%s: displayId %d %s", __FUNCTION__, (uint32_t)mId,
538 to_string(Error::BadConfig).c_str());
539 return Error::BadConfig;
540 }
541 auto configId = mActiveConfig->getId();
542 ALOGV("%s: displayId %d configId %d", __FUNCTION__,
543 (uint32_t)mId, (uint32_t)configId);
544 *outConfig = configId;
545 return Error::None;
546 }
547
getDisplayAttribute(hwc2_config_t configId,int32_t attribute,int32_t * outValue)548 Error EmuHWC2::Display::getDisplayAttribute(hwc2_config_t configId,
549 int32_t attribute, int32_t* outValue) {
550 ALOGVV("%s", __FUNCTION__);
551 std::unique_lock<std::mutex> lock(mStateMutex);
552
553 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
554 ALOGW("%s: bad config (%u %u)", __FUNCTION__, (uint32_t)mId, configId);
555 return Error::BadConfig;
556 }
557 *outValue = mConfigs[configId]->getAttribute((Attribute)attribute);
558 ALOGV("%s: (%d %d) %s --> %d", __FUNCTION__,
559 (uint32_t)mId, (uint32_t)configId,
560 to_string((Attribute)attribute).c_str(), *outValue);
561 return Error::None;
562 }
563
getChangedCompositionTypes(uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outTypes)564 Error EmuHWC2::Display::getChangedCompositionTypes(
565 uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) {
566 ALOGVV("%s", __FUNCTION__);
567 std::unique_lock<std::mutex> lock(mStateMutex);
568
569 if (!mChanges) {
570 ALOGW("display %u getChangedCompositionTypes failed: not validated",
571 (uint32_t)mId);
572 return Error::NotValidated;
573 }
574
575 if ((outLayers == nullptr) || (outTypes == nullptr)) {
576 *outNumElements = mChanges->getTypeChanges().size();
577 return Error::None;
578 }
579
580 uint32_t numWritten = 0;
581 for (const auto& element : mChanges->getTypeChanges()) {
582 if (numWritten == *outNumElements) {
583 break;
584 }
585 auto layerId = element.first;
586 auto intType = static_cast<int32_t>(element.second);
587 ALOGV("%s: Adding layer %u %s", __FUNCTION__, (uint32_t)layerId,
588 to_string(element.second).c_str());
589 outLayers[numWritten] = layerId;
590 outTypes[numWritten] = intType;
591 ++numWritten;
592 }
593 *outNumElements = numWritten;
594 return Error::None;
595 }
596
getColorModes(uint32_t * outNumModes,int32_t * outModes)597 Error EmuHWC2::Display::getColorModes(uint32_t* outNumModes,
598 int32_t* outModes) {
599 ALOGVV("%s", __FUNCTION__);
600 std::unique_lock<std::mutex> lock(mStateMutex);
601
602 if (!outModes) {
603 *outNumModes = mColorModes.size();
604 return Error::None;
605 }
606
607 // we only support HAL_COLOR_MODE_NATIVE so far
608 uint32_t numModes = std::min(*outNumModes,
609 static_cast<uint32_t>(mColorModes.size()));
610 std::copy_n(mColorModes.cbegin(), numModes, outModes);
611 *outNumModes = numModes;
612 return Error::None;
613 }
614
getConfigs(uint32_t * outNumConfigs,hwc2_config_t * outConfigs)615 Error EmuHWC2::Display::getConfigs(uint32_t* outNumConfigs,
616 hwc2_config_t* outConfigs) {
617 ALOGVV("%s", __FUNCTION__);
618 std::unique_lock<std::mutex> lock(mStateMutex);
619
620 if (!outConfigs) {
621 *outNumConfigs = mConfigs.size();
622 return Error::None;
623 }
624 uint32_t numWritten = 0;
625 for (const auto config : mConfigs) {
626 if (numWritten == *outNumConfigs) {
627 break;
628 }
629 outConfigs[numWritten] = config->getId();
630 ++numWritten;
631 }
632 *outNumConfigs = numWritten;
633 return Error::None;
634 }
635
getDozeSupport(int32_t * outSupport)636 Error EmuHWC2::Display::getDozeSupport(int32_t* outSupport) {
637 ALOGVV("%s", __FUNCTION__);
638 // We don't support so far
639 *outSupport = 0;
640 return Error::None;
641 }
642
getHdrCapabilities(uint32_t * outNumTypes,int32_t *,float *,float *,float *)643 Error EmuHWC2::Display::getHdrCapabilities(uint32_t* outNumTypes,
644 int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
645 float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
646 ALOGVV("%s", __FUNCTION__);
647 // We don't support so far
648 *outNumTypes = 0;
649 return Error::None;
650 }
651
getName(uint32_t * outSize,char * outName)652 Error EmuHWC2::Display::getName(uint32_t* outSize, char* outName) {
653 ALOGVV("%s", __FUNCTION__);
654 std::unique_lock<std::mutex> lock(mStateMutex);
655
656 if (!outName) {
657 *outSize = mName.size();
658 return Error::None;
659 }
660 auto numCopied = mName.copy(outName, *outSize);
661 *outSize = numCopied;
662 return Error::None;
663 }
664
getReleaseFences(uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outFences)665 Error EmuHWC2::Display::getReleaseFences(uint32_t* outNumElements,
666 hwc2_layer_t* outLayers, int32_t* outFences) {
667 ALOGVV("%s", __FUNCTION__);
668
669 *outNumElements = mReleaseLayerIds.size();
670
671 ALOGVV("%s. Got %u elements", __FUNCTION__, *outNumElements);
672
673 if (*outNumElements && outLayers) {
674 ALOGVV("%s. export release layers", __FUNCTION__);
675 memcpy(outLayers, mReleaseLayerIds.data(),
676 sizeof(hwc2_layer_t) * (*outNumElements));
677 }
678
679 if (*outNumElements && outFences) {
680 ALOGVV("%s. export release fences", __FUNCTION__);
681 memcpy(outFences, mReleaseFences.data(),
682 sizeof(int32_t) * (*outNumElements));
683 }
684
685 return Error::None;
686 }
687
getRequests(int32_t * outDisplayRequests,uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outLayerRequests)688 Error EmuHWC2::Display::getRequests(int32_t* outDisplayRequests,
689 uint32_t* outNumElements, hwc2_layer_t* outLayers,
690 int32_t* outLayerRequests) {
691 ALOGVV("%s", __FUNCTION__);
692 std::unique_lock<std::mutex> lock(mStateMutex);
693
694 if (!mChanges) {
695 return Error::NotValidated;
696 }
697
698 if (outLayers == nullptr || outLayerRequests == nullptr) {
699 *outNumElements = mChanges->getNumLayerRequests();
700 return Error::None;
701 }
702
703 //TODO
704 // Display requests (HWC2::DisplayRequest) are not supported so far:
705 *outDisplayRequests = 0;
706
707 uint32_t numWritten = 0;
708 for (const auto& request : mChanges->getLayerRequests()) {
709 if (numWritten == *outNumElements) {
710 break;
711 }
712 outLayers[numWritten] = request.first;
713 outLayerRequests[numWritten] = static_cast<int32_t>(request.second);
714 ++numWritten;
715 }
716
717 return Error::None;
718 }
719
getType(int32_t * outType)720 Error EmuHWC2::Display::getType(int32_t* outType) {
721 ALOGVV("%s", __FUNCTION__);
722 std::unique_lock<std::mutex> lock(mStateMutex);
723
724 *outType = (int32_t)mType;
725 return Error::None;
726 }
727
present(int32_t * outRetireFence)728 Error EmuHWC2::Display::present(int32_t* outRetireFence) {
729 ALOGVV("%s", __FUNCTION__);
730
731 *outRetireFence = -1;
732
733 std::unique_lock<std::mutex> lock(mStateMutex);
734
735 if (!mChanges || (mChanges->getNumTypes() > 0)) {
736 ALOGE("%s display(%u) set failed: not validated", __FUNCTION__,
737 (uint32_t)mId);
738 return Error::NotValidated;
739 }
740 mChanges.reset();
741
742 DEFINE_AND_VALIDATE_HOST_CONNECTION
743 hostCon->lock();
744 bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
745 bool hostCompositionV2 = rcEnc->hasHostCompositionV2();
746 hostCon->unlock();
747
748 // if we supports v2, then discard v1
749 if (hostCompositionV2) {
750 hostCompositionV1 = false;
751 }
752
753 if (hostCompositionV2 || hostCompositionV1) {
754 uint32_t numLayer = 0;
755 for (auto layer: mLayers) {
756 if (layer->getCompositionType() == Composition::Device ||
757 layer->getCompositionType() == Composition::SolidColor) {
758 numLayer++;
759 }
760 }
761
762 ALOGVV("present %d layers total %u layers",
763 numLayer, (uint32_t)mLayers.size());
764
765 mReleaseLayerIds.clear();
766 mReleaseFences.clear();
767
768 if (numLayer == 0) {
769 ALOGW("No layers, exit, buffer %p", mClientTarget.getBuffer());
770 if (mClientTarget.getBuffer()) {
771 post(hostCon, rcEnc, mClientTarget.getBuffer());
772 *outRetireFence = mClientTarget.getFence();
773 }
774 return Error::None;
775 }
776
777 if (hostCompositionV1) {
778 if (mComposeMsg == nullptr || mComposeMsg->getLayerCnt() < numLayer) {
779 mComposeMsg.reset(new ComposeMsg(numLayer));
780 }
781 } else {
782 if (mComposeMsg_v2 == nullptr || mComposeMsg_v2->getLayerCnt() < numLayer) {
783 mComposeMsg_v2.reset(new ComposeMsg_v2(numLayer));
784 }
785 }
786
787 // Handle the composition
788 ComposeDevice* p;
789 ComposeDevice_v2* p2;
790 ComposeLayer* l;
791
792 if (hostCompositionV1) {
793 p = mComposeMsg->get();
794 l = p->layer;
795 } else {
796 p2 = mComposeMsg_v2->get();
797 l = p2->layer;
798 }
799
800 for (auto layer: mLayers) {
801 if (layer->getCompositionType() != Composition::Device &&
802 layer->getCompositionType() != Composition::SolidColor) {
803 ALOGE("%s: Unsupported composition types %d layer %u",
804 __FUNCTION__, layer->getCompositionType(),
805 (uint32_t)layer->getId());
806 continue;
807 }
808 // send layer composition command to host
809 if (layer->getCompositionType() == Composition::Device) {
810 int fence = layer->getLayerBuffer().getFence();
811 mReleaseLayerIds.push_back(layer->getId());
812 if (fence != -1) {
813 int err = sync_wait(fence, 3000);
814 if (err < 0 && errno == ETIME) {
815 ALOGE("%s waited on fence %d for 3000 ms",
816 __FUNCTION__, fence);
817 }
818 close(fence);
819 }
820 else {
821 ALOGV("%s: acquire fence not set for layer %u",
822 __FUNCTION__, (uint32_t)layer->getId());
823 }
824 const native_handle_t *cb =
825 layer->getLayerBuffer().getBuffer();
826 if (cb != nullptr) {
827 l->cbHandle = hostCon->grallocHelper()->getHostHandle(cb);
828 }
829 else {
830 ALOGE("%s null buffer for layer %d", __FUNCTION__,
831 (uint32_t)layer->getId());
832 }
833 }
834 else {
835 // solidcolor has no buffer
836 l->cbHandle = 0;
837 }
838 l->composeMode = (hwc2_composition_t)layer->getCompositionType();
839 l->displayFrame = layer->getDisplayFrame();
840 l->crop = layer->getSourceCrop();
841 l->blendMode = layer->getBlendMode();
842 l->alpha = layer->getPlaneAlpha();
843 l->color = layer->getColor();
844 l->transform = layer->getTransform();
845 ALOGV(" cb %d blendmode %d alpha %f %d %d %d %d z %d"
846 " composeMode %d, transform %d",
847 l->cbHandle, l->blendMode, l->alpha,
848 l->displayFrame.left, l->displayFrame.top,
849 l->displayFrame.right, l->displayFrame.bottom,
850 layer->getZ(), l->composeMode, l->transform);
851 l++;
852 }
853 if (hostCompositionV1) {
854 p->version = 1;
855 p->targetHandle = hostCon->grallocHelper()->getHostHandle(mTargetCb);
856 p->numLayers = numLayer;
857 } else {
858 p2->version = 2;
859 p2->displayId = mHostDisplayId;
860 p2->targetHandle = hostCon->grallocHelper()->getHostHandle(mTargetCb);
861 p2->numLayers = numLayer;
862 }
863
864 hostCon->lock();
865 if (hostCompositionV1) {
866 rcEnc->rcCompose(rcEnc,
867 sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer),
868 (void *)p);
869 } else {
870 rcEnc->rcCompose(rcEnc,
871 sizeof(ComposeDevice_v2) + numLayer * sizeof(ComposeLayer),
872 (void *)p2);
873 }
874
875 hostCon->unlock();
876
877 // Send a retire fence and use it as the release fence for all layers,
878 // since media expects it
879 EGLint attribs[] = { EGL_SYNC_NATIVE_FENCE_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID };
880
881 uint64_t sync_handle, thread_handle;
882 int retire_fd;
883
884 hostCon->lock();
885 rcEnc->rcCreateSyncKHR(rcEnc, EGL_SYNC_NATIVE_FENCE_ANDROID,
886 attribs, 2 * sizeof(EGLint), true /* destroy when signaled */,
887 &sync_handle, &thread_handle);
888 hostCon->unlock();
889
890 goldfish_sync_queue_work(mSyncDeviceFd,
891 sync_handle, thread_handle, &retire_fd);
892
893 for (size_t i = 0; i < mReleaseLayerIds.size(); ++i) {
894 mReleaseFences.push_back(dup(retire_fd));
895 }
896
897 *outRetireFence = dup(retire_fd);
898 close(retire_fd);
899 hostCon->lock();
900 rcEnc->rcDestroySyncKHR(rcEnc, sync_handle);
901 hostCon->unlock();
902 } else {
903 // we set all layers Composition::Client, so do nothing.
904 post(hostCon, rcEnc, mClientTarget.getBuffer());
905 *outRetireFence = mClientTarget.getFence();
906 ALOGV("%s fallback to post, returns outRetireFence %d",
907 __FUNCTION__, *outRetireFence);
908 }
909
910 return Error::None;
911 }
912
setActiveConfig(hwc2_config_t configId)913 Error EmuHWC2::Display::setActiveConfig(hwc2_config_t configId) {
914 ALOGVV("%s %u", __FUNCTION__, (uint32_t)configId);
915 std::unique_lock<std::mutex> lock(mStateMutex);
916
917 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
918 ALOGW("%s: bad config (%u %u)", __FUNCTION__, (uint32_t)mId,
919 (uint32_t)configId);
920 return Error::BadConfig;
921 }
922 auto config = mConfigs[configId];
923 if (config == mActiveConfig) {
924 return Error::None;
925 }
926
927 mActiveConfig = config;
928 return Error::None;
929 }
930
setClientTarget(buffer_handle_t target,int32_t acquireFence,int32_t,hwc_region_t)931 Error EmuHWC2::Display::setClientTarget(buffer_handle_t target,
932 int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
933 ALOGVV("%s", __FUNCTION__);
934
935 std::unique_lock<std::mutex> lock(mStateMutex);
936 mClientTarget.setBuffer(target);
937 mClientTarget.setFence(acquireFence);
938 return Error::None;
939 }
940
setColorMode(int32_t intMode)941 Error EmuHWC2::Display::setColorMode(int32_t intMode) {
942 ALOGVV("%s %d", __FUNCTION__, intMode);
943 std::unique_lock<std::mutex> lock(mStateMutex);
944
945 auto mode = static_cast<android_color_mode_t>(intMode);
946 ALOGV("%s: (display %u mode %d)", __FUNCTION__, (uint32_t)mId, intMode);
947 if (mode == mActiveColorMode) {
948 return Error::None;
949 }
950 if (mColorModes.count(mode) == 0) {
951 ALOGE("%s: display %d Mode %d not found in mColorModes",
952 __FUNCTION__, (uint32_t)mId, intMode);
953 return Error::Unsupported;
954 }
955 mActiveColorMode = mode;
956 return Error::None;
957 }
958
setColorTransform(const float *,int32_t hint)959 Error EmuHWC2::Display::setColorTransform(const float* /*matrix*/,
960 int32_t hint) {
961 ALOGVV("%s hint %d", __FUNCTION__, hint);
962 std::unique_lock<std::mutex> lock(mStateMutex);
963 //we force client composition if this is set
964 if (hint == 0 ) {
965 mSetColorTransform = false;
966 }
967 else {
968 mSetColorTransform = true;
969 }
970 return Error::None;
971 }
972
setOutputBuffer(buffer_handle_t,int32_t)973 Error EmuHWC2::Display::setOutputBuffer(buffer_handle_t /*buffer*/,
974 int32_t /*releaseFence*/) {
975 ALOGVV("%s", __FUNCTION__);
976 //TODO: for virtual display
977 return Error::None;
978 }
979
isValid(PowerMode mode)980 static bool isValid(PowerMode mode) {
981 switch (mode) {
982 case PowerMode::Off: // Fall-through
983 case PowerMode::DozeSuspend: // Fall-through
984 case PowerMode::Doze: // Fall-through
985 case PowerMode::On: return true;
986 default: return false;
987 }
988 }
989
setPowerMode(int32_t intMode)990 Error EmuHWC2::Display::setPowerMode(int32_t intMode) {
991 ALOGVV("%s", __FUNCTION__);
992 // Emulator always set screen ON
993 PowerMode mode = static_cast<PowerMode>(intMode);
994 if (!isValid(mode)) {
995 return Error::BadParameter;
996 }
997 if (mode == mPowerMode) {
998 return Error::None;
999 }
1000 std::unique_lock<std::mutex> lock(mStateMutex);
1001
1002 ALOGV("%s: (display %u mode %s)", __FUNCTION__,
1003 (uint32_t)mId, to_string(mode).c_str());
1004 mPowerMode = mode;
1005 return Error::None;
1006 }
1007
isValid(Vsync enable)1008 static bool isValid(Vsync enable) {
1009 switch (enable) {
1010 case Vsync::Enable: // Fall-through
1011 case Vsync::Disable: return true;
1012 case Vsync::Invalid: return false;
1013 }
1014 }
1015
setVsyncEnabled(int32_t intEnable)1016 Error EmuHWC2::Display::setVsyncEnabled(int32_t intEnable) {
1017 ALOGVV("%s %d", __FUNCTION__, intEnable);
1018 Vsync enable = static_cast<Vsync>(intEnable);
1019 if (!isValid(enable)) {
1020 return Error::BadParameter;
1021 }
1022 if (enable == mVsyncEnabled) {
1023 return Error::None;
1024 }
1025
1026 std::unique_lock<std::mutex> lock(mStateMutex);
1027
1028 mVsyncEnabled = enable;
1029 return Error::None;
1030 }
1031
validate(uint32_t * outNumTypes,uint32_t * outNumRequests)1032 Error EmuHWC2::Display::validate(uint32_t* outNumTypes,
1033 uint32_t* outNumRequests) {
1034 ALOGVV("%s", __FUNCTION__);
1035 std::unique_lock<std::mutex> lock(mStateMutex);
1036
1037 if (!mChanges) {
1038 mChanges.reset(new Changes);
1039 DEFINE_AND_VALIDATE_HOST_CONNECTION
1040 hostCon->lock();
1041 bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
1042 bool hostCompositionV2 = rcEnc->hasHostCompositionV2();
1043 hostCon->unlock();
1044
1045 if (hostCompositionV1 || hostCompositionV2) {
1046 // Support Device and SolidColor, otherwise, fallback all layers
1047 // to Client
1048 bool fallBack = false;
1049 for (auto& layer : mLayers) {
1050 if (layer->getCompositionType() == Composition::Invalid) {
1051 // Log error for unused layers, layer leak?
1052 ALOGE("%s layer %u CompositionType(%d) not set",
1053 __FUNCTION__, (uint32_t)layer->getId(),
1054 layer->getCompositionType());
1055 continue;
1056 }
1057 if (layer->getCompositionType() == Composition::Client ||
1058 layer->getCompositionType() == Composition::Cursor ||
1059 layer->getCompositionType() == Composition::Sideband) {
1060 ALOGW("%s: layer %u CompositionType %d, fallback", __FUNCTION__,
1061 (uint32_t)layer->getId(), layer->getCompositionType());
1062 fallBack = true;
1063 break;
1064 }
1065 }
1066 if (mSetColorTransform) {
1067 fallBack = true;
1068 }
1069 if (fallBack) {
1070 for (auto& layer : mLayers) {
1071 if (layer->getCompositionType() == Composition::Invalid) {
1072 continue;
1073 }
1074 if (layer->getCompositionType() != Composition::Client) {
1075 mChanges->addTypeChange(layer->getId(),
1076 Composition::Client);
1077 }
1078 }
1079 }
1080 }
1081 else {
1082 for (auto& layer : mLayers) {
1083 if (layer->getCompositionType() != Composition::Client) {
1084 mChanges->addTypeChange(layer->getId(),
1085 Composition::Client);
1086 }
1087 }
1088 }
1089 }
1090 else {
1091 ALOGE("Validate was called more than once!");
1092 }
1093
1094 *outNumTypes = mChanges->getNumTypes();
1095 *outNumRequests = mChanges->getNumLayerRequests();
1096 ALOGV("%s: displayId %u types %u, requests %u", __FUNCTION__,
1097 (uint32_t)mId, *outNumTypes, *outNumRequests);
1098 return *outNumTypes > 0 ? Error::HasChanges : Error::None;
1099 }
1100
updateLayerZ(hwc2_layer_t layerId,uint32_t z)1101 Error EmuHWC2::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
1102 ALOGVV("%s", __FUNCTION__);
1103 std::unique_lock<std::mutex> lock(mStateMutex);
1104
1105 const auto mapLayer = mDevice.mLayers.find(layerId);
1106 if (mapLayer == mDevice.mLayers.end()) {
1107 ALOGE("%s failed to find layer %u", __FUNCTION__, (uint32_t)mId);
1108 return Error::BadLayer;
1109 }
1110
1111 const auto layer = mapLayer->second;
1112 const auto zRange = mLayers.equal_range(layer);
1113 bool layerOnDisplay = false;
1114 for (auto current = zRange.first; current != zRange.second; ++current) {
1115 if (**current == *layer) {
1116 if ((*current)->getZ() == z) {
1117 // Don't change anything if the Z hasn't changed
1118 return Error::None;
1119 }
1120 current = mLayers.erase(current);
1121 layerOnDisplay = true;
1122 break;
1123 }
1124 }
1125
1126 if (!layerOnDisplay) {
1127 ALOGE("%s failed to find layer %u on display", __FUNCTION__,
1128 (uint32_t)mId);
1129 return Error::BadLayer;
1130 }
1131
1132 layer->setZ(z);
1133 mLayers.emplace(std::move(layer));
1134 return Error::None;
1135 }
1136
getClientTargetSupport(uint32_t width,uint32_t height,int32_t format,int32_t dataspace)1137 Error EmuHWC2::Display::getClientTargetSupport(uint32_t width, uint32_t height,
1138 int32_t format, int32_t dataspace){
1139 ALOGVV("%s", __FUNCTION__);
1140 std::unique_lock<std::mutex> lock(mStateMutex);
1141
1142 if (mActiveConfig == nullptr) {
1143 return Error::Unsupported;
1144 }
1145
1146 if (width == (uint32_t)mActiveConfig->getAttribute(Attribute::Width) &&
1147 height == (uint32_t)mActiveConfig->getAttribute(Attribute::Height) &&
1148 format == HAL_PIXEL_FORMAT_RGBA_8888 &&
1149 dataspace == HAL_DATASPACE_UNKNOWN) {
1150 return Error::None;
1151 }
1152
1153 return Error::None;
1154 }
1155
1156 // thess EDIDs are carefully generated according to the EDID spec version 1.3, more info
1157 // can be found from the following file:
1158 // frameworks/native/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
1159 // approved pnp ids can be found here: https://uefi.org/pnp_id_list
1160 // pnp id: GGL, name: EMU_display_0, last byte is checksum
1161 // display id is local:8141603649153536
1162 static const uint8_t sEDID0[] = {
1163 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
1164 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27,
1165 0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1166 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
1167 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
1170 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x30, 0x00, 0x4b
1171 };
1172
1173 // pnp id: GGL, name: EMU_display_1
1174 // display id is local:8140900251843329
1175 static const uint8_t sEDID1[] = {
1176 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
1177 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27,
1178 0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1179 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
1180 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
1183 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x00, 0x3b
1184 };
1185
1186 // pnp id: GGL, name: EMU_display_2
1187 // display id is local:8140940453066754
1188 static const uint8_t sEDID2[] = {
1189 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
1190 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27,
1191 0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1192 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
1193 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
1196 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x00, 0x49
1197 };
1198
1199 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
1200
getDisplayIdentificationData(uint8_t * outPort,uint32_t * outDataSize,uint8_t * outData)1201 Error EmuHWC2::Display::getDisplayIdentificationData(uint8_t* outPort,
1202 uint32_t* outDataSize, uint8_t* outData) {
1203 ALOGVV("%s DisplayId %u", __FUNCTION__, (uint32_t)mId);
1204 if (outPort == nullptr || outDataSize == nullptr)
1205 return Error::BadParameter;
1206
1207 uint32_t len = std::min(*outDataSize, (uint32_t)ARRAY_SIZE(sEDID0));
1208 if (outData != nullptr && len < (uint32_t)ARRAY_SIZE(sEDID0)) {
1209 ALOGW("%s DisplayId %u, small buffer size: %u is specified",
1210 __FUNCTION__, (uint32_t)mId, len);
1211 }
1212 *outDataSize = ARRAY_SIZE(sEDID0);
1213 switch (mId) {
1214 case 0:
1215 *outPort = 0;
1216 if (outData)
1217 memcpy(outData, sEDID0, len);
1218 break;
1219
1220 case 1:
1221 *outPort = 1;
1222 if (outData)
1223 memcpy(outData, sEDID1, len);
1224 break;
1225
1226 case 2:
1227 *outPort = 2;
1228 if (outData)
1229 memcpy(outData, sEDID2, len);
1230 break;
1231
1232 default:
1233 *outPort = (uint8_t)mId;
1234 if (outData) {
1235 memcpy(outData, sEDID2, len);
1236 uint32_t size = ARRAY_SIZE(sEDID0);
1237 // change the name to EMU_display_<mID>
1238 // note the 3rd char from back is the number, _0, _1, _2, etc.
1239 if (len >= size - 2)
1240 outData[size-3] = '0' + (uint8_t)mId;
1241 if (len >= size) {
1242 // update the last byte, which is checksum byte
1243 uint8_t checksum = -(uint8_t)std::accumulate(
1244 outData, outData + size - 1, static_cast<uint8_t>(0));
1245 outData[size - 1] = checksum;
1246 }
1247 }
1248 break;
1249 }
1250
1251 return Error::None;
1252 }
1253
getDisplayCapabilities(uint32_t * outNumCapabilities,uint32_t * outCapabilities)1254 Error EmuHWC2::Display::getDisplayCapabilities(uint32_t* outNumCapabilities,
1255 uint32_t* outCapabilities) {
1256 if (outNumCapabilities == nullptr) {
1257 return Error::None;
1258 }
1259
1260 bool brightness_support = true;
1261 bool doze_support = true;
1262
1263 uint32_t count = 1 + static_cast<uint32_t>(doze_support) + (brightness_support ? 1 : 0);
1264 int index = 0;
1265 if (outCapabilities != nullptr && (*outNumCapabilities >= count)) {
1266 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM;
1267 if (doze_support) {
1268 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_DOZE;
1269 }
1270 if (brightness_support) {
1271 outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_BRIGHTNESS;
1272 }
1273 }
1274
1275 *outNumCapabilities = count;
1276 return Error::None;
1277 }
1278
getDisplayBrightnessSupport(bool * out_support)1279 Error EmuHWC2::Display::getDisplayBrightnessSupport(bool *out_support) {
1280 *out_support = false;
1281 return Error::None;
1282 }
1283
setDisplayBrightness(float brightness)1284 Error EmuHWC2::Display::setDisplayBrightness(float brightness) {
1285 ALOGW("TODO: setDisplayBrightness() is not implemented yet: brightness=%f", brightness);
1286 return Error::None;
1287 }
1288
populatePrimaryConfigs(int width,int height,int dpiX,int dpiY)1289 int EmuHWC2::Display::populatePrimaryConfigs(int width, int height, int dpiX, int dpiY) {
1290 ALOGVV("%s DisplayId %u", __FUNCTION__, (uint32_t)mId);
1291 std::unique_lock<std::mutex> lock(mStateMutex);
1292
1293 auto newConfig = std::make_shared<Config>(*this);
1294 // vsync is 60 hz;
1295 newConfig->setAttribute(Attribute::VsyncPeriod, mVsyncPeriod);
1296 newConfig->setAttribute(Attribute::Width, width);
1297 newConfig->setAttribute(Attribute::Height, height);
1298 newConfig->setAttribute(Attribute::DpiX, dpiX * 1000);
1299 newConfig->setAttribute(Attribute::DpiY, dpiY * 1000);
1300
1301 newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
1302 ALOGV("Found new config %d: %s", (uint32_t)newConfig->getId(),
1303 newConfig->toString().c_str());
1304 mConfigs.emplace_back(std::move(newConfig));
1305
1306 // Only have single config so far, it is activeConfig
1307 mActiveConfig = mConfigs[0];
1308 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1309 mColorModes.emplace((android_color_mode_t)HAL_COLOR_MODE_NATIVE);
1310
1311 mSyncDeviceFd = goldfish_sync_open();
1312
1313 return 0;
1314 }
1315
post(HostConnection * hostCon,ExtendedRCEncoderContext * rcEnc,buffer_handle_t h)1316 void EmuHWC2::Display::post(HostConnection *hostCon,
1317 ExtendedRCEncoderContext *rcEnc,
1318 buffer_handle_t h) {
1319 assert(cb && "native_handle_t::from(h) failed");
1320
1321 hostCon->lock();
1322 rcEnc->rcFBPost(rcEnc, hostCon->grallocHelper()->getHostHandle(h));
1323 hostCon->flush();
1324 hostCon->unlock();
1325 }
1326
populateSecondaryConfigs(uint32_t width,uint32_t height,uint32_t dpi,uint32_t idx)1327 HWC2::Error EmuHWC2::Display::populateSecondaryConfigs(uint32_t width, uint32_t height,
1328 uint32_t dpi, uint32_t idx) {
1329 ALOGVV("%s DisplayId %u, width %u, height %u, dpi %u",
1330 __FUNCTION__, (uint32_t)mId, width, height, dpi);
1331 std::unique_lock<std::mutex> lock(mStateMutex);
1332
1333 auto newConfig = std::make_shared<Config>(*this);
1334 // vsync is 60 hz;
1335 newConfig->setAttribute(Attribute::VsyncPeriod, mVsyncPeriod);
1336 newConfig->setAttribute(Attribute::Width, width);
1337 newConfig->setAttribute(Attribute::Height, height);
1338 newConfig->setAttribute(Attribute::DpiX, dpi*1000);
1339 newConfig->setAttribute(Attribute::DpiY, dpi*1000);
1340
1341 int configId = mConfigs.size();
1342 newConfig->setId(static_cast<hwc2_config_t>(configId));
1343 ALOGV("Found new secondary config %d: %s", (uint32_t)newConfig->getId(),
1344 newConfig->toString().c_str());
1345 mConfigs.emplace_back(std::move(newConfig));
1346
1347 mActiveConfig = mConfigs[configId];
1348 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1349 mColorModes.emplace((android_color_mode_t)HAL_COLOR_MODE_NATIVE);
1350
1351 uint32_t displayId = hostDisplayIdStart + idx;
1352 DEFINE_AND_VALIDATE_HOST_CONNECTION
1353
1354 hostCon->lock();
1355 rcEnc->rcDestroyDisplay(rcEnc, displayId);
1356 rcEnc->rcCreateDisplay(rcEnc, &displayId);
1357 rcEnc->rcSetDisplayPose(rcEnc, displayId, -1, -1, width, height);
1358 hostCon->unlock();
1359
1360 if (displayId != hostDisplayIdStart + idx) {
1361 ALOGE("Something wrong with host displayId allocation, want %d "
1362 "allocated %d", hostDisplayIdStart + idx, displayId);
1363 }
1364 mHostDisplayId = displayId;
1365 ALOGVV("%s: mHostDisplayId=%d", __FUNCTION__, mHostDisplayId);
1366
1367 return HWC2::Error::None;
1368 }
1369
1370
1371 // Config functions
1372
setAttribute(Attribute attribute,int32_t value)1373 void EmuHWC2::Display::Config::setAttribute(Attribute attribute,
1374 int32_t value) {
1375 mAttributes[attribute] = value;
1376 }
1377
getAttribute(Attribute attribute) const1378 int32_t EmuHWC2::Display::Config::getAttribute(Attribute attribute) const {
1379 if (mAttributes.count(attribute) == 0) {
1380 return -1;
1381 }
1382 return mAttributes.at(attribute);
1383 }
1384
toString() const1385 std::string EmuHWC2::Display::Config::toString() const {
1386 std::string output;
1387
1388 const size_t BUFFER_SIZE = 100;
1389 char buffer[BUFFER_SIZE] = {};
1390 auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
1391 "%u x %u", mAttributes.at(HWC2::Attribute::Width),
1392 mAttributes.at(HWC2::Attribute::Height));
1393 output.append(buffer, writtenBytes);
1394
1395 if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
1396 std::memset(buffer, 0, BUFFER_SIZE);
1397 writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
1398 1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
1399 output.append(buffer, writtenBytes);
1400 }
1401
1402 if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
1403 mAttributes.at(HWC2::Attribute::DpiX) != -1) {
1404 std::memset(buffer, 0, BUFFER_SIZE);
1405 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1406 ", DPI: %.1f x %.1f",
1407 mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
1408 mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
1409 output.append(buffer, writtenBytes);
1410 }
1411
1412 return output;
1413 }
1414
1415 // VsyncThread function
threadLoop()1416 bool EmuHWC2::Display::VsyncThread::threadLoop() {
1417 struct timespec rt;
1418 if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
1419 ALOGE("%s: error in vsync thread clock_gettime: %s",
1420 __FUNCTION__, strerror(errno));
1421 return true;
1422 }
1423 const int logInterval = 60;
1424 int64_t lastLogged = rt.tv_sec;
1425 int sent = 0;
1426 int lastSent = 0;
1427 bool vsyncEnabled = false;
1428
1429 struct timespec wait_time;
1430 wait_time.tv_sec = 0;
1431 wait_time.tv_nsec = mDisplay.mVsyncPeriod;
1432 const int64_t kOneRefreshNs = mDisplay.mVsyncPeriod;
1433 const int64_t kOneSecondNs = 1000ULL * 1000ULL * 1000ULL;
1434 int64_t lastTimeNs = -1;
1435 int64_t phasedWaitNs = 0;
1436 int64_t currentNs = 0;
1437
1438 while (true) {
1439 clock_gettime(CLOCK_MONOTONIC, &rt);
1440 currentNs = rt.tv_nsec + rt.tv_sec * kOneSecondNs;
1441
1442 if (lastTimeNs < 0) {
1443 phasedWaitNs = currentNs + kOneRefreshNs;
1444 } else {
1445 phasedWaitNs = kOneRefreshNs *
1446 (( currentNs - lastTimeNs) / kOneRefreshNs + 1) +
1447 lastTimeNs;
1448 }
1449
1450 wait_time.tv_sec = phasedWaitNs / kOneSecondNs;
1451 wait_time.tv_nsec = phasedWaitNs - wait_time.tv_sec * kOneSecondNs;
1452
1453 int ret;
1454 do {
1455 ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wait_time, NULL);
1456 } while (ret == -1 && errno == EINTR);
1457
1458 lastTimeNs = phasedWaitNs;
1459
1460 std::unique_lock<std::mutex> lock(mDisplay.mStateMutex);
1461 vsyncEnabled = (mDisplay.mVsyncEnabled == Vsync::Enable);
1462 lock.unlock();
1463
1464 if (!vsyncEnabled) {
1465 continue;
1466 }
1467
1468 lock.lock();
1469 const auto& callbackInfo = mDisplay.mDevice.mCallbacks[Callback::Vsync];
1470 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
1471 lock.unlock();
1472
1473 if (vsync) {
1474 vsync(callbackInfo.data, mDisplay.mId, lastTimeNs);
1475 }
1476
1477 if (rt.tv_sec - lastLogged >= logInterval) {
1478 ALOGVV("sent %d syncs in %ds", sent - lastSent, rt.tv_sec - lastLogged);
1479 lastLogged = rt.tv_sec;
1480 lastSent = sent;
1481 }
1482 ++sent;
1483 }
1484 return false;
1485 }
1486
1487
1488 // Layer functions
operator ()(const std::shared_ptr<Layer> & lhs,const std::shared_ptr<Layer> & rhs) const1489 bool EmuHWC2::SortLayersByZ::operator()(const std::shared_ptr<Layer>& lhs,
1490 const std::shared_ptr<Layer>& rhs) const {
1491 return lhs->getZ() < rhs->getZ();
1492 }
1493
1494 std::atomic<hwc2_layer_t> EmuHWC2::Layer::sNextId(1);
1495
Layer(Display & display)1496 EmuHWC2::Layer::Layer(Display& display)
1497 : mId(sNextId++),
1498 mDisplay(display),
1499 mBuffer(),
1500 mSurfaceDamage(),
1501 mBlendMode(BlendMode::None),
1502 mColor({0, 0, 0, 0}),
1503 mCompositionType(Composition::Invalid),
1504 mDisplayFrame({0, 0, -1, -1}),
1505 mPlaneAlpha(0.0f),
1506 mSidebandStream(nullptr),
1507 mSourceCrop({0.0f, 0.0f, -1.0f, -1.0f}),
1508 mTransform(Transform::None),
1509 mVisibleRegion(),
1510 mZ(0)
1511 {}
1512
setBuffer(buffer_handle_t buffer,int32_t acquireFence)1513 Error EmuHWC2::Layer::setBuffer(buffer_handle_t buffer,
1514 int32_t acquireFence) {
1515 ALOGVV("%s: Setting acquireFence %d for layer %u", __FUNCTION__,
1516 acquireFence, (uint32_t)mId);
1517 mBuffer.setBuffer(buffer);
1518 mBuffer.setFence(acquireFence);
1519 return Error::None;
1520 }
1521
setCursorPosition(int32_t,int32_t)1522 Error EmuHWC2::Layer::setCursorPosition(int32_t /*x*/,
1523 int32_t /*y*/) {
1524 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1525 if (mCompositionType != Composition::Cursor) {
1526 ALOGE("%s: CompositionType not Cursor type", __FUNCTION__);
1527 return Error::BadLayer;
1528 }
1529 //TODO
1530 return Error::None;
1531 }
1532
setSurfaceDamage(hwc_region_t)1533 Error EmuHWC2::Layer::setSurfaceDamage(hwc_region_t /*damage*/) {
1534 // Emulator redraw whole layer per frame, so ignore this.
1535 ALOGVV("%s", __FUNCTION__);
1536 return Error::None;
1537 }
1538
1539 // Layer state functions
1540
setBlendMode(int32_t mode)1541 Error EmuHWC2::Layer::setBlendMode(int32_t mode) {
1542 ALOGVV("%s %d for layer %u", __FUNCTION__, mode, (uint32_t)mId);
1543 mBlendMode = static_cast<BlendMode>(mode);
1544 return Error::None;
1545 }
1546
setColor(hwc_color_t color)1547 Error EmuHWC2::Layer::setColor(hwc_color_t color) {
1548 ALOGVV("%s layer %u %d", __FUNCTION__, (uint32_t)mId, color);
1549 mColor = color;
1550 return Error::None;
1551 }
1552
setCompositionType(int32_t type)1553 Error EmuHWC2::Layer::setCompositionType(int32_t type) {
1554 ALOGVV("%s layer %u %u", __FUNCTION__, (uint32_t)mId, type);
1555 mCompositionType = static_cast<Composition>(type);
1556 return Error::None;
1557 }
1558
setDataspace(int32_t)1559 Error EmuHWC2::Layer::setDataspace(int32_t) {
1560 ALOGVV("%s", __FUNCTION__);
1561 return Error::None;
1562 }
1563
setDisplayFrame(hwc_rect_t frame)1564 Error EmuHWC2::Layer::setDisplayFrame(hwc_rect_t frame) {
1565 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1566 mDisplayFrame = frame;
1567 return Error::None;
1568 }
1569
setPlaneAlpha(float alpha)1570 Error EmuHWC2::Layer::setPlaneAlpha(float alpha) {
1571 ALOGVV("%s layer %u %f", __FUNCTION__, (uint32_t)mId, alpha);
1572 mPlaneAlpha = alpha;
1573 return Error::None;
1574 }
1575
setSidebandStream(const native_handle_t * stream)1576 Error EmuHWC2::Layer::setSidebandStream(const native_handle_t* stream) {
1577 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1578 mSidebandStream = stream;
1579 return Error::None;
1580 }
1581
setSourceCrop(hwc_frect_t crop)1582 Error EmuHWC2::Layer::setSourceCrop(hwc_frect_t crop) {
1583 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1584 mSourceCrop = crop;
1585 return Error::None;
1586 }
1587
setTransform(int32_t transform)1588 Error EmuHWC2::Layer::setTransform(int32_t transform) {
1589 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1590 mTransform = static_cast<Transform>(transform);
1591 return Error::None;
1592 }
1593
compareRects(const hwc_rect_t & rect1,const hwc_rect_t & rect2)1594 static bool compareRects(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
1595 return rect1.left == rect2.left &&
1596 rect1.right == rect2.right &&
1597 rect1.top == rect2.top &&
1598 rect1.bottom == rect2.bottom;
1599 }
1600
setVisibleRegion(hwc_region_t visible)1601 Error EmuHWC2::Layer::setVisibleRegion(hwc_region_t visible) {
1602 ALOGVV("%s", __FUNCTION__);
1603 if ((getNumVisibleRegions() != visible.numRects) ||
1604 !std::equal(mVisibleRegion.begin(), mVisibleRegion.end(), visible.rects,
1605 compareRects)) {
1606 mVisibleRegion.resize(visible.numRects);
1607 std::copy_n(visible.rects, visible.numRects, mVisibleRegion.begin());
1608 }
1609 return Error::None;
1610 }
1611
setZ(uint32_t z)1612 Error EmuHWC2::Layer::setZ(uint32_t z) {
1613 ALOGVV("%s layer %u %d", __FUNCTION__, (uint32_t)mId, z);
1614 mZ = z;
1615 return Error::None;
1616 }
1617
1618 // Adaptor Helpers
1619
populateCapabilities()1620 void EmuHWC2::populateCapabilities() {
1621 //TODO: add Capabilities
1622 // support virtualDisplay
1623 // support sideBandStream
1624 // support backGroundColor
1625 // we should not set this for HWC2, TODO: remove
1626 // mCapabilities.insert(Capability::PresentFenceIsNotReliable);
1627 }
1628
populatePrimary()1629 int EmuHWC2::populatePrimary() {
1630 int ret = 0;
1631 auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical,
1632 mDisplayWidth, mDisplayHeight);
1633 ret = display->populatePrimaryConfigs(mDisplayWidth, mDisplayHeight,
1634 mDisplayDpiX, mDisplayDpiY);
1635 if (ret != 0) {
1636 return ret;
1637 }
1638 mDisplays.emplace(display->getId(), std::move(display));
1639 return ret;
1640 }
1641
1642 // Note "hwservicemanager." is used to avoid selinux issue
1643 #define EXTERANL_DISPLAY_PROP "hwservicemanager.external.displays"
1644
1645 // return 0 for successful, 1 if no external displays are specified
1646 // return < 0 if failed
populateSecondaryDisplays()1647 int EmuHWC2::populateSecondaryDisplays() {
1648 // this guest property, hwservicemanager.external.displays,
1649 // specifies multi-display info, with comma (,) as separator
1650 // each display has the following info:
1651 // physicalId,width,height,dpi,flags
1652 // serveral displays can be provided, e.g., following has 2 displays:
1653 // setprop hwservicemanager.external.displays 1,1200,800,120,0,2,1200,800,120,0
1654 std::vector<uint64_t> values;
1655 char displaysValue[PROPERTY_VALUE_MAX] = "";
1656 property_get(EXTERANL_DISPLAY_PROP, displaysValue, "");
1657 bool isValid = displaysValue[0] != '\0';
1658 if (isValid) {
1659 char *p = displaysValue;
1660 while (*p) {
1661 if (!isdigit(*p) && *p != ',' && *p != ' ') {
1662 isValid = false;
1663 break;
1664 }
1665 p ++;
1666 }
1667 if (!isValid) {
1668 ALOGE("Invalid syntax for the value of system prop: %s", EXTERANL_DISPLAY_PROP);
1669 }
1670 }
1671 if (!isValid) {
1672 // no external displays are specified
1673 return 1;
1674 }
1675 // parse all int values to a vector
1676 std::istringstream stream(displaysValue);
1677 for (uint64_t id; stream >> id;) {
1678 values.push_back(id);
1679 if (stream.peek() == ',')
1680 stream.ignore();
1681 }
1682 // each display has 5 values
1683 if ((values.size() % 5) != 0) {
1684 ALOGE("%s: invalid value for system property: %s", __FUNCTION__, EXTERANL_DISPLAY_PROP);
1685 return -1;
1686 }
1687 uint32_t idx = 0;
1688 while (!values.empty()) {
1689 // uint64_t physicalId = values[0];
1690 uint32_t width = values[1];
1691 uint32_t height = values[2];
1692 uint32_t dpi = values[3];
1693 // uint32_t flags = values[4];
1694 values.erase(values.begin(), values.begin() + 5);
1695
1696 Error ret = Error::None;
1697 auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical, width, height);
1698 ret = display->populateSecondaryConfigs(width, height, dpi, idx++);
1699 if (ret != Error::None) {
1700 return -2;
1701 }
1702 mDisplays.emplace(display->getId(), std::move(display));
1703 }
1704 return 0;
1705 }
1706
getDisplay(hwc2_display_t id)1707 EmuHWC2::Display* EmuHWC2::getDisplay(hwc2_display_t id) {
1708 auto display = mDisplays.find(id);
1709 if (display == mDisplays.end()) {
1710 ALOGE("Failed to get display for id=%d", (uint32_t)id);
1711 return nullptr;
1712 }
1713 return display->second.get();
1714 }
1715
getLayer(hwc2_display_t displayId,hwc2_layer_t layerId)1716 std::tuple<EmuHWC2::Layer*, Error> EmuHWC2::getLayer(
1717 hwc2_display_t displayId, hwc2_layer_t layerId) {
1718 auto display = getDisplay(displayId);
1719 if (!display) {
1720 ALOGE("%s: Fail to find display %d", __FUNCTION__, (uint32_t)displayId);
1721 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
1722 }
1723
1724 auto layerEntry = mLayers.find(layerId);
1725 if (layerEntry == mLayers.end()) {
1726 ALOGE("%s: Fail to find layer %d", __FUNCTION__, (uint32_t)layerId);
1727 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
1728 }
1729
1730 auto layer = layerEntry->second;
1731 if (layer->getDisplay().getId() != displayId) {
1732 ALOGE("%s: layer %d not belongs to display %d", __FUNCTION__,
1733 (uint32_t)layerId, (uint32_t)displayId);
1734 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
1735 }
1736 return std::make_tuple(layer.get(), Error::None);
1737 }
1738
hwc2DevOpen(const struct hw_module_t * module,const char * name,struct hw_device_t ** dev)1739 static int hwc2DevOpen(const struct hw_module_t *module, const char *name,
1740 struct hw_device_t **dev) {
1741 ALOGVV("%s ", __FUNCTION__);
1742 if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
1743 ALOGE("Invalid module name- %s", name);
1744 return -EINVAL;
1745 }
1746
1747 EmuHWC2* ctx = new EmuHWC2();
1748 if (!ctx) {
1749 ALOGE("Failed to allocate EmuHWC2");
1750 return -ENOMEM;
1751 }
1752 int ret = ctx->populatePrimary();
1753 if (ret != 0) {
1754 ALOGE("Failed to populate primary display");
1755 return ret;
1756 }
1757
1758 ret = ctx->populateSecondaryDisplays();
1759 if (ret < 0) {
1760 ALOGE("Failed to populate secondary displays");
1761 return ret;
1762 }
1763
1764 ctx->common.module = const_cast<hw_module_t *>(module);
1765 *dev = &ctx->common;
1766 return 0;
1767 }
1768 }
1769
1770 static struct hw_module_methods_t hwc2_module_methods = {
1771 .open = android::hwc2DevOpen
1772 };
1773
1774 hw_module_t HAL_MODULE_INFO_SYM = {
1775 .tag = HARDWARE_MODULE_TAG,
1776 .version_major = 2,
1777 .version_minor = 0,
1778 .id = HWC_HARDWARE_MODULE_ID,
1779 .name = "goldfish HWC2 module",
1780 .author = "The Android Open Source Project",
1781 .methods = &hwc2_module_methods,
1782 .dso = NULL,
1783 .reserved = {0},
1784 };
1785