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

Commit f19506d9 authored by Tatenda Chipeperekwa's avatar Tatenda Chipeperekwa Committed by Linux Build Service Account
Browse files

sf: vds: Selectively compose displays via HWC.

1. Replace static force copy flag with member variable

The decision to copy a virtual display using the WriteBack path will be
done when the display is created. We initialize the member variable to
false meaning all virtual display devices are composed via GLES.

2. Select which displays to compose based on sink usage flags

We should compose a display using HWC only if the sink usage contains
GRALLOC_USAGE_PRIVATE_WFD and GRALLOC_USAGE_HW_VIDEO_ENCODER flags.

If this condition is not met then the display is composed using GLES.
This means that GLES composes directly into the sink buffer and signals
the consumer. Furthermore, it is expected that any color conversion will
be handled on the consumer side.

3. Add debug hook for ScreenRecord use case

We add a debug hook which serves to by-pass the checks imposed by (2).
This is useful for debugging purposes and allows us to test VDS
end-to-end when WFD is not working on a particular build.

The debug hook is through the system property: debug.hwc.screenrecord

4. Update composition checks

-mFbProducerSlot is always at least 0 so there is no point in validating
 it when in advanceFrame().
-Release scratch buffers in onFrameCommitted as long as mFbProducerSlot
 is valid.

Change-Id: I2964e2f8d0b3e848895cdf4f41df8a5d2739ddad

Conflicts:
services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
Change-Id: I2d2fc152f14487c4f24dbfb210c81c21346bdbe3
parent 46dc8d6a
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -51,10 +51,6 @@ ifeq ($(TARGET_DISABLE_TRIPLE_BUFFERING),true)
	LOCAL_CFLAGS += -DTARGET_DISABLE_TRIPLE_BUFFERING
endif

ifeq ($(TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS),true)
    LOCAL_CFLAGS += -DFORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS
endif

ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),)
  LOCAL_CFLAGS += -DNUM_FRAMEBUFFER_SURFACE_BUFFERS=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS)
endif
+36 −16
Original line number Diff line number Diff line
@@ -17,7 +17,10 @@
// #define LOG_NDEBUG 0
#include "VirtualDisplaySurface.h"
#include "HWComposer.h"

#include <cutils/properties.h>
#if QCOM_BSP
#include <gralloc_priv.h>
#endif
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
@@ -58,16 +61,18 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
    mProducerSlotSource(0),
    mDbgState(DBG_STATE_IDLE),
    mDbgLastCompositionType(COMPOSITION_UNKNOWN),
    mMustRecompose(false)
    mMustRecompose(false),
    mForceHwcCopy(false)
{
    mSource[SOURCE_SINK] = sink;
    mSource[SOURCE_SCRATCH] = bqProducer;

    resetPerFrameState();

    int sinkWidth, sinkHeight;
    int sinkWidth, sinkHeight, sinkFormat, sinkUsage;
    sink->query(NATIVE_WINDOW_WIDTH, &sinkWidth);
    sink->query(NATIVE_WINDOW_HEIGHT, &sinkHeight);
    sink->query(NATIVE_WINDOW_FORMAT, &sinkFormat);
    sink->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &sinkUsage);

    mSinkBufferWidth = sinkWidth;
    mSinkBufferHeight = sinkHeight;

@@ -75,16 +80,32 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
    // with GLES. If the consumer needs CPU access, use the default format
    // set by the consumer. Otherwise allow gralloc to decide the format based
    // on usage bits.
    int sinkUsage;
    sink->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &sinkUsage);
    if (sinkUsage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
        int sinkFormat;
        sink->query(NATIVE_WINDOW_FORMAT, &sinkFormat);
    mDefaultOutputFormat = sinkFormat;
    } else {
    if((sinkUsage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
#if QCOM_BSP
            && (sinkUsage & GRALLOC_USAGE_PRIVATE_WFD)
#endif
      )
    {
        mDefaultOutputFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
        mForceHwcCopy = true;
    }

    // XXX: With this debug property we can allow screenrecord to be composed
    // via HWC. This is useful for debugging purposes, for example when WFD
    // is not working on a particular build.
    char value[PROPERTY_VALUE_MAX];
    if( (property_get("debug.hwc.screenrecord", value, NULL) > 0) &&
        ((!strncmp(value, "1", strlen("1"))) ||
        !strncasecmp(value, "true", strlen("true")))) {
        mForceHwcCopy = true;
    }
    mOutputFormat = mDefaultOutputFormat;
    // TODO: need to add the below logs as part of dumpsys output
    VDS_LOGV("creation: sinkFormat: 0x%x sinkUsage: 0x%x mForceHwcCopy: %d",
            mOutputFormat, sinkUsage, mForceHwcCopy);

    resetPerFrameState();

    ConsumerBase::mName = String8::format("VDS: %s", mDisplayName.string());
    mConsumer->setConsumerName(ConsumerBase::mName);
@@ -118,7 +139,7 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
    mDbgState = DBG_STATE_PREPARED;

    mCompositionType = compositionType;
    if (sForceHwcCopy && mCompositionType == COMPOSITION_GLES) {
    if (mForceHwcCopy) {
        // Some hardware can do RGB->YUV conversion more efficiently in hardware
        // controlled by HWC than in hardware controlled by the video encoder.
        // Forcing GLES-composed frames to go through an extra copy by the HWC
@@ -176,8 +197,7 @@ status_t VirtualDisplaySurface::advanceFrame() {
    }
    mDbgState = DBG_STATE_HWC;

    if (mOutputProducerSlot < 0 ||
            (mCompositionType != COMPOSITION_HWC && mFbProducerSlot < 0)) {
    if (mOutputProducerSlot < 0) {
        // Last chance bailout if something bad happened earlier. For example,
        // in a GLES configuration, if the sink disappears then dequeueBuffer
        // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger
@@ -215,7 +235,7 @@ void VirtualDisplaySurface::onFrameCommitted() {
    mDbgState = DBG_STATE_IDLE;

    sp<Fence> fbFence = mHwc.getAndResetReleaseFence(mDisplayId);
    if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) {
    if (mFbProducerSlot >= 0) {
        // release the scratch buffer back to the pool
        Mutex::Autolock lock(mMutex);
        int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot);
+4 −0
Original line number Diff line number Diff line
@@ -144,6 +144,10 @@ private:
    sp<IGraphicBufferProducer> mSource[2]; // indexed by SOURCE_*
    uint32_t mDefaultOutputFormat;

    // Force copy flag. Used to determine if we are forcing composition
    // through HWC.
    bool mForceHwcCopy;

    //
    // Inter-frame state
    //