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