• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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