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

Commit c81aa3e3 authored by Andy McFadden's avatar Andy McFadden Committed by Android Git Automerger
Browse files

am b0d1dd36: Reshuffle FramebufferSurface

* commit 'b0d1dd36':
  Reshuffle FramebufferSurface
parents fc737a16 b0d1dd36
Loading
Loading
Loading
Loading
+17 −54
Original line number Diff line number Diff line
@@ -33,21 +33,12 @@
#include <ui/GraphicBuffer.h>

#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/HWComposer.h"

// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------

sp<FramebufferSurface> FramebufferSurface::create() {
    sp<FramebufferSurface> result = new FramebufferSurface();
    if (result->fbDev == NULL) {
        result = NULL;
    }
    return result;
}

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

class GraphicBufferAlloc : public BnGraphicBufferAlloc {
public:
    GraphicBufferAlloc() { };
@@ -66,36 +57,21 @@ public:
 *
 */

FramebufferSurface::FramebufferSurface():
FramebufferSurface::FramebufferSurface(HWComposer& hwc) :
    ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),
    fbDev(0),
    mCurrentBufferSlot(-1),
    mCurrentBuffer(0)
    mCurrentBuffer(0),
    mHwc(hwc)
{
    hw_module_t const* module;

    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
        int stride;
        int err;
        int i;
        err = framebuffer_open(module, &fbDev);
        ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));

        // bail out if we can't initialize the modules
        if (!fbDev)
            return;

    mName = "FramebufferSurface";
    mBufferQueue->setConsumerName(mName);
    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
                                       GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER);
        mBufferQueue->setDefaultBufferFormat(fbDev->format);
        mBufferQueue->setDefaultBufferSize(fbDev->width, fbDev->height);
    mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(HWC_DISPLAY_PRIMARY));
    mBufferQueue->setDefaultBufferSize(mHwc.getResolutionX(HWC_DISPLAY_PRIMARY),
                                       mHwc.getResolutionY(HWC_DISPLAY_PRIMARY));
    mBufferQueue->setSynchronousMode(true);
    mBufferQueue->setDefaultMaxBufferCount(NUM_FRAME_BUFFERS);
    } else {
        ALOGE("Couldn't get gralloc module");
    }
}

status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) {
@@ -145,12 +121,7 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) {
    return NO_ERROR;
}

FramebufferSurface::~FramebufferSurface() {
    if (fbDev) {
        framebuffer_close(fbDev);
    }
}

// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
void FramebufferSurface::onFrameAvailable() {
    // XXX: The following code is here temporarily as part of the transition
    // away from the framebuffer HAL.
@@ -161,7 +132,7 @@ void FramebufferSurface::onFrameAvailable() {
                strerror(-err), err);
        return;
    }
    err = fbDev->post(fbDev, buf->handle);
    err = mHwc.fbPost(buf->handle);
    if (err != NO_ERROR) {
        ALOGE("error posting framebuffer: %d", err);
    }
@@ -181,19 +152,11 @@ status_t FramebufferSurface::setUpdateRectangle(const Rect& r)

status_t FramebufferSurface::compositionComplete()
{
    if (fbDev->compositionComplete) {
        return fbDev->compositionComplete(fbDev);
    }
    return INVALID_OPERATION;
    return mHwc.fbCompositionComplete();
}

void FramebufferSurface::dump(String8& result) {
    if (fbDev->common.version >= 1 && fbDev->dump) {
        const size_t SIZE = 4096;
        char buffer[SIZE];
        fbDev->dump(fbDev, buffer, SIZE);
        result.append(buffer);
    }
    mHwc.fbDump(result);
    ConsumerBase::dump(result);
}

+6 −13
Original line number Diff line number Diff line
@@ -30,13 +30,13 @@ namespace android {

class Rect;
class String8;
class HWComposer;

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

class FramebufferSurface : public ConsumerBase {
public:

    static sp<FramebufferSurface> create();
    FramebufferSurface(HWComposer& hwc);

    bool isUpdateOnDemand() const { return false; }
    status_t setUpdateRectangle(const Rect& updateRect);
@@ -49,22 +49,12 @@ public:
    // BufferQueue.  The new buffer is returned in the 'buffer' argument.
    status_t nextBuffer(sp<GraphicBuffer>* buffer);

    // FIXME: currently there are information we can only get from the
    // FB HAL, and FB HAL can only be instantiated once on some devices.
    // Eventually this functionality will have to move in HWC or somewhere else.
    const framebuffer_device_t* getFbHal() const {
        return fbDev;
    }

private:
    FramebufferSurface();
    virtual ~FramebufferSurface(); // this class cannot be overloaded
    virtual ~FramebufferSurface() { }; // this class cannot be overloaded

    virtual void onFrameAvailable();
    virtual void freeBufferLocked(int slotIndex);

    framebuffer_device_t* fbDev;

    // mCurrentBufferIndex is the slot index of the current buffer or
    // INVALID_BUFFER_SLOT to indicate that either there is no current buffer
    // or the buffer is not associated with a slot.
@@ -73,6 +63,9 @@ private:
    // mCurrentBuffer is the current buffer or NULL to indicate that there is
    // no current buffer.
    sp<GraphicBuffer> mCurrentBuffer;

    // Hardware composer, owned by SurfaceFlinger.
    HWComposer& mHwc;
};

// ---------------------------------------------------------------------------
+142 −69
Original line number Diff line number Diff line
@@ -90,10 +90,9 @@ struct HWComposer::cb_context {

HWComposer::HWComposer(
        const sp<SurfaceFlinger>& flinger,
        EventHandler& handler,
        framebuffer_device_t const* fbDev)
        EventHandler& handler)
    : mFlinger(flinger),
      mModule(0), mHwc(0), mNumDisplays(1),
      mFbDev(0), mHwc(0), mNumDisplays(1),
      mCBContext(new cb_context),
      mEventHandler(handler),
      mVSyncCount(0), mDebugForceFakeVSync(false)
@@ -107,22 +106,10 @@ HWComposer::HWComposer(
    mDebugForceFakeVSync = atoi(value);

    bool needVSyncThread = true;
    int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
    ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
    if (err == 0) {
        err = hwc_open_1(mModule, &mHwc);
        ALOGE_IF(err, "%s device failed to initialize (%s)",
                HWC_HARDWARE_COMPOSER, strerror(-err));
        if (err == 0) {
            if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
                    hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION ||
                    hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) {
                ALOGE("%s device version %#x unsupported, will not be used",
                        HWC_HARDWARE_COMPOSER, mHwc->common.version);
                hwc_close_1(mHwc);
                mHwc = NULL;
            }
        }

    // Note: some devices may insist that the FB HAL be opened before HWC.
    loadFbHalModule();
    loadHwcModule();

    if (mHwc) {
        ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
@@ -140,8 +127,9 @@ HWComposer::HWComposer(
            mHwc->registerProcs(mHwc, &mCBContext->procs);
        }

            // always turn vsync off when we start
        // don't need a vsync thread if we have a hardware composer
        needVSyncThread = false;
        // always turn vsync off when we start
        mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);

        // these IDs are always reserved
@@ -161,17 +149,19 @@ HWComposer::HWComposer(
            mNumDisplays = 1;
        }
    }
    }

    if (fbDev) {
    if (mFbDev) {
        ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),
                "should only have fbdev if no hwc or hwc is 1.0");

        DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
        disp.xdpi = fbDev->xdpi;
        disp.ydpi = fbDev->ydpi;
        disp.xres = mFbDev->width;
        disp.yres = mFbDev->height;
        disp.format = mFbDev->format;
        disp.xdpi = mFbDev->xdpi;
        disp.ydpi = mFbDev->ydpi;
        if (disp.refresh == 0) {
            disp.refresh = nsecs_t(1e9 / fbDev->fps);
            disp.refresh = nsecs_t(1e9 / mFbDev->fps);
            ALOGW("getting VSYNC period from fb HAL: %lld", disp.refresh);
        }
        if (disp.refresh == 0) {
@@ -197,9 +187,57 @@ HWComposer::~HWComposer() {
    if (mHwc) {
        hwc_close_1(mHwc);
    }
    if (mFbDev) {
        framebuffer_close(mFbDev);
    }
    delete mCBContext;
}

// Load and prepare the hardware composer module.  Sets mHwc.
void HWComposer::loadHwcModule()
{
    hw_module_t const* module;

    if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
        ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID);
        return;
    }

    int err = hwc_open_1(module, &mHwc);
    if (err) {
        ALOGE("%s device failed to initialize (%s)",
              HWC_HARDWARE_COMPOSER, strerror(-err));
        return;
    }

    if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
            hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION ||
            hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) {
        ALOGE("%s device version %#x unsupported, will not be used",
              HWC_HARDWARE_COMPOSER, mHwc->common.version);
        hwc_close_1(mHwc);
        mHwc = NULL;
        return;
    }
}

// Load and prepare the FB HAL, which uses the gralloc module.  Sets mFbDev.
void HWComposer::loadFbHalModule()
{
    hw_module_t const* module;

    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) != 0) {
        ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
        return;
    }

    int err = framebuffer_open(module, &mFbDev);
    if (err) {
        ALOGE("framebuffer_open failed (%s)", strerror(-err));
        return;
    }
}

status_t HWComposer::initCheck() const {
    return mHwc ? NO_ERROR : NO_INIT;
}
@@ -265,6 +303,7 @@ static const uint32_t DISPLAY_ATTRIBUTES[] = {
void HWComposer::queryDisplayProperties(int disp) {
    ALOG_ASSERT(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));

    // use zero as default value for unspecified attributes
    int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];
    memset(values, 0, sizeof(values));

@@ -283,12 +322,10 @@ void HWComposer::queryDisplayProperties(int disp) {
            mDisplayData[disp].refresh = nsecs_t(values[i]);
            break;
        case HWC_DISPLAY_RESOLUTION_X:
            // TODO: we'll probably want to remember this eventually
            w = values[i];
            mDisplayData[disp].xres = values[i];
            break;
        case HWC_DISPLAY_RESOLUTION_Y:
            // TODO: we'll probably want to remember this eventually
            h = values[i];
            mDisplayData[disp].yres = values[i];
            break;
        case HWC_DISPLAY_DPI_X:
            mDisplayData[disp].xdpi = values[i] / 1000.0f;
@@ -336,25 +373,37 @@ status_t HWComposer::freeDisplayId(int32_t id) {
    return NO_ERROR;
}

nsecs_t HWComposer::getRefreshPeriod() const {
    return mDisplayData[HWC_DISPLAY_PRIMARY].refresh;
nsecs_t HWComposer::getRefreshPeriod(int disp) const {
    return mDisplayData[disp].refresh;
}

nsecs_t HWComposer::getRefreshTimestamp() const {
nsecs_t HWComposer::getRefreshTimestamp(int disp) const {
    // this returns the last refresh timestamp.
    // if the last one is not available, we estimate it based on
    // the refresh period and whatever closest timestamp we have.
    Mutex::Autolock _l(mLock);
    nsecs_t now = systemTime(CLOCK_MONOTONIC);
    return now - ((now - mLastHwVSync) %  mDisplayData[HWC_DISPLAY_PRIMARY].refresh);
    return now - ((now - mLastHwVSync) %  mDisplayData[disp].refresh);
}

uint32_t HWComposer::getResolutionX(int disp) const {
    return mDisplayData[disp].xres;
}

uint32_t HWComposer::getResolutionY(int disp) const {
    return mDisplayData[disp].yres;
}

uint32_t HWComposer::getFormat(int disp) const {
    return mDisplayData[disp].format;
}

float HWComposer::getDpiX() const {
    return mDisplayData[HWC_DISPLAY_PRIMARY].xdpi;
float HWComposer::getDpiX(int disp) const {
    return mDisplayData[disp].xdpi;
}

float HWComposer::getDpiY() const {
    return mDisplayData[HWC_DISPLAY_PRIMARY].ydpi;
float HWComposer::getDpiY(int disp) const {
    return mDisplayData[disp].ydpi;
}

void HWComposer::eventControl(int event, int enabled) {
@@ -493,6 +542,30 @@ size_t HWComposer::getNumLayers(int32_t id) const {
            mDisplayData[id].list->numHwLayers : 0;
}

int HWComposer::fbPost(buffer_handle_t buffer)
{
    return mFbDev->post(mFbDev, buffer);
}

int HWComposer::fbCompositionComplete()
{
    if (mFbDev->compositionComplete) {
        return mFbDev->compositionComplete(mFbDev);
    } else {
        return INVALID_OPERATION;
    }
}

void HWComposer::fbDump(String8& result) {
    if (mFbDev->common.version >= 1 && mFbDev->dump) {
        const size_t SIZE = 4096;
        char buffer[SIZE];
        mFbDev->dump(mFbDev, buffer, SIZE);
        result.append(buffer);
    }
}


/*
 * Helper template to implement a concrete HWCLayer
 * This holds the pointer to the concrete hwc layer type
@@ -680,7 +753,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
    : mHwc(hwc), mEnabled(false),
      mNextFakeVSync(0),
      mRefreshPeriod(hwc.getRefreshPeriod())
      mRefreshPeriod(hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY))
{
}

+21 −7
Original line number Diff line number Diff line
@@ -64,8 +64,7 @@ public:

    HWComposer(
            const sp<SurfaceFlinger>& flinger,
            EventHandler& handler,
            framebuffer_device_t const* fbDev);
            EventHandler& handler);

    ~HWComposer();

@@ -107,6 +106,11 @@ public:
    // needed forward declarations
    class LayerListIterator;

    // Forwarding to FB HAL for pre-HWC-1.1 code (see FramebufferSurface).
    int fbPost(buffer_handle_t buffer);
    int fbCompositionComplete();
    void fbDump(String8& result);

    /*
     * Interface to hardware composer's layers functionality.
     * This abstracts the HAL interface to layers which can evolve in
@@ -208,10 +212,15 @@ public:

    void eventControl(int event, int enabled);

    nsecs_t getRefreshPeriod() const;
    nsecs_t getRefreshTimestamp() const;
    float getDpiX() const;
    float getDpiY() const;
    // Query display parameters.  Pass in a display index (e.g.
    // HWC_DISPLAY_PRIMARY).
    nsecs_t getRefreshPeriod(int disp) const;
    nsecs_t getRefreshTimestamp(int disp) const;
    uint32_t getResolutionX(int disp) const;
    uint32_t getResolutionY(int disp) const;
    uint32_t getFormat(int disp) const;
    float getDpiX(int disp) const;
    float getDpiY(int disp) const;

    // this class is only used to fake the VSync event on systems that don't
    // have it.
@@ -236,6 +245,8 @@ public:
            const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;

private:
    void loadHwcModule();
    void loadFbHalModule();

    LayerListIterator getLayerIterator(int32_t id, size_t index);
    size_t getNumLayers(int32_t id) const;
@@ -261,6 +272,9 @@ private:
        ~DisplayData() {
            free(list);
        }
        uint32_t xres;
        uint32_t yres;
        uint32_t format;    // pixel format from FB hal, for pre-hwc-1.1
        float xdpi;
        float ydpi;
        nsecs_t refresh;
@@ -271,7 +285,7 @@ private:
    };

    sp<SurfaceFlinger>              mFlinger;
    hw_module_t const*              mModule;
    framebuffer_device_t*           mFbDev;
    struct hwc_composer_device_1*   mHwc;
    // invariant: mLists[0] != NULL iff mHwc != NULL
    // mLists[i>0] can be NULL. that display is to be ignored
+3 −2
Original line number Diff line number Diff line
@@ -515,7 +515,7 @@ void Layer::onPostComposition() {
        const size_t offset = mFrameLatencyOffset;
        mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp();
        mFrameStats[offset].set = systemTime();
        mFrameStats[offset].vsync = hwc.getRefreshTimestamp();
        mFrameStats[offset].vsync = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
        mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
        mFrameLatencyNeeded = false;
    }
@@ -726,7 +726,8 @@ void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
{
    LayerBaseClient::dumpStats(result, buffer, SIZE);
    const size_t o = mFrameLatencyOffset;
    const nsecs_t period = mFlinger->getHwComposer().getRefreshPeriod();
    const nsecs_t period =
            mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
    result.appendFormat("%lld\n", period);
    for (size_t i=0 ; i<128 ; i++) {
        const size_t index = (o+i) % 128;
Loading