इस आसान फ़्रेमवर्क की सेवा की मदद से, वेंडर हर प्रोसेस में, बिना लिंक किए एचएएल लागू करने के लिए, SurfaceFlinger/EGL का इस्तेमाल किया जाता है है. एओएसपी इस सेवा का डिफ़ॉल्ट रूप से इस्तेमाल करने की सुविधा देता है, जो कि काम करते हों. हालांकि, यह सेवा देने के लिए वेंडर को एपीआई लागू करने होंगे लोगों की दिलचस्पी बढ़ाई जा सकती है.
package android.frameworks.automotive.display@1.0; import android.hardware.graphics.bufferqueue@2.0::IGraphicBufferProducer; interface IAutomotiveDisplayProxyService { /** * Gets an IGraphicBufferProducer instance from the service. * * @param id Target's stable display identifier * * @return igbp Returns an IGraphicBufferProducer object, that can be * converted to an ANativeWindow object. */ getIGraphicBufferProducer(uint64_t id) generates (IGraphicBufferProducer igbp); /** * Sets the ANativeWindow, which is associated with the * IGraphicBufferProducer, to be visible and to take over the display. * * @param id Target display ID * * @return success Returns true on success. */ showWindow(uint64_t id) generates (bool success); /** * Sets the ANativeWindow, which is associated with the * IGraphicBufferProducer, to be invisible and to release the control * over display. * * @param id Target display ID * * @return success Returns true on success. */ hideWindow(uint64_t id) generates (bool success); /** * Returns the stable identifiers of all available displays. * * @return ids A list of stable display identifiers. */ getDisplayIdList() generates (vec<uint64_t> ids); /** * Returns the descriptor of the target display. * * @param id Stable ID of a target display. * @return cfg DisplayConfig of the active display. * @return state Current state of the active display. */ getDisplayInfo(uint64_t id) generates (HwDisplayConfig cfg, HwDisplayState state); }
इस सेवा का इस्तेमाल करने के लिए:
IAutomotiveDisplayProxyService
पाएं.android::sp<IAutomotiveDisplayProxyService> windowProxyService = IAutomotiveDisplayProxyService::getService("default"); if (windowProxyService == nullptr) { LOG(ERROR) << "Cannot use AutomotiveDisplayProxyService. Exiting."; return 1; }
- रिज़ॉल्यूशन तय करने के लिए, सेवा से किसी चालू डिसप्ले की जानकारी वापस पाएं.
// We use the first display in the list as the primary. pWindowProxy->getDisplayInfo(displayId, [this](auto dpyConfig, auto dpyState) { DisplayConfig *pConfig = (DisplayConfig*)dpyConfig.data(); mWidth = pConfig->resolution.getWidth(); mHeight = pConfig->resolution.getHeight(); ui::DisplayState* pState = (ui::DisplayState*)dpyState.data(); if (pState->orientation != ui::ROTATION_0 && pState->orientation != ui::ROTATION_180) { // rotate std::swap(mWidth, mHeight); } LOG(DEBUG) << "Display resolution is " << mWidth << " x " << mHeight; });
IGraphicBufferProducer
हार्डवेयर वापस पाएं (या,IAutomotiveDisplayProxyService
की ओर से HIDL GraphicBufferProducer (HGBP):mGfxBufferProducer = pWindowProxy->getIGraphicBufferProducer(displayId); if (mGfxBufferProducer == nullptr) { LOG(ERROR) << "Failed to get IGraphicBufferProducer from " << "IAutomotiveDisplayProxyService."; return false; }
- एपीआई का इस्तेमाल करके, वापस लाई गई HGBP से
SurfaceHolder
पाएंlibbufferqueueconverter
:mSurfaceHolder = getSurfaceFromHGBP(mGfxBufferProducer); if (mSurfaceHolder == nullptr) { LOG(ERROR) << "Failed to get a Surface from HGBP."; return false; }
- इसका इस्तेमाल करके
SurfaceHolder
को नेटिव विंडो में बदलें एपीआईlibbufferqueueconverter
:mWindow = getNativeWindow(mSurfaceHolder.get()); if (mWindow == nullptr) { LOG(ERROR) << "Failed to get a native window from Surface."; return false; }
- स्थानीय विंडो के साथ EGL विंडो सतह बनाएं और फिर रेंडर करें:
// Set up our OpenGL ES context associated with the default display mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (mDisplay == EGL_NO_DISPLAY) { LOG(ERROR) << "Failed to get egl display"; return false; } ... // Create the EGL render target surface mSurface = eglCreateWindowSurface(mDisplay, egl_config, mWindow, nullptr); if (mSurface == EGL_NO_SURFACE) { LOG(ERROR) << "eglCreateWindowSurface failed."; return false; } ...
IAutomotiveDisplayProxyService::showWindow()
को इस नंबर पर कॉल करें रेंडर किया गया व्यू, स्क्रीन पर दिखाता है. इस सेवा की प्राथमिकता सबसे ज़्यादा है और इसलिए, वर्तमान स्वामी को हमेशा स्क्रीन का नियंत्रण मिल जाता है:mAutomotiveDisplayProxyService->showWindow();
service.cpp
और GlWrapper.cpp
देखें
$ANDROID_BUILD_TOP/packages/services/Car/evs/sampleDriver/
में इसके लिए
लागू करने के बारे में ज़्यादा जानकारी.
ईवीएस एचएएल को लागू करने के लिए, इनमें अतिरिक्त लाइब्रेरी होनी चाहिए बोल्ड करें.
cc_binary { name: "android.hardware.automotive.evs@1.1-sample", vendor: true, srcs: [ ... ], shared_libs: [ ... "libbufferqueueconverter", "android.hidl.token@1.0-utils", "android.frameworks.automotive.display@1.0", "android.hardware.graphics.bufferqueue@1.0", "android.hardware.graphics.bufferqueue@2.0", ],
मल्टी-डिसप्ले की सुविधा
डिवाइस की गिनती दिखाना और डिसप्ले की जानकारी पाना
कैमरा डिवाइस की गिनती की तरह ही, ईवीएस फ़्रेमवर्क इन कामों के लिए
उपलब्ध डिसप्ले की सूची बनाएं.
स्टैटिक डिसप्ले आइडेंटिफ़ायर, एक टाइप-लंबे आइडेंटिफ़ायर को कोड में बदलता है.
पोर्ट की जानकारी को लोअर बाइट में और Extended Display IDentification
Data
को ऊपरी बिट में शामिल करता है.
IAutomotiveDisplayProxyService::getDisplayIdList()
नतीजे के तौर पर सूची दिखाता है
स्थानीय डिसप्ले के डिसप्ले आईडी, जो ईवीएस सेवा के लिए उपलब्ध हैं,
और IEvsEnumerator::getDisplayIdList()
, डिसप्ले की सूची दिखाता है
जिन पोर्ट का पता चला है वे कनेक्ट हैं. सूची में पहला आईडी हमेशा इनमें से होता है
प्राइमरी डिसप्ले है.
interface IEvsEnumerator extends @1.0::IEvsEnumerator { ... /** * Returns a list of all EVS displays available to the system * * @return displayIds Identifiers of available displays. */ getDisplayIdList() generates (vec<uint8_t> displayIds); };
टारगेट डिसप्ले डिवाइस खोलें
ईवीएस ऐप्लिकेशन, टारगेट डिसप्ले के साथ IEvsEnumerator::openDisplay_1_1() को कॉल करता है पोर्ट नंबर:
android::sp<IEvsDisplay> pDisplay = pEvs->openDisplay_1_1(displayId); if (pDisplay.get() == nullptr) { LOG(ERROR) << "EVS Display unavailable. Exiting."; return 1; }
ध्यान दें: एक बार में सिर्फ़ एक डिसप्ले का इस्तेमाल किया जा सकता है, इसका मतलब है कि जब कोई दूसरा ईवीएस क्लाइंट दिखता है, तो मौजूदा ईवीएस क्लाइंट अपना डिसप्ले नहीं दिखाता है डिसप्ले खोलने के अनुरोध करता है, भले ही वे एक जैसे न हों.