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 <log/log.h>
25 #include <sync/sync.h>
26
27 #include <EGL/egl.h>
28 #include <EGL/eglext.h>
29
30 #include "../egl/goldfish_sync.h"
31
32 #include "ThreadInfo.h"
33
34 #if defined(LOG_NNDEBUG) && LOG_NNDEBUG == 0
35 #define ALOGVV ALOGV
36 #else
37 #define ALOGVV(...) ((void)0)
38 #endif
39
40 template <typename PFN, typename T>
asFP(T function)41 static hwc2_function_pointer_t asFP(T function)
42 {
43 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
44 return reinterpret_cast<hwc2_function_pointer_t>(function);
45 }
46
47 static HostConnection *sHostCon = nullptr;
48
createOrGetHostConnection()49 static HostConnection* createOrGetHostConnection() {
50 if (!sHostCon) {
51 sHostCon = HostConnection::createUnique();
52 }
53 return sHostCon;
54 }
55
56 #define DEFINE_AND_VALIDATE_HOST_CONNECTION \
57 HostConnection *hostCon = createOrGetHostConnection(); \
58 if (!hostCon) { \
59 ALOGE("EmuHWC2: Failed to get host connection\n"); \
60 return Error::NoResources; \
61 } \
62 ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
63 if (!rcEnc) { \
64 ALOGE("EmuHWC2: Failed to get renderControl encoder context\n"); \
65 return Error::NoResources; \
66 }
67
68
69 using namespace HWC2;
70
71 namespace android {
72
EmuHWC2()73 EmuHWC2::EmuHWC2()
74 : mStateMutex()
75 {
76 common.tag = HARDWARE_DEVICE_TAG;
77 common.version = HWC_DEVICE_API_VERSION_2_0;
78 common.close = closeHook;
79 getCapabilities = getCapabilitiesHook;
80 getFunction = getFunctionHook;
81 populateCapabilities();
82 }
83
doGetCapabilities(uint32_t * outCount,int32_t * outCapabilities)84 void EmuHWC2::doGetCapabilities(uint32_t* outCount, int32_t* outCapabilities) {
85 if (outCapabilities == nullptr) {
86 *outCount = mCapabilities.size();
87 return;
88 }
89
90 auto capabilityIter = mCapabilities.cbegin();
91 for (size_t i = 0; i < *outCount; ++i) {
92 if (capabilityIter == mCapabilities.cend()) {
93 return;
94 }
95 outCapabilities[i] = static_cast<int32_t>(*capabilityIter);
96 ++capabilityIter;
97 }
98 }
99
doGetFunction(FunctionDescriptor descriptor)100 hwc2_function_pointer_t EmuHWC2::doGetFunction(
101 FunctionDescriptor descriptor) {
102 switch(descriptor) {
103 case FunctionDescriptor::CreateVirtualDisplay:
104 return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
105 createVirtualDisplayHook);
106 case FunctionDescriptor::DestroyVirtualDisplay:
107 return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
108 destroyVirtualDisplayHook);
109 case FunctionDescriptor::Dump:
110 return asFP<HWC2_PFN_DUMP>(dumpHook);
111 case FunctionDescriptor::GetMaxVirtualDisplayCount:
112 return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
113 getMaxVirtualDisplayCountHook);
114 case FunctionDescriptor::RegisterCallback:
115 return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
116
117 // Display functions
118 case FunctionDescriptor::AcceptDisplayChanges:
119 return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
120 displayHook<decltype(&Display::acceptChanges),
121 &Display::acceptChanges>);
122 case FunctionDescriptor::CreateLayer:
123 return asFP<HWC2_PFN_CREATE_LAYER>(
124 displayHook<decltype(&Display::createLayer),
125 &Display::createLayer, hwc2_layer_t*>);
126 case FunctionDescriptor::DestroyLayer:
127 return asFP<HWC2_PFN_DESTROY_LAYER>(
128 displayHook<decltype(&Display::destroyLayer),
129 &Display::destroyLayer, hwc2_layer_t>);
130 case FunctionDescriptor::GetActiveConfig:
131 return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
132 displayHook<decltype(&Display::getActiveConfig),
133 &Display::getActiveConfig, hwc2_config_t*>);
134 case FunctionDescriptor::GetChangedCompositionTypes:
135 return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
136 displayHook<decltype(&Display::getChangedCompositionTypes),
137 &Display::getChangedCompositionTypes, uint32_t*,
138 hwc2_layer_t*, int32_t*>);
139 case FunctionDescriptor::GetColorModes:
140 return asFP<HWC2_PFN_GET_COLOR_MODES>(
141 displayHook<decltype(&Display::getColorModes),
142 &Display::getColorModes, uint32_t*, int32_t*>);
143 case FunctionDescriptor::GetDisplayAttribute:
144 return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
145 displayHook<decltype(&Display::getDisplayAttribute),
146 &Display::getDisplayAttribute, hwc2_config_t,
147 int32_t, int32_t*>);
148 case FunctionDescriptor::GetDisplayConfigs:
149 return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
150 displayHook<decltype(&Display::getConfigs),
151 &Display::getConfigs, uint32_t*, hwc2_config_t*>);
152 case FunctionDescriptor::GetDisplayName:
153 return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
154 displayHook<decltype(&Display::getName),
155 &Display::getName, uint32_t*, char*>);
156 case FunctionDescriptor::GetDisplayRequests:
157 return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
158 displayHook<decltype(&Display::getRequests),
159 &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*,
160 int32_t*>);
161 case FunctionDescriptor::GetDisplayType:
162 return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
163 displayHook<decltype(&Display::getType),
164 &Display::getType, int32_t*>);
165 case FunctionDescriptor::GetDozeSupport:
166 return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
167 displayHook<decltype(&Display::getDozeSupport),
168 &Display::getDozeSupport, int32_t*>);
169 case FunctionDescriptor::GetHdrCapabilities:
170 return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
171 displayHook<decltype(&Display::getHdrCapabilities),
172 &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
173 float*, float*>);
174 case FunctionDescriptor::GetReleaseFences:
175 return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
176 displayHook<decltype(&Display::getReleaseFences),
177 &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
178 int32_t*>);
179 case FunctionDescriptor::PresentDisplay:
180 return asFP<HWC2_PFN_PRESENT_DISPLAY>(
181 displayHook<decltype(&Display::present),
182 &Display::present, int32_t*>);
183 case FunctionDescriptor::SetActiveConfig:
184 return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
185 displayHook<decltype(&Display::setActiveConfig),
186 &Display::setActiveConfig, hwc2_config_t>);
187 case FunctionDescriptor::SetClientTarget:
188 return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
189 displayHook<decltype(&Display::setClientTarget),
190 &Display::setClientTarget, buffer_handle_t, int32_t,
191 int32_t, hwc_region_t>);
192 case FunctionDescriptor::SetColorMode:
193 return asFP<HWC2_PFN_SET_COLOR_MODE>(
194 displayHook<decltype(&Display::setColorMode),
195 &Display::setColorMode, int32_t>);
196 case FunctionDescriptor::SetColorTransform:
197 return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(
198 displayHook<decltype(&Display::setColorTransform),
199 &Display::setColorTransform, const float*, int32_t>);
200 case FunctionDescriptor::SetOutputBuffer:
201 return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
202 displayHook<decltype(&Display::setOutputBuffer),
203 &Display::setOutputBuffer, buffer_handle_t, int32_t>);
204 case FunctionDescriptor::SetPowerMode:
205 return asFP<HWC2_PFN_SET_POWER_MODE>(
206 displayHook<decltype(&Display::setPowerMode),
207 &Display::setPowerMode, int32_t>);
208 case FunctionDescriptor::SetVsyncEnabled:
209 return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(
210 displayHook<decltype(&Display::setVsyncEnabled),
211 &Display::setVsyncEnabled, int32_t>);
212 case FunctionDescriptor::ValidateDisplay:
213 return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
214 displayHook<decltype(&Display::validate),
215 &Display::validate, uint32_t*, uint32_t*>);
216 case FunctionDescriptor::GetClientTargetSupport:
217 return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
218 displayHook<decltype(&Display::getClientTargetSupport),
219 &Display::getClientTargetSupport, uint32_t, uint32_t,
220 int32_t, int32_t>);
221 // Layer functions
222 case FunctionDescriptor::SetCursorPosition:
223 return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
224 layerHook<decltype(&Layer::setCursorPosition),
225 &Layer::setCursorPosition, int32_t, int32_t>);
226 case FunctionDescriptor::SetLayerBuffer:
227 return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
228 layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
229 buffer_handle_t, int32_t>);
230 case FunctionDescriptor::SetLayerSurfaceDamage:
231 return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
232 layerHook<decltype(&Layer::setSurfaceDamage),
233 &Layer::setSurfaceDamage, hwc_region_t>);
234
235 // Layer state functions
236 case FunctionDescriptor::SetLayerBlendMode:
237 return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
238 layerHook<decltype(&Layer::setBlendMode),
239 &Layer::setBlendMode, int32_t>);
240 case FunctionDescriptor::SetLayerColor:
241 return asFP<HWC2_PFN_SET_LAYER_COLOR>(
242 layerHook<decltype(&Layer::setColor), &Layer::setColor,
243 hwc_color_t>);
244 case FunctionDescriptor::SetLayerCompositionType:
245 return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
246 layerHook<decltype(&Layer::setCompositionType),
247 &Layer::setCompositionType, int32_t>);
248 case FunctionDescriptor::SetLayerDataspace:
249 return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(
250 layerHook<decltype(&Layer::setDataspace),
251 &Layer::setDataspace, int32_t>);
252 case FunctionDescriptor::SetLayerDisplayFrame:
253 return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
254 layerHook<decltype(&Layer::setDisplayFrame),
255 &Layer::setDisplayFrame, hwc_rect_t>);
256 case FunctionDescriptor::SetLayerPlaneAlpha:
257 return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
258 layerHook<decltype(&Layer::setPlaneAlpha),
259 &Layer::setPlaneAlpha, float>);
260 case FunctionDescriptor::SetLayerSidebandStream:
261 return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
262 layerHook<decltype(&Layer::setSidebandStream),
263 &Layer::setSidebandStream, const native_handle_t*>);
264 case FunctionDescriptor::SetLayerSourceCrop:
265 return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
266 layerHook<decltype(&Layer::setSourceCrop),
267 &Layer::setSourceCrop, hwc_frect_t>);
268 case FunctionDescriptor::SetLayerTransform:
269 return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(
270 layerHook<decltype(&Layer::setTransform),
271 &Layer::setTransform, int32_t>);
272 case FunctionDescriptor::SetLayerVisibleRegion:
273 return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
274 layerHook<decltype(&Layer::setVisibleRegion),
275 &Layer::setVisibleRegion, hwc_region_t>);
276 case FunctionDescriptor::SetLayerZOrder:
277 return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(
278 displayHook<decltype(&Display::updateLayerZ),
279 &Display::updateLayerZ, hwc2_layer_t, uint32_t>);
280
281 default:
282 ALOGE("doGetFunction: Unknown function descriptor: %d (%s)",
283 static_cast<int32_t>(descriptor),
284 to_string(descriptor).c_str());
285 return nullptr;
286 }
287 }
288
289
290 // Device functions
291
createVirtualDisplay(uint32_t,uint32_t,int32_t *,hwc2_display_t *)292 Error EmuHWC2::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/,
293 int32_t* /*format*/, hwc2_display_t* /*outDisplay*/) {
294 ALOGVV("%s", __FUNCTION__);
295 //TODO: VirtualDisplay support
296 return Error::None;
297 }
298
destroyVirtualDisplay(hwc2_display_t)299 Error EmuHWC2::destroyVirtualDisplay(hwc2_display_t /*displayId*/) {
300 ALOGVV("%s", __FUNCTION__);
301 //TODO: VirtualDisplay support
302 return Error::None;
303 }
304
dump(uint32_t *,char *)305 void EmuHWC2::dump(uint32_t* /*outSize*/, char* /*outBuffer*/) {
306 ALOGVV("%s", __FUNCTION__);
307 //TODO:
308 return;
309 }
310
getMaxVirtualDisplayCount()311 uint32_t EmuHWC2::getMaxVirtualDisplayCount() {
312 ALOGVV("%s", __FUNCTION__);
313 //TODO: VirtualDisplay support
314 return 0;
315 }
316
isValid(Callback descriptor)317 static bool isValid(Callback descriptor) {
318 switch (descriptor) {
319 case Callback::Hotplug: // Fall-through
320 case Callback::Refresh: // Fall-through
321 case Callback::Vsync: return true;
322 default: return false;
323 }
324 }
325
registerCallback(Callback descriptor,hwc2_callback_data_t callbackData,hwc2_function_pointer_t pointer)326 Error EmuHWC2::registerCallback(Callback descriptor,
327 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
328 ALOGVV("%s", __FUNCTION__);
329 if (!isValid(descriptor)) {
330 ALOGE("registerCallback: Unkown function descriptor: %d",
331 static_cast<int32_t>(descriptor));
332 return Error::BadParameter;
333 }
334 ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(),
335 callbackData, pointer);
336
337 std::unique_lock<std::mutex> lock(mStateMutex);
338
339 if (pointer != nullptr) {
340 mCallbacks[descriptor] = {callbackData, pointer};
341 }
342 else {
343 ALOGV("unregisterCallback(%s)", to_string(descriptor).c_str());
344 mCallbacks.erase(descriptor);
345 return Error::None;
346 }
347
348 // Callback without the state lock held
349 if (descriptor == Callback::Hotplug) {
350 lock.unlock();
351 auto hotplug = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
352 hotplug(callbackData, 0, static_cast<int32_t>(Connection::Connected));
353 }
354
355 return Error::None;
356 }
357
358 //Gralloc Functions
GrallocModule()359 EmuHWC2::GrallocModule::GrallocModule() {
360 int ret;
361
362 ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mHw);
363 assert(ret == 0 && "Gralloc moudle not found");
364 mGralloc = reinterpret_cast<const gralloc_module_t*>(mHw);
365
366 ret = framebuffer_open(mHw, &mFbDev);
367 assert(ret == 0 && "Fail to open FrameBuffer device");
368 }
369
~GrallocModule()370 EmuHWC2::GrallocModule::~GrallocModule() {
371 if (mHandle != nullptr) {
372 mGralloc->unregisterBuffer(mGralloc, mHandle);
373 mAllocDev->free(mAllocDev, mHandle);
374 ALOGI("free targetCb %d", ((cb_handle_t*)(mHandle))->hostHandle);
375 }
376 }
377
getTargetCb()378 uint32_t EmuHWC2::GrallocModule::getTargetCb() {
379 if (mHandle == nullptr) {
380 int ret, stride;
381 ret = gralloc_open(mHw, &mAllocDev);
382 assert(ret == 0 && "Fail to open GPU device");
383 ret = mAllocDev->alloc(mAllocDev,
384 mFbDev->width, mFbDev->height, mFbDev->format,
385 GRALLOC_USAGE_HW_COMPOSER|GRALLOC_USAGE_HW_RENDER,
386 &mHandle, &stride);
387 assert(ret == 0 && "Fail to allocate target ColorBuffer");
388 mGralloc->registerBuffer(mGralloc, mHandle);
389 ALOGI("targetCb %d", reinterpret_cast<const cb_handle_t*>(mHandle)
390 ->hostHandle);
391 }
392 return reinterpret_cast<const cb_handle_t*>(mHandle)->hostHandle;
393 }
394
395 // Display functions
396
397 std::atomic<hwc2_display_t> EmuHWC2::Display::sNextId(0);
398
Display(EmuHWC2 & device,DisplayType type)399 EmuHWC2::Display::Display(EmuHWC2& device, DisplayType type)
400 : mDevice(device),
401 mId(sNextId++),
402 mName(),
403 mType(type),
404 mPowerMode(PowerMode::Off),
405 mVsyncEnabled(Vsync::Invalid),
406 mVsyncPeriod(1000*1000*1000/60), // vsync is 60 hz
407 mVsyncThread(*this),
408 mClientTarget(),
409 mChanges(),
410 mLayers(),
411 mReleaseLayerIds(),
412 mReleaseFences(),
413 mConfigs(),
414 mActiveConfig(nullptr),
415 mColorModes(),
416 mSetColorTransform(false),
417 mStateMutex()
418 {
419 mVsyncThread.run("", HAL_PRIORITY_URGENT_DISPLAY);
420 }
421
acceptChanges()422 Error EmuHWC2::Display::acceptChanges() {
423 ALOGVV("%s: displayId %u", __FUNCTION__, (uint32_t)mId);
424 std::unique_lock<std::mutex> lock(mStateMutex);
425
426 if (!mChanges) {
427 ALOGW("%s: displayId %u acceptChanges failed, not validated",
428 __FUNCTION__, (uint32_t)mId);
429 return Error::NotValidated;
430 }
431
432
433 for (auto& change : mChanges->getTypeChanges()) {
434 auto layerId = change.first;
435 auto type = change.second;
436 if (mDevice.mLayers.count(layerId) == 0) {
437 // This should never happen but somehow does.
438 ALOGW("Cannot accept change for unknown layer %u",
439 (uint32_t)layerId);
440 continue;
441 }
442 auto layer = mDevice.mLayers[layerId];
443 layer->setCompositionType((int32_t)type);
444 }
445
446 mChanges->clearTypeChanges();
447 return Error::None;
448 }
449
createLayer(hwc2_layer_t * outLayerId)450 Error EmuHWC2::Display::createLayer(hwc2_layer_t* outLayerId) {
451 ALOGVV("%s", __FUNCTION__);
452 std::unique_lock<std::mutex> lock(mStateMutex);
453
454 auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
455 mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
456 *outLayerId = layer->getId();
457 ALOGV("%s: Display %u created layer %u", __FUNCTION__, (uint32_t)mId,
458 (uint32_t)(*outLayerId));
459 return Error::None;
460 }
461
destroyLayer(hwc2_layer_t layerId)462 Error EmuHWC2::Display::destroyLayer(hwc2_layer_t layerId) {
463 ALOGVV("%s", __FUNCTION__);
464 std::unique_lock<std::mutex> lock(mStateMutex);
465
466 const auto mapLayer = mDevice.mLayers.find(layerId);
467 if (mapLayer == mDevice.mLayers.end()) {
468 ALOGW("%s failed: no such layer, displayId %u layerId %u",
469 __FUNCTION__, (uint32_t)mId, (uint32_t)layerId);
470 return Error::BadLayer;
471 }
472 const auto layer = mapLayer->second;
473 mDevice.mLayers.erase(mapLayer);
474 const auto zRange = mLayers.equal_range(layer);
475 for (auto current = zRange.first; current != zRange.second; ++current) {
476 if (**current == *layer) {
477 current = mLayers.erase(current);
478 break;
479 }
480 }
481 ALOGV("%s: displayId %d layerId %d", __FUNCTION__, (uint32_t)mId,
482 (uint32_t)layerId);
483 return Error::None;
484 }
485
getActiveConfig(hwc2_config_t * outConfig)486 Error EmuHWC2::Display::getActiveConfig(hwc2_config_t* outConfig) {
487 ALOGVV("%s", __FUNCTION__);
488 std::unique_lock<std::mutex> lock(mStateMutex);
489
490 if (!mActiveConfig) {
491 ALOGW("%s: displayId %d %s", __FUNCTION__, (uint32_t)mId,
492 to_string(Error::BadConfig).c_str());
493 return Error::BadConfig;
494 }
495 auto configId = mActiveConfig->getId();
496 ALOGV("%s: displayId %d configId %d", __FUNCTION__,
497 (uint32_t)mId, (uint32_t)configId);
498 *outConfig = configId;
499 return Error::None;
500 }
501
getDisplayAttribute(hwc2_config_t configId,int32_t attribute,int32_t * outValue)502 Error EmuHWC2::Display::getDisplayAttribute(hwc2_config_t configId,
503 int32_t attribute, int32_t* outValue) {
504 ALOGVV("%s", __FUNCTION__);
505 std::unique_lock<std::mutex> lock(mStateMutex);
506
507 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
508 ALOGW("%s: bad config (%u %u)", __FUNCTION__, (uint32_t)mId, configId);
509 return Error::BadConfig;
510 }
511 *outValue = mConfigs[configId]->getAttribute((Attribute)attribute);
512 ALOGV("%s: (%d %d) %s --> %d", __FUNCTION__,
513 (uint32_t)mId, (uint32_t)configId,
514 to_string((Attribute)attribute).c_str(), *outValue);
515 return Error::None;
516 }
517
getChangedCompositionTypes(uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outTypes)518 Error EmuHWC2::Display::getChangedCompositionTypes(
519 uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) {
520 ALOGVV("%s", __FUNCTION__);
521 std::unique_lock<std::mutex> lock(mStateMutex);
522
523 if (!mChanges) {
524 ALOGW("display %u getChangedCompositionTypes failed: not validated",
525 (uint32_t)mId);
526 return Error::NotValidated;
527 }
528
529 if ((outLayers == nullptr) || (outTypes == nullptr)) {
530 *outNumElements = mChanges->getTypeChanges().size();
531 return Error::None;
532 }
533
534 uint32_t numWritten = 0;
535 for (const auto& element : mChanges->getTypeChanges()) {
536 if (numWritten == *outNumElements) {
537 break;
538 }
539 auto layerId = element.first;
540 auto intType = static_cast<int32_t>(element.second);
541 ALOGV("%s: Adding layer %u %s", __FUNCTION__, (uint32_t)layerId,
542 to_string(element.second).c_str());
543 outLayers[numWritten] = layerId;
544 outTypes[numWritten] = intType;
545 ++numWritten;
546 }
547 *outNumElements = numWritten;
548 return Error::None;
549 }
550
getColorModes(uint32_t * outNumModes,int32_t * outModes)551 Error EmuHWC2::Display::getColorModes(uint32_t* outNumModes,
552 int32_t* outModes) {
553 ALOGVV("%s", __FUNCTION__);
554 std::unique_lock<std::mutex> lock(mStateMutex);
555
556 if (!outModes) {
557 *outNumModes = mColorModes.size();
558 return Error::None;
559 }
560
561 // we only support HAL_COLOR_MODE_NATIVE so far
562 uint32_t numModes = std::min(*outNumModes,
563 static_cast<uint32_t>(mColorModes.size()));
564 std::copy_n(mColorModes.cbegin(), numModes, outModes);
565 *outNumModes = numModes;
566 return Error::None;
567 }
568
getConfigs(uint32_t * outNumConfigs,hwc2_config_t * outConfigs)569 Error EmuHWC2::Display::getConfigs(uint32_t* outNumConfigs,
570 hwc2_config_t* outConfigs) {
571 ALOGVV("%s", __FUNCTION__);
572 std::unique_lock<std::mutex> lock(mStateMutex);
573
574 if (!outConfigs) {
575 *outNumConfigs = mConfigs.size();
576 return Error::None;
577 }
578 uint32_t numWritten = 0;
579 for (const auto config : mConfigs) {
580 if (numWritten == *outNumConfigs) {
581 break;
582 }
583 outConfigs[numWritten] = config->getId();
584 ++numWritten;
585 }
586 *outNumConfigs = numWritten;
587 return Error::None;
588 }
589
getDozeSupport(int32_t * outSupport)590 Error EmuHWC2::Display::getDozeSupport(int32_t* outSupport) {
591 ALOGVV("%s", __FUNCTION__);
592 // We don't support so far
593 *outSupport = 0;
594 return Error::None;
595 }
596
getHdrCapabilities(uint32_t * outNumTypes,int32_t *,float *,float *,float *)597 Error EmuHWC2::Display::getHdrCapabilities(uint32_t* outNumTypes,
598 int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
599 float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
600 ALOGVV("%s", __FUNCTION__);
601 // We don't support so far
602 *outNumTypes = 0;
603 return Error::None;
604 }
605
getName(uint32_t * outSize,char * outName)606 Error EmuHWC2::Display::getName(uint32_t* outSize, char* outName) {
607 ALOGVV("%s", __FUNCTION__);
608 std::unique_lock<std::mutex> lock(mStateMutex);
609
610 if (!outName) {
611 *outSize = mName.size();
612 return Error::None;
613 }
614 auto numCopied = mName.copy(outName, *outSize);
615 *outSize = numCopied;
616 return Error::None;
617 }
618
getReleaseFences(uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outFences)619 Error EmuHWC2::Display::getReleaseFences(uint32_t* outNumElements,
620 hwc2_layer_t* outLayers, int32_t* outFences) {
621 ALOGVV("%s", __FUNCTION__);
622
623 *outNumElements = mReleaseLayerIds.size();
624
625 ALOGVV("%s. Got %u elements", __FUNCTION__, *outNumElements);
626
627 if (*outNumElements && outLayers) {
628 ALOGVV("%s. export release layers", __FUNCTION__);
629 memcpy(outLayers, mReleaseLayerIds.data(),
630 sizeof(hwc2_layer_t) * (*outNumElements));
631 }
632
633 if (*outNumElements && outFences) {
634 ALOGVV("%s. export release fences", __FUNCTION__);
635 memcpy(outFences, mReleaseFences.data(),
636 sizeof(int32_t) * (*outNumElements));
637 }
638
639 return Error::None;
640 }
641
getRequests(int32_t * outDisplayRequests,uint32_t * outNumElements,hwc2_layer_t * outLayers,int32_t * outLayerRequests)642 Error EmuHWC2::Display::getRequests(int32_t* outDisplayRequests,
643 uint32_t* outNumElements, hwc2_layer_t* outLayers,
644 int32_t* outLayerRequests) {
645 ALOGVV("%s", __FUNCTION__);
646 std::unique_lock<std::mutex> lock(mStateMutex);
647
648 if (!mChanges) {
649 return Error::NotValidated;
650 }
651
652 if (outLayers == nullptr || outLayerRequests == nullptr) {
653 *outNumElements = mChanges->getNumLayerRequests();
654 return Error::None;
655 }
656
657 //TODO
658 // Display requests (HWC2::DisplayRequest) are not supported so far:
659 *outDisplayRequests = 0;
660
661 uint32_t numWritten = 0;
662 for (const auto& request : mChanges->getLayerRequests()) {
663 if (numWritten == *outNumElements) {
664 break;
665 }
666 outLayers[numWritten] = request.first;
667 outLayerRequests[numWritten] = static_cast<int32_t>(request.second);
668 ++numWritten;
669 }
670
671 return Error::None;
672 }
673
getType(int32_t * outType)674 Error EmuHWC2::Display::getType(int32_t* outType) {
675 ALOGVV("%s", __FUNCTION__);
676 std::unique_lock<std::mutex> lock(mStateMutex);
677
678 *outType = (int32_t)mType;
679 return Error::None;
680 }
681
present(int32_t * outRetireFence)682 Error EmuHWC2::Display::present(int32_t* outRetireFence) {
683 ALOGVV("%s", __FUNCTION__);
684
685 *outRetireFence = -1;
686
687 std::unique_lock<std::mutex> lock(mStateMutex);
688
689 if (!mChanges || (mChanges->getNumTypes() > 0)) {
690 ALOGE("%s display(%u) set failed: not validated", __FUNCTION__,
691 (uint32_t)mId);
692 return Error::NotValidated;
693 }
694 mChanges.reset();
695
696 DEFINE_AND_VALIDATE_HOST_CONNECTION
697 hostCon->lock();
698 bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
699 hostCon->unlock();
700
701 if (hostCompositionV1) {
702 uint32_t numLayer = 0;
703 for (auto layer: mLayers) {
704 if (layer->getCompositionType() == Composition::Device ||
705 layer->getCompositionType() == Composition::SolidColor) {
706 numLayer++;
707 }
708 }
709
710 ALOGVV("present %d layers total %u layers",
711 numLayer, (uint32_t)mLayers.size());
712
713 mReleaseLayerIds.clear();
714 mReleaseFences.clear();
715
716 if (numLayer == 0) {
717 ALOGVV("No layers, exit");
718 mGralloc->getFb()->post(mGralloc->getFb(), mClientTarget.getBuffer());
719 *outRetireFence = mClientTarget.getFence();
720 return Error::None;
721 }
722
723 if (mComposeMsg == nullptr || mComposeMsg->getLayerCnt() < numLayer) {
724 mComposeMsg.reset(new ComposeMsg(numLayer));
725 }
726
727 // Handle the composition
728 ComposeDevice* p = mComposeMsg->get();
729 ComposeLayer* l = p->layer;
730
731 for (auto layer: mLayers) {
732 if (layer->getCompositionType() != Composition::Device &&
733 layer->getCompositionType() != Composition::SolidColor) {
734 ALOGE("%s: Unsupported composition types %d layer %u",
735 __FUNCTION__, layer->getCompositionType(),
736 (uint32_t)layer->getId());
737 continue;
738 }
739 // send layer composition command to host
740 if (layer->getCompositionType() == Composition::Device) {
741 int fence = layer->getLayerBuffer().getFence();
742 mReleaseLayerIds.push_back(layer->getId());
743 if (fence != -1) {
744 int err = sync_wait(fence, 3000);
745 if (err < 0 && errno == ETIME) {
746 ALOGE("%s waited on fence %d for 3000 ms",
747 __FUNCTION__, fence);
748 }
749 close(fence);
750 }
751 else {
752 ALOGV("%s: acquire fence not set for layer %u",
753 __FUNCTION__, (uint32_t)layer->getId());
754 }
755 cb_handle_t *cb =
756 (cb_handle_t *)layer->getLayerBuffer().getBuffer();
757 if (cb != nullptr) {
758 l->cbHandle = cb->hostHandle;
759 }
760 else {
761 ALOGE("%s null buffer for layer %d", __FUNCTION__,
762 (uint32_t)layer->getId());
763 }
764 }
765 else {
766 // solidcolor has no buffer
767 l->cbHandle = 0;
768 }
769 l->composeMode = (hwc2_composition_t)layer->getCompositionType();
770 l->displayFrame = layer->getDisplayFrame();
771 l->crop = layer->getSourceCrop();
772 l->blendMode = layer->getBlendMode();
773 l->alpha = layer->getPlaneAlpha();
774 l->color = layer->getColor();
775 l->transform = layer->getTransform();
776 ALOGV(" cb %d blendmode %d alpha %f %d %d %d %d z %d"
777 " composeMode %d, transform %d",
778 l->cbHandle, l->blendMode, l->alpha,
779 l->displayFrame.left, l->displayFrame.top,
780 l->displayFrame.right, l->displayFrame.bottom,
781 layer->getZ(), l->composeMode, l->transform);
782 l++;
783 }
784 p->version = 1;
785 p->targetHandle = mGralloc->getTargetCb();
786 p->numLayers = numLayer;
787
788 hostCon->lock();
789 rcEnc->rcCompose(rcEnc,
790 sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer),
791 (void *)p);
792 hostCon->unlock();
793
794 // Send a retire fence and use it as the release fence for all layers,
795 // since media expects it
796 EGLint attribs[] = { EGL_SYNC_NATIVE_FENCE_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID };
797
798 uint64_t sync_handle, thread_handle;
799 int retire_fd;
800
801 hostCon->lock();
802 rcEnc->rcCreateSyncKHR(rcEnc, EGL_SYNC_NATIVE_FENCE_ANDROID,
803 attribs, 2 * sizeof(EGLint), true /* destroy when signaled */,
804 &sync_handle, &thread_handle);
805 hostCon->unlock();
806
807 goldfish_sync_queue_work(mSyncDeviceFd,
808 sync_handle, thread_handle, &retire_fd);
809
810 for (size_t i = 0; i < mReleaseLayerIds.size(); ++i) {
811 mReleaseFences.push_back(dup(retire_fd));
812 }
813
814 *outRetireFence = dup(retire_fd);
815 close(retire_fd);
816 hostCon->lock();
817 rcEnc->rcDestroySyncKHR(rcEnc, sync_handle);
818 hostCon->unlock();
819 } else {
820 // we set all layers Composition::Client, so do nothing.
821 mGralloc->getFb()->post(mGralloc->getFb(), mClientTarget.getBuffer());
822 *outRetireFence = mClientTarget.getFence();
823 ALOGV("%s fallback to post, returns outRetireFence %d",
824 __FUNCTION__, *outRetireFence);
825 }
826
827 return Error::None;
828 }
829
setActiveConfig(hwc2_config_t configId)830 Error EmuHWC2::Display::setActiveConfig(hwc2_config_t configId) {
831 ALOGVV("%s %u", __FUNCTION__, (uint32_t)configId);
832 std::unique_lock<std::mutex> lock(mStateMutex);
833
834 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
835 ALOGW("%s: bad config (%u %u)", __FUNCTION__, (uint32_t)mId,
836 (uint32_t)configId);
837 return Error::BadConfig;
838 }
839 auto config = mConfigs[configId];
840 if (config == mActiveConfig) {
841 return Error::None;
842 }
843
844 mActiveConfig = config;
845 return Error::None;
846 }
847
setClientTarget(buffer_handle_t target,int32_t acquireFence,int32_t,hwc_region_t)848 Error EmuHWC2::Display::setClientTarget(buffer_handle_t target,
849 int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
850 ALOGVV("%s", __FUNCTION__);
851
852 cb_handle_t *cb =
853 (cb_handle_t *)target;
854 ALOGV("%s: display(%u) buffer handle %p cb %d, acquireFence %d", __FUNCTION__,
855 (uint32_t)mId, target, cb->hostHandle, acquireFence);
856 std::unique_lock<std::mutex> lock(mStateMutex);
857 mClientTarget.setBuffer(target);
858 mClientTarget.setFence(acquireFence);
859 return Error::None;
860 }
861
setColorMode(int32_t intMode)862 Error EmuHWC2::Display::setColorMode(int32_t intMode) {
863 ALOGVV("%s %d", __FUNCTION__, intMode);
864 std::unique_lock<std::mutex> lock(mStateMutex);
865
866 auto mode = static_cast<android_color_mode_t>(intMode);
867 ALOGV("%s: (display %u mode %d)", __FUNCTION__, (uint32_t)mId, intMode);
868 if (mode == mActiveColorMode) {
869 return Error::None;
870 }
871 if (mColorModes.count(mode) == 0) {
872 ALOGE("%s: display %d Mode %d not found in mColorModes",
873 __FUNCTION__, (uint32_t)mId, intMode);
874 return Error::Unsupported;
875 }
876 mActiveColorMode = mode;
877 return Error::None;
878 }
879
setColorTransform(const float *,int32_t hint)880 Error EmuHWC2::Display::setColorTransform(const float* /*matrix*/,
881 int32_t hint) {
882 ALOGVV("%s hint %d", __FUNCTION__, hint);
883 std::unique_lock<std::mutex> lock(mStateMutex);
884 //we force client composition if this is set
885 if (hint == 0 ) {
886 mSetColorTransform = false;
887 }
888 else {
889 mSetColorTransform = true;
890 }
891 return Error::None;
892 }
893
setOutputBuffer(buffer_handle_t,int32_t)894 Error EmuHWC2::Display::setOutputBuffer(buffer_handle_t /*buffer*/,
895 int32_t /*releaseFence*/) {
896 ALOGVV("%s", __FUNCTION__);
897 //TODO: for virtual display
898 return Error::None;
899 }
900
isValid(PowerMode mode)901 static bool isValid(PowerMode mode) {
902 switch (mode) {
903 case PowerMode::Off: // Fall-through
904 case PowerMode::DozeSuspend: // Fall-through
905 case PowerMode::Doze: // Fall-through
906 case PowerMode::On: return true;
907 default: return false;
908 }
909 }
910
setPowerMode(int32_t intMode)911 Error EmuHWC2::Display::setPowerMode(int32_t intMode) {
912 ALOGVV("%s", __FUNCTION__);
913 // Emulator always set screen ON
914 PowerMode mode = static_cast<PowerMode>(intMode);
915 if (!isValid(mode)) {
916 return Error::BadParameter;
917 }
918 if (mode == mPowerMode) {
919 return Error::None;
920 }
921 std::unique_lock<std::mutex> lock(mStateMutex);
922
923 ALOGV("%s: (display %u mode %s)", __FUNCTION__,
924 (uint32_t)mId, to_string(mode).c_str());
925 mPowerMode = mode;
926 return Error::None;
927 }
928
isValid(Vsync enable)929 static bool isValid(Vsync enable) {
930 switch (enable) {
931 case Vsync::Enable: // Fall-through
932 case Vsync::Disable: return true;
933 case Vsync::Invalid: return false;
934 }
935 }
936
setVsyncEnabled(int32_t intEnable)937 Error EmuHWC2::Display::setVsyncEnabled(int32_t intEnable) {
938 ALOGVV("%s %d", __FUNCTION__, intEnable);
939 Vsync enable = static_cast<Vsync>(intEnable);
940 if (!isValid(enable)) {
941 return Error::BadParameter;
942 }
943 if (enable == mVsyncEnabled) {
944 return Error::None;
945 }
946
947 std::unique_lock<std::mutex> lock(mStateMutex);
948
949 mVsyncEnabled = enable;
950 return Error::None;
951 }
952
validate(uint32_t * outNumTypes,uint32_t * outNumRequests)953 Error EmuHWC2::Display::validate(uint32_t* outNumTypes,
954 uint32_t* outNumRequests) {
955 ALOGVV("%s", __FUNCTION__);
956 std::unique_lock<std::mutex> lock(mStateMutex);
957
958 if (!mChanges) {
959 mChanges.reset(new Changes);
960 DEFINE_AND_VALIDATE_HOST_CONNECTION
961 hostCon->lock();
962 bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
963 hostCon->unlock();
964
965 if (hostCompositionV1) {
966 // Support Device and SolidColor, otherwise, fallback all layers
967 // to Client
968 bool fallBack = false;
969 for (auto& layer : mLayers) {
970 if (layer->getCompositionType() == Composition::Invalid) {
971 // Log error for unused layers, layer leak?
972 ALOGE("%s layer %u CompositionType(%d) not set",
973 __FUNCTION__, (uint32_t)layer->getId(),
974 layer->getCompositionType());
975 continue;
976 }
977 if (layer->getCompositionType() == Composition::Client ||
978 layer->getCompositionType() == Composition::Cursor ||
979 layer->getCompositionType() == Composition::Sideband) {
980 ALOGW("%s: layer %u CompositionType %d, fallback", __FUNCTION__,
981 (uint32_t)layer->getId(), layer->getCompositionType());
982 fallBack = true;
983 break;
984 }
985 }
986 if (mSetColorTransform) {
987 fallBack = true;
988 }
989 if (fallBack) {
990 for (auto& layer : mLayers) {
991 if (layer->getCompositionType() == Composition::Invalid) {
992 continue;
993 }
994 if (layer->getCompositionType() != Composition::Client) {
995 mChanges->addTypeChange(layer->getId(),
996 Composition::Client);
997 }
998 }
999 }
1000 }
1001 else {
1002 for (auto& layer : mLayers) {
1003 if (layer->getCompositionType() != Composition::Client) {
1004 mChanges->addTypeChange(layer->getId(),
1005 Composition::Client);
1006 }
1007 }
1008 }
1009 }
1010 else {
1011 ALOGE("Validate was called more than once!");
1012 }
1013
1014 *outNumTypes = mChanges->getNumTypes();
1015 *outNumRequests = mChanges->getNumLayerRequests();
1016 ALOGV("%s: displayId %u types %u, requests %u", __FUNCTION__,
1017 (uint32_t)mId, *outNumTypes, *outNumRequests);
1018 return *outNumTypes > 0 ? Error::HasChanges : Error::None;
1019 }
1020
updateLayerZ(hwc2_layer_t layerId,uint32_t z)1021 Error EmuHWC2::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
1022 ALOGVV("%s", __FUNCTION__);
1023 std::unique_lock<std::mutex> lock(mStateMutex);
1024
1025 const auto mapLayer = mDevice.mLayers.find(layerId);
1026 if (mapLayer == mDevice.mLayers.end()) {
1027 ALOGE("%s failed to find layer %u", __FUNCTION__, (uint32_t)mId);
1028 return Error::BadLayer;
1029 }
1030
1031 const auto layer = mapLayer->second;
1032 const auto zRange = mLayers.equal_range(layer);
1033 bool layerOnDisplay = false;
1034 for (auto current = zRange.first; current != zRange.second; ++current) {
1035 if (**current == *layer) {
1036 if ((*current)->getZ() == z) {
1037 // Don't change anything if the Z hasn't changed
1038 return Error::None;
1039 }
1040 current = mLayers.erase(current);
1041 layerOnDisplay = true;
1042 break;
1043 }
1044 }
1045
1046 if (!layerOnDisplay) {
1047 ALOGE("%s failed to find layer %u on display", __FUNCTION__,
1048 (uint32_t)mId);
1049 return Error::BadLayer;
1050 }
1051
1052 layer->setZ(z);
1053 mLayers.emplace(std::move(layer));
1054 return Error::None;
1055 }
1056
getClientTargetSupport(uint32_t width,uint32_t height,int32_t format,int32_t dataspace)1057 Error EmuHWC2::Display::getClientTargetSupport(uint32_t width, uint32_t height,
1058 int32_t format, int32_t dataspace){
1059 ALOGVV("%s", __FUNCTION__);
1060 std::unique_lock<std::mutex> lock(mStateMutex);
1061
1062 if (mActiveConfig == nullptr) {
1063 return Error::Unsupported;
1064 }
1065
1066 if (width == (uint32_t)mActiveConfig->getAttribute(Attribute::Width) &&
1067 height == (uint32_t)mActiveConfig->getAttribute(Attribute::Height) &&
1068 format == HAL_PIXEL_FORMAT_RGBA_8888 &&
1069 dataspace == HAL_DATASPACE_UNKNOWN) {
1070 return Error::None;
1071 }
1072
1073 return Error::None;
1074 }
1075
1076
populatePrimaryConfigs()1077 int EmuHWC2::Display::populatePrimaryConfigs() {
1078 ALOGVV("%s DisplayId %u", __FUNCTION__, (uint32_t)mId);
1079 std::unique_lock<std::mutex> lock(mStateMutex);
1080
1081 mGralloc.reset(new GrallocModule());
1082 auto newConfig = std::make_shared<Config>(*this);
1083 // vsync is 60 hz;
1084 newConfig->setAttribute(Attribute::VsyncPeriod, mVsyncPeriod);
1085 newConfig->setAttribute(Attribute::Width, mGralloc->getFb()->width);
1086 newConfig->setAttribute(Attribute::Height, mGralloc->getFb()->height);
1087 newConfig->setAttribute(Attribute::DpiX, mGralloc->getFb()->xdpi*1000);
1088 newConfig->setAttribute(Attribute::DpiY, mGralloc->getFb()->ydpi*1000);
1089
1090 newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
1091 ALOGV("Found new config %d: %s", (uint32_t)newConfig->getId(),
1092 newConfig->toString().c_str());
1093 mConfigs.emplace_back(std::move(newConfig));
1094
1095 // Only have single config so far, it is activeConfig
1096 mActiveConfig = mConfigs[0];
1097 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1098 mColorModes.emplace((android_color_mode_t)HAL_COLOR_MODE_NATIVE);
1099
1100 mSyncDeviceFd = goldfish_sync_open();
1101
1102 return 0;
1103 }
1104
1105
1106 // Config functions
1107
setAttribute(Attribute attribute,int32_t value)1108 void EmuHWC2::Display::Config::setAttribute(Attribute attribute,
1109 int32_t value) {
1110 mAttributes[attribute] = value;
1111 }
1112
getAttribute(Attribute attribute) const1113 int32_t EmuHWC2::Display::Config::getAttribute(Attribute attribute) const {
1114 if (mAttributes.count(attribute) == 0) {
1115 return -1;
1116 }
1117 return mAttributes.at(attribute);
1118 }
1119
toString() const1120 std::string EmuHWC2::Display::Config::toString() const {
1121 std::string output;
1122
1123 const size_t BUFFER_SIZE = 100;
1124 char buffer[BUFFER_SIZE] = {};
1125 auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
1126 "%u x %u", mAttributes.at(HWC2::Attribute::Width),
1127 mAttributes.at(HWC2::Attribute::Height));
1128 output.append(buffer, writtenBytes);
1129
1130 if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
1131 std::memset(buffer, 0, BUFFER_SIZE);
1132 writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
1133 1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
1134 output.append(buffer, writtenBytes);
1135 }
1136
1137 if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
1138 mAttributes.at(HWC2::Attribute::DpiX) != -1) {
1139 std::memset(buffer, 0, BUFFER_SIZE);
1140 writtenBytes = snprintf(buffer, BUFFER_SIZE,
1141 ", DPI: %.1f x %.1f",
1142 mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
1143 mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
1144 output.append(buffer, writtenBytes);
1145 }
1146
1147 return output;
1148 }
1149
1150
1151 // VsyncThread function
threadLoop()1152 bool EmuHWC2::Display::VsyncThread::threadLoop() {
1153 struct timespec rt;
1154 if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
1155 ALOGE("%s: error in vsync thread clock_gettime: %s",
1156 __FUNCTION__, strerror(errno));
1157 return true;
1158 }
1159 const int logInterval = 60;
1160 int64_t lastLogged = rt.tv_sec;
1161 int sent = 0;
1162 int lastSent = 0;
1163 bool vsyncEnabled = false;
1164 struct timespec wait_time;
1165 wait_time.tv_sec = 0;
1166 wait_time.tv_nsec = mDisplay.mVsyncPeriod;
1167
1168 while (true) {
1169 int err = nanosleep(&wait_time, NULL);
1170 if (err == -1) {
1171 if (errno == EINTR) {
1172 break;
1173 }
1174 ALOGE("%s: error in vsync thread: %s", __FUNCTION__, strerror(errno));
1175 }
1176
1177 std::unique_lock<std::mutex> lock(mDisplay.mStateMutex);
1178 vsyncEnabled = (mDisplay.mVsyncEnabled == Vsync::Enable);
1179 lock.unlock();
1180
1181 if (!vsyncEnabled) {
1182 continue;
1183 }
1184
1185 if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
1186 ALOGE("%s: error in vsync thread clock_gettime: %s",
1187 __FUNCTION__, strerror(errno));
1188 }
1189
1190 int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
1191
1192 lock.lock();
1193 const auto& callbackInfo = mDisplay.mDevice.mCallbacks[Callback::Vsync];
1194 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
1195 lock.unlock();
1196
1197 if (vsync) {
1198 vsync(callbackInfo.data, mDisplay.mId, timestamp);
1199 }
1200
1201 if (rt.tv_sec - lastLogged >= logInterval) {
1202 ALOGVV("sent %d syncs in %ds", sent - lastSent, rt.tv_sec - lastLogged);
1203 lastLogged = rt.tv_sec;
1204 lastSent = sent;
1205 }
1206 ++sent;
1207 }
1208 return false;
1209 }
1210
1211
1212 // Layer functions
operator ()(const std::shared_ptr<Layer> & lhs,const std::shared_ptr<Layer> & rhs) const1213 bool EmuHWC2::SortLayersByZ::operator()(const std::shared_ptr<Layer>& lhs,
1214 const std::shared_ptr<Layer>& rhs) const {
1215 return lhs->getZ() < rhs->getZ();
1216 }
1217
1218 std::atomic<hwc2_layer_t> EmuHWC2::Layer::sNextId(1);
1219
Layer(Display & display)1220 EmuHWC2::Layer::Layer(Display& display)
1221 : mId(sNextId++),
1222 mDisplay(display),
1223 mBuffer(),
1224 mSurfaceDamage(),
1225 mBlendMode(BlendMode::None),
1226 mColor({0, 0, 0, 0}),
1227 mCompositionType(Composition::Invalid),
1228 mDisplayFrame({0, 0, -1, -1}),
1229 mPlaneAlpha(0.0f),
1230 mSidebandStream(nullptr),
1231 mSourceCrop({0.0f, 0.0f, -1.0f, -1.0f}),
1232 mTransform(Transform::None),
1233 mVisibleRegion(),
1234 mZ(0)
1235 {}
1236
setBuffer(buffer_handle_t buffer,int32_t acquireFence)1237 Error EmuHWC2::Layer::setBuffer(buffer_handle_t buffer,
1238 int32_t acquireFence) {
1239 ALOGVV("%s: Setting acquireFence %d for layer %u", __FUNCTION__,
1240 acquireFence, (uint32_t)mId);
1241 mBuffer.setBuffer(buffer);
1242 mBuffer.setFence(acquireFence);
1243 return Error::None;
1244 }
1245
setCursorPosition(int32_t,int32_t)1246 Error EmuHWC2::Layer::setCursorPosition(int32_t /*x*/,
1247 int32_t /*y*/) {
1248 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1249 if (mCompositionType != Composition::Cursor) {
1250 ALOGE("%s: CompositionType not Cursor type", __FUNCTION__);
1251 return Error::BadLayer;
1252 }
1253 //TODO
1254 return Error::None;
1255 }
1256
setSurfaceDamage(hwc_region_t)1257 Error EmuHWC2::Layer::setSurfaceDamage(hwc_region_t /*damage*/) {
1258 // Emulator redraw whole layer per frame, so ignore this.
1259 ALOGVV("%s", __FUNCTION__);
1260 return Error::None;
1261 }
1262
1263 // Layer state functions
1264
setBlendMode(int32_t mode)1265 Error EmuHWC2::Layer::setBlendMode(int32_t mode) {
1266 ALOGVV("%s %d for layer %u", __FUNCTION__, mode, (uint32_t)mId);
1267 mBlendMode = static_cast<BlendMode>(mode);
1268 return Error::None;
1269 }
1270
setColor(hwc_color_t color)1271 Error EmuHWC2::Layer::setColor(hwc_color_t color) {
1272 ALOGVV("%s layer %u %d", __FUNCTION__, (uint32_t)mId, color);
1273 mColor = color;
1274 return Error::None;
1275 }
1276
setCompositionType(int32_t type)1277 Error EmuHWC2::Layer::setCompositionType(int32_t type) {
1278 ALOGVV("%s layer %u %u", __FUNCTION__, (uint32_t)mId, type);
1279 mCompositionType = static_cast<Composition>(type);
1280 return Error::None;
1281 }
1282
setDataspace(int32_t)1283 Error EmuHWC2::Layer::setDataspace(int32_t) {
1284 ALOGVV("%s", __FUNCTION__);
1285 return Error::None;
1286 }
1287
setDisplayFrame(hwc_rect_t frame)1288 Error EmuHWC2::Layer::setDisplayFrame(hwc_rect_t frame) {
1289 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1290 mDisplayFrame = frame;
1291 return Error::None;
1292 }
1293
setPlaneAlpha(float alpha)1294 Error EmuHWC2::Layer::setPlaneAlpha(float alpha) {
1295 ALOGVV("%s layer %u %f", __FUNCTION__, (uint32_t)mId, alpha);
1296 mPlaneAlpha = alpha;
1297 return Error::None;
1298 }
1299
setSidebandStream(const native_handle_t * stream)1300 Error EmuHWC2::Layer::setSidebandStream(const native_handle_t* stream) {
1301 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1302 mSidebandStream = stream;
1303 return Error::None;
1304 }
1305
setSourceCrop(hwc_frect_t crop)1306 Error EmuHWC2::Layer::setSourceCrop(hwc_frect_t crop) {
1307 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1308 mSourceCrop = crop;
1309 return Error::None;
1310 }
1311
setTransform(int32_t transform)1312 Error EmuHWC2::Layer::setTransform(int32_t transform) {
1313 ALOGVV("%s layer %u", __FUNCTION__, (uint32_t)mId);
1314 mTransform = static_cast<Transform>(transform);
1315 return Error::None;
1316 }
1317
compareRects(const hwc_rect_t & rect1,const hwc_rect_t & rect2)1318 static bool compareRects(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
1319 return rect1.left == rect2.left &&
1320 rect1.right == rect2.right &&
1321 rect1.top == rect2.top &&
1322 rect1.bottom == rect2.bottom;
1323 }
1324
setVisibleRegion(hwc_region_t visible)1325 Error EmuHWC2::Layer::setVisibleRegion(hwc_region_t visible) {
1326 ALOGVV("%s", __FUNCTION__);
1327 if ((getNumVisibleRegions() != visible.numRects) ||
1328 !std::equal(mVisibleRegion.begin(), mVisibleRegion.end(), visible.rects,
1329 compareRects)) {
1330 mVisibleRegion.resize(visible.numRects);
1331 std::copy_n(visible.rects, visible.numRects, mVisibleRegion.begin());
1332 }
1333 return Error::None;
1334 }
1335
setZ(uint32_t z)1336 Error EmuHWC2::Layer::setZ(uint32_t z) {
1337 ALOGVV("%s layer %u %d", __FUNCTION__, (uint32_t)mId, z);
1338 mZ = z;
1339 return Error::None;
1340 }
1341
1342 // Adaptor Helpers
1343
populateCapabilities()1344 void EmuHWC2::populateCapabilities() {
1345 //TODO: add Capabilities
1346 // support virtualDisplay
1347 // support sideBandStream
1348 // support backGroundColor
1349 // we should not set this for HWC2, TODO: remove
1350 // mCapabilities.insert(Capability::PresentFenceIsNotReliable);
1351 }
1352
populatePrimary()1353 int EmuHWC2::populatePrimary() {
1354 int ret = 0;
1355 auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
1356 ret = display->populatePrimaryConfigs();
1357 if (ret != 0) {
1358 return ret;
1359 }
1360 mDisplays.emplace(display->getId(), std::move(display));
1361 return ret;
1362 }
1363
getDisplay(hwc2_display_t id)1364 EmuHWC2::Display* EmuHWC2::getDisplay(hwc2_display_t id) {
1365 auto display = mDisplays.find(id);
1366 if (display == mDisplays.end()) {
1367 return nullptr;
1368 }
1369 return display->second.get();
1370 }
1371
getLayer(hwc2_display_t displayId,hwc2_layer_t layerId)1372 std::tuple<EmuHWC2::Layer*, Error> EmuHWC2::getLayer(
1373 hwc2_display_t displayId, hwc2_layer_t layerId) {
1374 auto display = getDisplay(displayId);
1375 if (!display) {
1376 ALOGE("%s: Fail to find display %d", __FUNCTION__, (uint32_t)displayId);
1377 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
1378 }
1379
1380 auto layerEntry = mLayers.find(layerId);
1381 if (layerEntry == mLayers.end()) {
1382 ALOGE("%s: Fail to find layer %d", __FUNCTION__, (uint32_t)layerId);
1383 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
1384 }
1385
1386 auto layer = layerEntry->second;
1387 if (layer->getDisplay().getId() != displayId) {
1388 ALOGE("%s: layer %d not belongs to display %d", __FUNCTION__,
1389 (uint32_t)layerId, (uint32_t)displayId);
1390 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
1391 }
1392 return std::make_tuple(layer.get(), Error::None);
1393 }
1394
hwc2DevOpen(const struct hw_module_t * module,const char * name,struct hw_device_t ** dev)1395 static int hwc2DevOpen(const struct hw_module_t *module, const char *name,
1396 struct hw_device_t **dev) {
1397 ALOGVV("%s ", __FUNCTION__);
1398 if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
1399 ALOGE("Invalid module name- %s", name);
1400 return -EINVAL;
1401 }
1402
1403 EmuHWC2* ctx = new EmuHWC2();
1404 if (!ctx) {
1405 ALOGE("Failed to allocate EmuHWC2");
1406 return -ENOMEM;
1407 }
1408 int ret = ctx->populatePrimary();
1409 if (ret != 0) {
1410 ALOGE("Failed to populate primary display");
1411 return ret;
1412 }
1413
1414 ctx->common.module = const_cast<hw_module_t *>(module);
1415 *dev = &ctx->common;
1416 return 0;
1417 }
1418 }
1419
1420 static struct hw_module_methods_t hwc2_module_methods = {
1421 .open = android::hwc2DevOpen
1422 };
1423
1424 hw_module_t HAL_MODULE_INFO_SYM = {
1425 .tag = HARDWARE_MODULE_TAG,
1426 .version_major = 2,
1427 .version_minor = 0,
1428 .id = HWC_HARDWARE_MODULE_ID,
1429 .name = "goldfish HWC2 module",
1430 .author = "The Android Open Source Project",
1431 .methods = &hwc2_module_methods,
1432 .dso = NULL,
1433 .reserved = {0},
1434 };
1435