Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 766d5f67 authored by Arun Kumar K.R's avatar Arun Kumar K.R Committed by Linux Build Service Account
Browse files

SurfaceFlinger: Add support for extendedMode

- Displays only video with full screen on External with no UI controls
- Primary will show only UI controls
- Similar to presentation class, but will be used by a third
  party app, which does not use presentation class
- To enable this set sys.extended_mode to 1

Change-Id: I9a66c770e1c1a7471cb50690514497dae8dad4b3
parent db7ca4dd
Loading
Loading
Loading
Loading
+52 −5
Original line number Original line Diff line number Diff line
@@ -56,6 +56,31 @@ namespace android {


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------


/* Calculates the aspect ratio for external display based on the video w/h */
static Rect getAspectRatio(const sp<const DisplayDevice>& hw,
                           const int& srcWidth, const int& srcHeight) {
    Rect outRect;
    int fbWidth  = hw->getWidth();
    int fbHeight = hw->getHeight();
    int x , y = 0;
    int w = fbWidth, h = fbHeight;
    if (srcWidth * fbHeight > fbWidth * srcHeight) {
        h = fbWidth * srcHeight / srcWidth;
        w = fbWidth;
    } else if (srcWidth * fbHeight < fbWidth * srcHeight) {
        w = fbHeight * srcWidth / srcHeight;
        h = fbHeight;
    }
    x = (fbWidth - w) / 2;
    y = (fbHeight - h) / 2;
    outRect.left = x;
    outRect.top = y;
    outRect.right = x + w;
    outRect.bottom = y + h;

    return outRect;
}

int32_t Layer::sSequence = 1;
int32_t Layer::sSequence = 1;


Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
@@ -473,12 +498,20 @@ void Layer::setGeometry(
    const Transform& tr(hw->getTransform());
    const Transform& tr(hw->getTransform());
    layer.setFrame(tr.transform(frame));
    layer.setFrame(tr.transform(frame));
#ifdef QCOM_BSP
#ifdef QCOM_BSP
    // set dest_rect to frame buffer width and height, if external_only flag
    // set dest_rect to display width and height, if external_only flag
    // for the layer is enabled.
    // for the layer is enabled or if its yuvLayer in extended mode.
    if(isExtOnly()) {
    uint32_t x = 0, y = 0;
    uint32_t w = hw->getWidth();
    uint32_t w = hw->getWidth();
    uint32_t h = hw->getHeight();
    uint32_t h = hw->getHeight();
        layer.setFrame(Rect(w,h));
    bool extendedMode = SurfaceFlinger::isExtendedMode();
    if(isExtOnly()) {
        // Position: fullscreen for ext_only
        Rect r(0, 0, w, h);
        layer.setFrame(r);
    } else if(hw->getDisplayType() > 0 && (extendedMode && isYuvLayer())) {
        // Need to position the video full screen on external with aspect ratio
        Rect r = getAspectRatio(hw, s.active.w, s.active.h);
        layer.setFrame(r);
    }
    }
#endif
#endif
    layer.setCrop(computeCrop(hw));
    layer.setCrop(computeCrop(hw));
@@ -1499,6 +1532,20 @@ bool Layer::isSecureDisplay() const
    return false;
    return false;
}
}


// returns true, if the activeBuffer is Yuv
bool Layer::isYuvLayer() const {
    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
    if(activeBuffer != 0) {
        ANativeWindowBuffer* buffer = activeBuffer->getNativeBuffer();
        if(buffer) {
            private_handle_t* hnd = static_cast<private_handle_t*>
                (const_cast<native_handle_t*>(buffer->handle));
            //if BUFFER_TYPE_VIDEO, its YUV
            return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO));
        }
    }
    return false;
}
#endif
#endif


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
+1 −0
Original line number Original line Diff line number Diff line
@@ -278,6 +278,7 @@ public:
    virtual bool isExtOnly() const;
    virtual bool isExtOnly() const;
    virtual bool isIntOnly() const;
    virtual bool isIntOnly() const;
    virtual bool isSecureDisplay() const;
    virtual bool isSecureDisplay() const;
    virtual bool isYuvLayer() const;
#endif
#endif


    /*
    /*
+38 −7
Original line number Original line Diff line number Diff line
@@ -130,6 +130,10 @@ const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
const String16 sDump("android.permission.DUMP");
const String16 sDump("android.permission.DUMP");


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Initialize extendedMode to false
#ifdef QCOM_BSP
bool SurfaceFlinger::sExtendedMode = false;
#endif


SurfaceFlinger::SurfaceFlinger()
SurfaceFlinger::SurfaceFlinger()
    :   BnSurfaceComposer(),
    :   BnSurfaceComposer(),
@@ -829,6 +833,13 @@ void SurfaceFlinger::onHotplugReceived(int type, bool connected) {
        } else {
        } else {
            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
            mBuiltinDisplays[type].clear();
            mBuiltinDisplays[type].clear();
#ifdef QCOM_BSP
            // if extended_mode is set, and set mVisibleRegionsDirty
            // as we need to rebuildLayerStack
            if(isExtendedMode()) {
                mVisibleRegionsDirty = true;
            }
#endif
        }
        }
        setTransactionFlags(eDisplayTransactionNeeded);
        setTransactionFlags(eDisplayTransactionNeeded);


@@ -1015,6 +1026,11 @@ void SurfaceFlinger::postComposition()
}
}


void SurfaceFlinger::rebuildLayerStacks() {
void SurfaceFlinger::rebuildLayerStacks() {
#ifdef QCOM_BSP
    char prop[PROPERTY_VALUE_MAX];
    property_get("sys.extended_mode", prop, "0");
    sExtendedMode = atoi(prop) ? true : false;
#endif
    // rebuild the visible layer list per screen
    // rebuild the visible layer list per screen
    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
        ATRACE_CALL();
        ATRACE_CALL();
@@ -1770,8 +1786,10 @@ void SurfaceFlinger::computeVisibleRegions(size_t dpy,
                indexLOI = i;
                indexLOI = i;
            break;
            break;
        }
        }

        // iterate through the layer list to find ext_only layers or yuv
        if (dpy && layer->isExtOnly()) {
        // layer(extended_mode) and store the index
        if ((dpy && (layer->isExtOnly() ||
                     (isExtendedMode() && layer->isYuvLayer())))) {
            bIgnoreLayers= true;
            bIgnoreLayers= true;
            indexLOI = i;
            indexLOI = i;
        }
        }
@@ -1785,13 +1803,16 @@ void SurfaceFlinger::computeVisibleRegions(size_t dpy,
        const Layer::State& s(layer->getDrawingState());
        const Layer::State& s(layer->getDrawingState());


#ifdef QCOM_BSP
#ifdef QCOM_BSP
        // Only add the layer marked as "external_only" to external list and
        // Only add the layer marked as "external_only" or yuvLayer
        // only remove the layer marked as "external_only" from primary list
        // (extended_mode) to external list and
        // only remove the layer marked as "external_only" or yuvLayer in
        // extended_mode from primary list
        // and do not add the layer marked as "internal_only" to external list
        // and do not add the layer marked as "internal_only" to external list
        // Add secure UI layers to primary and remove other layers from internal
        // Add secure UI layers to primary and remove other layers from internal
        //and external list
        //and external list
        if((bIgnoreLayers && indexLOI != (int)i) ||
        if(((bIgnoreLayers && indexLOI != (int)i) ||
           (!dpy && layer->isExtOnly()) ||
           (!dpy && layer->isExtOnly()) ||
                     (!dpy && isExtendedMode() && layer->isYuvLayer()))||
                     (dpy && layer->isIntOnly())) {
                     (dpy && layer->isIntOnly())) {
            // Ignore all other layers except the layers marked as ext_only
            // Ignore all other layers except the layers marked as ext_only
            // by setting visible non transparent region empty.
            // by setting visible non transparent region empty.
@@ -3489,7 +3510,17 @@ void SurfaceFlinger::renderScreenImplLocked(
                    continue;
                    continue;
                }
                }
#endif
#endif
#ifdef QCOM_BSP
                int dispType = hw->getDisplayType();
                // Dont let ext_only and extended_mode to be captured
                // If not, we would see incorrect image during rotatoin
                // on primary
                if (layer->isVisible() &&
                    not (!dispType && (layer->isExtOnly() ||
                         (isExtendedMode() && layer->isYuvLayer())))) {
#else
                if (layer->isVisible()) {
                if (layer->isVisible()) {
#endif
                    if (filtering) layer->setFiltering(true);
                    if (filtering) layer->setFiltering(true);
                    if(!layer->isProtected())
                    if(!layer->isProtected())
                           layer->draw(hw, useIdentityTransform);
                           layer->draw(hw, useIdentityTransform);
+6 −1
Original line number Original line Diff line number Diff line
@@ -135,7 +135,12 @@ public:
    RenderEngine& getRenderEngine() const {
    RenderEngine& getRenderEngine() const {
        return *mRenderEngine;
        return *mRenderEngine;
    }
    }

#ifdef QCOM_BSP
    // Extended Mode - No video on primary and it will be shown full
    // screen on External
    static bool sExtendedMode;
    static bool isExtendedMode() { return sExtendedMode; };
#endif
private:
private:
    friend class Client;
    friend class Client;
    friend class DisplayEventConnection;
    friend class DisplayEventConnection;