diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 1eb23616c..3c966e2f7 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -34,8 +34,8 @@ LOCAL_SRC_FILES := \ RenderEngine/Texture.cpp \ RenderEngine/GLES10RenderEngine.cpp \ RenderEngine/GLES11RenderEngine.cpp \ - RenderEngine/GLES20RenderEngine.cpp - + RenderEngine/GLES20RenderEngine.cpp \ + DisplayUtils.cpp LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES @@ -106,6 +106,17 @@ LOCAL_SHARED_LIBRARIES := \ libgui \ libpowermanager +LOCAL_WHOLE_STATIC_LIBRARIES += libexsurfaceflinger + +LOCAL_C_INCLUDES += $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/display-frameworks/native/services/surfaceflinger/ + +ifeq ($(TARGET_USES_QCOM_BSP), true) + LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc + LOCAL_C_INCLUDES += hardware/qcom/display/libqdutils + LOCAL_SHARED_LIBRARIES += libqdutils + LOCAL_CFLAGS += -DQTI_BSP +endif + LOCAL_MODULE := libsurfaceflinger LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 814f6a391..d262f8482 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -74,7 +74,7 @@ public: const sp& flinger, EventHandler& handler); - ~HWComposer(); + virtual ~HWComposer(); status_t initCheck() const; @@ -304,6 +304,11 @@ public: // for debugging ---------------------------------------------------------- void dump(String8& out) const; + /* ------------------------------------------------------------------------ + * Extensions + */ + virtual inline bool isVDSEnabled() const { return true; }; + private: void loadHwcModule(); int loadFbHalModule(); diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index ba4c1981a..1e4f907da 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -152,7 +152,7 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) { // format/usage and get a new buffer when the GLES driver calls // dequeueBuffer(). mOutputFormat = mDefaultOutputFormat; - mOutputUsage = GRALLOC_USAGE_HW_COMPOSER; + setOutputUsage(GRALLOC_USAGE_HW_COMPOSER); refreshOutputBuffer(); } @@ -377,7 +377,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp* fence, bool mSinkBufferWidth, mSinkBufferHeight, buf->getPixelFormat(), buf->getUsage()); mOutputFormat = format; - mOutputUsage = usage; + setOutputUsage(usage); result = refreshOutputBuffer(); if (result < 0) return result; @@ -616,6 +616,10 @@ const char* VirtualDisplaySurface::dbgSourceStr(Source s) { } } +void VirtualDisplaySurface::setOutputUsage(uint32_t usage) { + mOutputUsage = usage; +} + // --------------------------------------------------------------------------- } // namespace android // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index 6298751f3..8b153d35b 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -72,6 +72,8 @@ class VirtualDisplaySurface : public DisplaySurface, public BnGraphicBufferProducer, private ConsumerBase { public: + friend class ExVirtualDisplaySurface; + VirtualDisplaySurface(HWComposer& hwc, int32_t dispId, const sp& sink, const sp& bqProducer, @@ -118,6 +120,7 @@ private: virtual status_t allowAllocation(bool allow); virtual status_t setGenerationNumber(uint32_t generationNumber); virtual String8 getConsumerName() const override; + virtual void setOutputUsage(uint32_t flag); // // Utility methods diff --git a/services/surfaceflinger/DisplayUtils.cpp b/services/surfaceflinger/DisplayUtils.cpp new file mode 100644 index 000000000..3937df0d4 --- /dev/null +++ b/services/surfaceflinger/DisplayUtils.cpp @@ -0,0 +1,106 @@ +/* Copyright (c) 2015, 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 +#include +#include + +#include +#include + +#include + +#include "DisplayUtils.h" +#include +#include +#include +#include +#include + +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() { + if(sUseExtendedImpls) { + return new ExSurfaceFlinger(); + } else { + return new SurfaceFlinger(); + } +} + +Layer* DisplayUtils::getLayerInstance(SurfaceFlinger* flinger, + const sp& client, const String8& name, + uint32_t w, uint32_t h, uint32_t flags) { + if(sUseExtendedImpls) { + return new ExLayer(flinger, client, name, w, h, flags); + } else { + return new Layer(flinger, client, name, w, h, flags); + } +} + +HWComposer* DisplayUtils::getHWCInstance( + const sp& flinger, + HWComposer::EventHandler& handler) { + if(sUseExtendedImpls) { + return new ExHWComposer(flinger, handler); + } else { + return new HWComposer(flinger,handler); + } +} + +VirtualDisplaySurface* DisplayUtils::getVDSInstance(HWComposer* hwc, int32_t hwcDisplayId, + sp currentStateSurface, sp bqProducer, + sp bqConsumer, String8 currentStateDisplayName, + bool currentStateIsSecure) +{ + if(sUseExtendedImpls) { + return new ExVirtualDisplaySurface(*hwc, hwcDisplayId, currentStateSurface, bqProducer, + bqConsumer, currentStateDisplayName, currentStateIsSecure); + } else { + return new VirtualDisplaySurface(*hwc, hwcDisplayId, currentStateSurface, bqProducer, + bqConsumer, currentStateDisplayName); + } +} + +}; // namespace android + diff --git a/services/surfaceflinger/DisplayUtils.h b/services/surfaceflinger/DisplayUtils.h new file mode 100644 index 000000000..c35e36a14 --- /dev/null +++ b/services/surfaceflinger/DisplayUtils.h @@ -0,0 +1,71 @@ +/* Copyright (c) 2015, 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. + */ + +#ifndef ANDROID_DISPLAY_UTILS_H +#define ANDROID_DISPLAY_UTILS_H + +#include +#include + +#include "Layer.h" +#include "SurfaceFlinger.h" +#include "DisplayHardware/HWComposer.h" +#include "DisplayHardware/VirtualDisplaySurface.h" + +// --------------------------------------------------------------------------- + +namespace android { + +class IGraphicBufferProducer; +class IGraphicBufferConsumer; +class DisplaySurface; + +/* Factory Classes */ + +class DisplayUtils { + public: + static DisplayUtils* getInstance() ANDROID_API; + SurfaceFlinger* getSFInstance() ANDROID_API; + Layer* getLayerInstance(SurfaceFlinger*, const sp&, + const String8&, uint32_t, + uint32_t, uint32_t); + HWComposer* getHWCInstance(const sp& flinger, + HWComposer::EventHandler& handler); + VirtualDisplaySurface* getVDSInstance(HWComposer* hwc, int32_t hwcDisplayId, + sp currentStateSurface, sp bqProducer, + sp bqConsumer, String8 currentStateDisplayName, + bool currentStateIsSecure); + DisplayUtils(); + private: + static DisplayUtils* sDisplayUtils; + static bool sUseExtendedImpls; +}; + +}; // namespace android + +#endif // ANDROID_DISPLAY_UTILS_H diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 5ff79a9e3..bfd83e470 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -320,7 +320,7 @@ Rect Layer::getContentCrop() const { return crop; } -static Rect reduce(const Rect& win, const Region& exclude) { +Rect Layer::reduce(const Rect& win, const Region& exclude) const{ if (CC_LIKELY(exclude.isEmpty())) { return win; } @@ -494,6 +494,7 @@ void Layer::setGeometry( frame.intersect(hw->getViewport(), &frame); const Transform& tr(hw->getTransform()); layer.setFrame(tr.transform(frame)); + setPosition(hw, layer, s); layer.setCrop(computeCrop(hw)); layer.setPlaneAlpha(s.alpha); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c1e5e9ff1..25437acd3 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -71,6 +71,7 @@ class Layer : public SurfaceFlingerConsumer::ContentsChangedListener { static int32_t sSequence; public: + friend class ExLayer; mutable bool contentDirty; // regions below are in window-manager space Region visibleRegion; @@ -285,6 +286,17 @@ public: // the current orientation of the display device. void updateTransformHint(const sp& hw) const; + /* ------------------------------------------------------------------------ + * Extensions + */ + virtual bool isExtOnly() const { return false; } + virtual bool isIntOnly() const { return false; } + virtual bool isSecureDisplay() const { return false; } + virtual bool isYuvLayer() const { return false; } + virtual void setPosition(const sp& /*hw*/, + HWComposer::HWCLayerInterface& /*layer*/, + const State& /*state*/) { } + /* * returns the rectangle that crops the content of the layer and scales it * to the layer's size. @@ -336,6 +348,7 @@ protected: LayerCleaner(const sp& flinger, const sp& layer); }; + Rect reduce(const Rect& win, const Region& exclude) const; private: // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 2b5982e46..d7cf13069 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -77,6 +77,7 @@ #include "RenderEngine/RenderEngine.h" #include +#include "DisplayUtils.h" #define DISPLAY_COUNT 1 @@ -444,7 +445,7 @@ void SurfaceFlinger::init() { // Initialize the H/W composer object. There may or may not be an // actual hardware composer underneath. - mHwc = new HWComposer(this, + mHwc = DisplayUtils::getInstance()->getHWCInstance(this, *static_cast(this)); // get a RenderEngine for the given display / config (can't fail) @@ -874,6 +875,7 @@ void SurfaceFlinger::onHotplugReceived(int type, bool connected) { } else { mCurrentState.displays.removeItem(mBuiltinDisplays[type]); mBuiltinDisplays[type].clear(); + updateVisibleRegionsDirty(); } setTransactionFlags(eDisplayTransactionNeeded); @@ -1053,6 +1055,7 @@ void SurfaceFlinger::postComposition() } void SurfaceFlinger::rebuildLayerStacks() { + updateExtendedMode(); // rebuild the visible layer list per screen if (CC_UNLIKELY(mVisibleRegionsDirty)) { ATRACE_CALL(); @@ -1068,14 +1071,13 @@ void SurfaceFlinger::rebuildLayerStacks() { const Transform& tr(hw->getTransform()); const Rect bounds(hw->getBounds()); if (hw->isDisplayOn()) { - SurfaceFlinger::computeVisibleRegions(layers, + computeVisibleRegions(hw->getHwcDisplayId(), layers, hw->getLayerStack(), dirtyRegion, opaqueRegion); const size_t count = layers.size(); for (size_t i=0 ; i& layer(layers[i]); - const Layer::State& s(layer->getDrawingState()); - if (s.layerStack == hw->getLayerStack()) { + { Region drawRegion(tr.transform( layer->visibleNonTransparentRegion)); drawRegion.andSelf(bounds); @@ -1155,6 +1157,8 @@ void SurfaceFlinger::setUpHWComposer() { sp hw(mDisplays[dpy]); const int32_t id = hw->getHwcDisplayId(); if (id >= 0) { + bool freezeSurfacePresent = false; + isfreezeSurfacePresent(freezeSurfacePresent, hw, id); const Vector< sp >& currentLayers( hw->getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); @@ -1167,6 +1171,7 @@ void SurfaceFlinger::setUpHWComposer() { */ const sp& layer(currentLayers[i]); layer->setPerFrameData(hw, *cur); + setOrientationEventControl(freezeSurfacePresent,id); } } } @@ -1440,9 +1445,9 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) hwcDisplayId = allocateHwcDisplayId(state.type); } - sp vds = new VirtualDisplaySurface( - *mHwc, hwcDisplayId, state.surface, - bqProducer, bqConsumer, state.displayName); + sp vds = DisplayUtils::getInstance()->getVDSInstance( + mHwc, hwcDisplayId, state.surface, + bqProducer, bqConsumer, state.displayName, state.isSecure); dispSurface = vds; producer = vds; @@ -1639,7 +1644,7 @@ void SurfaceFlinger::commitTransaction() mTransactionCV.broadcast(); } -void SurfaceFlinger::computeVisibleRegions( +void SurfaceFlinger::computeVisibleRegions(size_t dpy, const LayerVector& currentLayers, uint32_t layerStack, Region& outDirtyRegion, Region& outOpaqueRegion) { @@ -1650,6 +1655,9 @@ void SurfaceFlinger::computeVisibleRegions( Region dirty; outDirtyRegion.clear(); + bool bIgnoreLayers = false; + int indexLOI = -1; + getIndexLOI(dpy, currentLayers, bIgnoreLayers, indexLOI); size_t i = currentLayers.size(); while (i--) { @@ -1658,8 +1666,9 @@ void SurfaceFlinger::computeVisibleRegions( // start with the whole surface at its current location const Layer::State& s(layer->getDrawingState()); - // only consider the layers on the given layer stack - if (s.layerStack != layerStack) + if(updateLayerVisibleNonTransparentRegion(dpy, layer, + bIgnoreLayers, indexLOI, + layerStack, i)) continue; /* @@ -2092,6 +2101,8 @@ void SurfaceFlinger::setTransactionState( uint32_t flags) { ATRACE_CALL(); + + delayDPTransactionIfNeeded(displays); Mutex::Autolock _l(mStateLock); uint32_t transactionFlags = 0; @@ -2338,7 +2349,7 @@ status_t SurfaceFlinger::createNormalLayer(const sp& client, break; } - *outLayer = new Layer(this, client, name, w, h, flags); + *outLayer = DisplayUtils::getInstance()->getLayerInstance(this, client, name, w, h, flags); status_t err = (*outLayer)->setBuffers(w, h, format, flags); if (err == NO_ERROR) { *handle = (*outLayer)->getHandle(); @@ -3312,7 +3323,7 @@ void SurfaceFlinger::renderScreenImplLocked( const Layer::State& state(layer->getDrawingState()); if (state.layerStack == hw->getLayerStack()) { if (state.z >= minLayerZ && state.z <= maxLayerZ) { - if (layer->isVisible()) { + if (canDrawLayerinScreenShot(hw,layer)) { if (filtering) layer->setFiltering(true); layer->draw(hw, useIdentityTransform); if (filtering) layer->setFiltering(false); @@ -3488,6 +3499,29 @@ void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* v } } +/* ------------------------------------------------------------------------ + * Extensions + */ + +bool SurfaceFlinger::updateLayerVisibleNonTransparentRegion(const int& /*dpy*/, + const sp& layer, bool& /*bIgnoreLayers*/, int& /*indexLOI*/, + uint32_t layerStack, const int& /*i*/) { + + const Layer::State& s(layer->getDrawingState()); + + // only consider the layers on the given layer stack + if (s.layerStack != layerStack) + return true; + + return false; +} + +bool SurfaceFlinger::canDrawLayerinScreenShot( + const sp& /*hw*/, + const sp& layer) { + return layer->isVisible(); +} + // --------------------------------------------------------------------------- SurfaceFlinger::LayerVector::LayerVector() { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 3759a9240..bb0bfc49e 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -84,6 +84,8 @@ class SurfaceFlinger : public BnSurfaceComposer, private HWComposer::EventHandler { public: + friend class ExSurfaceFlinger; + static char const* getServiceName() ANDROID_API { return "SurfaceFlinger"; } @@ -234,6 +236,38 @@ private: virtual void onVSyncReceived(int type, nsecs_t timestamp); virtual void onHotplugReceived(int disp, bool connected); + /* ------------------------------------------------------------------------ + * Extensions + */ + virtual void updateExtendedMode() { } + + virtual void getIndexLOI(size_t /*dpy*/, + const LayerVector& /*currentLayers*/, + bool& /*bIgnoreLayers*/, + int& /*indexLOI*/) { } + + virtual bool updateLayerVisibleNonTransparentRegion( + const int& dpy, const sp& layer, + bool& bIgnoreLayers, int& indexLOI, + uint32_t layerStack, const int& i); + + virtual void delayDPTransactionIfNeeded( + const Vector& /*displays*/) { } + + virtual bool canDrawLayerinScreenShot( + const sp& hw, + const sp& layer); + + virtual void isfreezeSurfacePresent( + bool& freezeSurfacePresent, + const sp& /*hw*/, + const int32_t& /*id*/) { freezeSurfacePresent = false; } + + virtual void setOrientationEventControl( + bool& /*freezeSurfacePresent*/, + const int32_t& /*id*/) { } + + virtual void updateVisibleRegionsDirty() { } /* ------------------------------------------------------------------------ * Message handling */ @@ -373,7 +407,7 @@ private: * Compositing */ void invalidateHwcGeometry(); - static void computeVisibleRegions( + void computeVisibleRegions(size_t dpy, const LayerVector& currentLayers, uint32_t layerStack, Region& dirtyRegion, Region& opaqueRegion); diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp index a74bc4cd9..6127cf6be 100644 --- a/services/surfaceflinger/main_surfaceflinger.cpp +++ b/services/surfaceflinger/main_surfaceflinger.cpp @@ -22,6 +22,7 @@ #include #include #include "SurfaceFlinger.h" +#include "DisplayUtils.h" using namespace android; @@ -35,7 +36,7 @@ int main(int, char**) { ps->startThreadPool(); // instantiate surfaceflinger - sp flinger = new SurfaceFlinger(); + sp flinger = DisplayUtils::getInstance()->getSFInstance(); setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);