diff options
Diffstat (limited to 'services/surfaceflinger/DisplayUtils.cpp')
-rw-r--r-- | services/surfaceflinger/DisplayUtils.cpp | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/services/surfaceflinger/DisplayUtils.cpp b/services/surfaceflinger/DisplayUtils.cpp new file mode 100644 index 0000000..e618e89 --- /dev/null +++ b/services/surfaceflinger/DisplayUtils.cpp @@ -0,0 +1,213 @@ +/* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/Log.h> + +#include <gui/Surface.h> +#include <ui/GraphicBuffer.h> + +#include "RenderEngine/RenderEngine.h" +#include "DisplayHardware/FramebufferSurface.h" +#include "DisplayUtils.h" +#ifdef QTI_BSP +#include <ExSurfaceFlinger/ExSurfaceFlinger.h> +#include <ExSurfaceFlinger/ExLayer.h> +#include <ExSurfaceFlinger/ExHWComposer.h> +#include <ExSurfaceFlinger/ExVirtualDisplaySurface.h> +#include <gralloc_priv.h> +#ifdef SDM_TARGET +#include <qd_utils.h> +#include <display_config.h> +#endif +#endif +#include <dlfcn.h> +#include <cutils/properties.h> + +namespace android { + +DisplayUtils* DisplayUtils::sDisplayUtils = NULL; +bool DisplayUtils::sUseExtendedImpls = false; + +DisplayUtils::DisplayUtils() { +#ifdef QTI_BSP + sUseExtendedImpls = true; +#endif +} + +DisplayUtils* DisplayUtils::getInstance() { + if(sDisplayUtils == NULL) { + sDisplayUtils = new DisplayUtils(); + } + return sDisplayUtils; +} + +SurfaceFlinger* DisplayUtils::getSFInstance() { +#ifdef QTI_BSP + if(sUseExtendedImpls) { + return new ExSurfaceFlinger(); + } +#endif + return new SurfaceFlinger(); +} + +Layer* DisplayUtils::getLayerInstance(SurfaceFlinger* flinger, + const sp<Client>& client, const String8& name, + uint32_t w, uint32_t h, uint32_t flags) { +#ifdef QTI_BSP + if(sUseExtendedImpls) { + return new ExLayer(flinger, client, name, w, h, flags); + } +#endif + return new Layer(flinger, client, name, w, h, flags); +} + +HWComposer* DisplayUtils::getHWCInstance( + const sp<SurfaceFlinger>& flinger, + HWComposer::EventHandler& handler) { +#ifdef QTI_BSP + if(sUseExtendedImpls) { + return new ExHWComposer(flinger, handler); + } +#endif + return new HWComposer(flinger,handler); +} + +void DisplayUtils::initVDSInstance(HWComposer* hwc, int32_t hwcDisplayId, + sp<IGraphicBufferProducer> currentStateSurface, sp<DisplaySurface> &dispSurface, + sp<IGraphicBufferProducer> &producer, sp<IGraphicBufferProducer> bqProducer, + sp<IGraphicBufferConsumer> bqConsumer, String8 currentStateDisplayName, + bool currentStateIsSecure, int currentStateType) +{ +#ifdef QTI_BSP + if(sUseExtendedImpls) { + 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 { +#endif + (void)currentStateIsSecure; + (void)currentStateType; + VirtualDisplaySurface* vds = new VirtualDisplaySurface(*hwc, hwcDisplayId, + currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName); + dispSurface = vds; + producer = vds; +#ifdef QTI_BSP + } +#endif +} + +bool DisplayUtils::createV4L2BasedVirtualDisplay(HWComposer* hwc, int32_t &hwcDisplayId, + sp<DisplaySurface> &dispSurface, sp<IGraphicBufferProducer> &producer, + sp<IGraphicBufferProducer> currentStateSurface, + sp<IGraphicBufferProducer> bqProducer, sp<IGraphicBufferConsumer> 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<ANativeWindow> 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; +} + +bool DisplayUtils::canAllocateHwcDisplayIdForVDS(int usage) { + // on AOSP builds with QTI_BSP disabled, we should allocate hwc display id for virtual display + int flag_mask = 0xffffffff; + +#ifdef QTI_BSP +#ifdef FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS +#ifdef SDM_TARGET + int hdmi_node = qdutils::getHDMINode(); + if(hdmi_node == HWC_DISPLAY_PRIMARY) { + int active_config = qdutils::getActiveConfig(HWC_DISPLAY_PRIMARY); + if(active_config >= 0) { + qdutils::DisplayAttributes attr = qdutils::getDisplayAttributes(active_config, + HWC_DISPLAY_PRIMARY); + if(!attr.is_yuv) { + // Reserve hardware acceleration for WFD use-case + flag_mask = GRALLOC_USAGE_PRIVATE_WFD; + } + } + } else { +#endif + // Reserve hardware acceleration for WFD use-case + flag_mask = GRALLOC_USAGE_PRIVATE_WFD; +#ifdef SDM_TARGET + } +#endif +#else + // Don't allocate HWC display unless we force HWC copy, otherwise + // incompatible buffers are sent to the media stack + flag_mask = 0; +#endif +#endif + + return (usage & flag_mask); +} + +}; // namespace android + |