diff --git a/services/surfaceflinger/DisplayUtils.cpp b/services/surfaceflinger/DisplayUtils.cpp index 3937df0d4..e4e2183d7 100644 --- a/services/surfaceflinger/DisplayUtils.cpp +++ b/services/surfaceflinger/DisplayUtils.cpp @@ -33,8 +33,11 @@ #include #include +#include #include +#include "RenderEngine/RenderEngine.h" +#include "DisplayHardware/FramebufferSurface.h" #include "DisplayUtils.h" #include #include @@ -88,19 +91,71 @@ HWComposer* DisplayUtils::getHWCInstance( } } -VirtualDisplaySurface* DisplayUtils::getVDSInstance(HWComposer* hwc, int32_t hwcDisplayId, - sp currentStateSurface, sp bqProducer, +void DisplayUtils::initVDSInstance(HWComposer* hwc, int32_t hwcDisplayId, + sp currentStateSurface, sp &dispSurface, + sp &producer, sp bqProducer, sp bqConsumer, String8 currentStateDisplayName, - bool currentStateIsSecure) + bool currentStateIsSecure, int currentStateType) { if(sUseExtendedImpls) { - return new ExVirtualDisplaySurface(*hwc, hwcDisplayId, currentStateSurface, bqProducer, - bqConsumer, currentStateDisplayName, currentStateIsSecure); + if(hwc->isVDSEnabled()) { + VirtualDisplaySurface* vds = new ExVirtualDisplaySurface(*hwc, hwcDisplayId, + currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName, + currentStateIsSecure); + dispSurface = vds; + producer = vds; + } else if(!createV4L2BasedVirtualDisplay(hwc, hwcDisplayId, dispSurface, producer, + currentStateSurface, bqProducer, bqConsumer, currentStateType)) { + VirtualDisplaySurface* vds = new VirtualDisplaySurface(*hwc, hwcDisplayId, + currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName); + dispSurface = vds; + producer = vds; + } } else { - return new VirtualDisplaySurface(*hwc, hwcDisplayId, currentStateSurface, bqProducer, - bqConsumer, currentStateDisplayName); + VirtualDisplaySurface* vds = new VirtualDisplaySurface(*hwc, hwcDisplayId, + currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName); + dispSurface = vds; + producer = vds; } } +bool DisplayUtils::createV4L2BasedVirtualDisplay(HWComposer* hwc, int32_t &hwcDisplayId, + sp &dispSurface, sp &producer, + sp currentStateSurface, + sp bqProducer, sp bqConsumer, + int currentStateType) { + char value[PROPERTY_VALUE_MAX]; + property_get("persist.sys.wfd.virtual", value, "0"); + int wfdVirtual = atoi(value); + if(wfdVirtual && hwcDisplayId > 0) { + //Read virtual display properties and create a + //rendering surface for it inorder to be handled + //by hwc. + + sp mNativeWindow = new Surface(currentStateSurface); + ANativeWindow* const window = mNativeWindow.get(); + + int format; + window->query(window, NATIVE_WINDOW_FORMAT, &format); + EGLSurface surface; + EGLint w, h; + EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + // In M AOSP getEGLConfig() always returns EGL_NO_CONFIG as + // EGL_ANDROIDX_no_config_context active now. + EGLConfig config = RenderEngine::chooseEglConfig(display, format); + + surface = eglCreateWindowSurface(display, config, window, NULL); + eglQuerySurface(display, surface, EGL_WIDTH, &w); + eglQuerySurface(display, surface, EGL_HEIGHT, &h); + if(hwc->setVirtualDisplayProperties(hwcDisplayId, w, h, format) != NO_ERROR) + return false; + + dispSurface = new FramebufferSurface(*hwc, currentStateType, bqConsumer); + producer = bqProducer; + return true; + } + return false; +} + }; // namespace android diff --git a/services/surfaceflinger/DisplayUtils.h b/services/surfaceflinger/DisplayUtils.h index c35e36a14..cdf2b67fd 100644 --- a/services/surfaceflinger/DisplayUtils.h +++ b/services/surfaceflinger/DisplayUtils.h @@ -56,14 +56,21 @@ class DisplayUtils { uint32_t, uint32_t); HWComposer* getHWCInstance(const sp& flinger, HWComposer::EventHandler& handler); - VirtualDisplaySurface* getVDSInstance(HWComposer* hwc, int32_t hwcDisplayId, - sp currentStateSurface, sp bqProducer, + void initVDSInstance(HWComposer* hwc, int32_t hwcDisplayId, + sp currentStateSurface, sp &dispSurface, + sp &producer, sp bqProducer, sp bqConsumer, String8 currentStateDisplayName, - bool currentStateIsSecure); + bool currentStateIsSecure, int currentStateType); DisplayUtils(); private: static DisplayUtils* sDisplayUtils; static bool sUseExtendedImpls; + + bool createV4L2BasedVirtualDisplay(HWComposer* hwc, int32_t &hwcDisplayId, + sp &dispSurface, sp &producer, + sp currentStateSurface, + sp bqProducer, + sp bqConsumer, int currentStateType); }; }; // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d7cf13069..3b4330d15 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1445,12 +1445,10 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) hwcDisplayId = allocateHwcDisplayId(state.type); } - sp vds = DisplayUtils::getInstance()->getVDSInstance( - mHwc, hwcDisplayId, state.surface, - bqProducer, bqConsumer, state.displayName, state.isSecure); + DisplayUtils::getInstance()->initVDSInstance(mHwc, hwcDisplayId, + state.surface, dispSurface, producer, bqProducer, bqConsumer, + state.displayName, state.isSecure, state.type); - dispSurface = vds; - producer = vds; } } else { ALOGE_IF(state.surface!=NULL, @@ -1466,7 +1464,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) } const wp& display(curr.keyAt(i)); - if (dispSurface != NULL) { + if (dispSurface != NULL && producer != NULL) { sp hw = new DisplayDevice(this, state.type, hwcDisplayId, mHwc->getFormat(hwcDisplayId), state.isSecure,