SurfaceFlinger: Add support for DisplayUtils

Add DisplayUtils class which uses the custom implementations
of ExLayer, ExSurfaceFlinger, ExHWComposer,
and ExVirtualDisplaySurface classes if needed

Change-Id: Ibdd8da5d3d0d602f42b76a15d0994c6aa98bee3f
This commit is contained in:
Raj Kamal 2015-06-23 12:55:15 -07:00 committed by Linux Build Service Account
parent 8eaa19460d
commit 20f9ced881
11 changed files with 303 additions and 20 deletions

View File

@ -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

View File

@ -74,7 +74,7 @@ public:
const sp<SurfaceFlinger>& 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();

View File

@ -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>* 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
// ---------------------------------------------------------------------------

View File

@ -72,6 +72,8 @@ class VirtualDisplaySurface : public DisplaySurface,
public BnGraphicBufferProducer,
private ConsumerBase {
public:
friend class ExVirtualDisplaySurface;
VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& 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

View File

@ -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 <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <ui/GraphicBuffer.h>
#include "DisplayUtils.h"
#include <ExSurfaceFlinger.h>
#include <ExLayer.h>
#include <DisplayHardware/ExHWComposer.h>
#include <DisplayHardware/ExVirtualDisplaySurface.h>
#include <dlfcn.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() {
if(sUseExtendedImpls) {
return new ExSurfaceFlinger();
} else {
return new SurfaceFlinger();
}
}
Layer* DisplayUtils::getLayerInstance(SurfaceFlinger* flinger,
const sp<Client>& 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<SurfaceFlinger>& 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<IGraphicBufferProducer> currentStateSurface, sp<IGraphicBufferProducer> bqProducer,
sp<IGraphicBufferConsumer> 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

View File

@ -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 <stdint.h>
#include <sys/types.h>
#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<Client>&,
const String8&, uint32_t,
uint32_t, uint32_t);
HWComposer* getHWCInstance(const sp<SurfaceFlinger>& flinger,
HWComposer::EventHandler& handler);
VirtualDisplaySurface* getVDSInstance(HWComposer* hwc, int32_t hwcDisplayId,
sp<IGraphicBufferProducer> currentStateSurface, sp<IGraphicBufferProducer> bqProducer,
sp<IGraphicBufferConsumer> bqConsumer, String8 currentStateDisplayName,
bool currentStateIsSecure);
DisplayUtils();
private:
static DisplayUtils* sDisplayUtils;
static bool sUseExtendedImpls;
};
}; // namespace android
#endif // ANDROID_DISPLAY_UTILS_H

View File

@ -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);

View File

@ -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<const DisplayDevice>& 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<const DisplayDevice>& /*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<SurfaceFlinger>& flinger, const sp<Layer>& layer);
};
Rect reduce(const Rect& win, const Region& exclude) const;
private:
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener

View File

@ -77,6 +77,7 @@
#include "RenderEngine/RenderEngine.h"
#include <cutils/compiler.h>
#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<HWComposer::EventHandler *>(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<count ; i++) {
const sp<Layer>& 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<const DisplayDevice> hw(mDisplays[dpy]);
const int32_t id = hw->getHwcDisplayId();
if (id >= 0) {
bool freezeSurfacePresent = false;
isfreezeSurfacePresent(freezeSurfacePresent, hw, id);
const Vector< sp<Layer> >& currentLayers(
hw->getVisibleLayersSortedByZ());
const size_t count = currentLayers.size();
@ -1167,6 +1171,7 @@ void SurfaceFlinger::setUpHWComposer() {
*/
const sp<Layer>& 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<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
*mHwc, hwcDisplayId, state.surface,
bqProducer, bqConsumer, state.displayName);
sp<VirtualDisplaySurface> 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>& 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>& 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<const DisplayDevice>& /*hw*/,
const sp<Layer>& layer) {
return layer->isVisible();
}
// ---------------------------------------------------------------------------
SurfaceFlinger::LayerVector::LayerVector() {

View File

@ -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>& layer,
bool& bIgnoreLayers, int& indexLOI,
uint32_t layerStack, const int& i);
virtual void delayDPTransactionIfNeeded(
const Vector<DisplayState>& /*displays*/) { }
virtual bool canDrawLayerinScreenShot(
const sp<const DisplayDevice>& hw,
const sp<Layer>& layer);
virtual void isfreezeSurfacePresent(
bool& freezeSurfacePresent,
const sp<const DisplayDevice>& /*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);

View File

@ -22,6 +22,7 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include "SurfaceFlinger.h"
#include "DisplayUtils.h"
using namespace android;
@ -35,7 +36,7 @@ int main(int, char**) {
ps->startThreadPool();
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
sp<SurfaceFlinger> flinger = DisplayUtils::getInstance()->getSFInstance();
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);