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

Commit 99ce5cde authored by Mathias Agopian's avatar Mathias Agopian
Browse files

separate transactions from updates

with this changes, SF transactions are handled as soon as possible
but do not trigger updates. the update is delayed until the next
vsync.

this allows us to work much better without requiring triple-buffering.

Change-Id: I1fa10794d0cf742129f0877698b7b1e1f2ec7401
parent 93bfeedd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,8 @@ public:
     * should be destroyed and getEvents() shouldn't be called again.
     */
    ssize_t getEvents(Event* events, size_t count);
    static ssize_t getEvents(const sp<BitTube>& dataChannel,
            Event* events, size_t count);

    /*
     * setVsyncRate() sets the Event::VSync delivery rate. A value of
+7 −1
Original line number Diff line number Diff line
@@ -80,7 +80,13 @@ status_t DisplayEventReceiver::requestNextVsync() {

ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
        size_t count) {
    ssize_t size = mDataChannel->read(events, sizeof(events[0])*count);
    return DisplayEventReceiver::getEvents(mDataChannel, events, count);
}

ssize_t DisplayEventReceiver::getEvents(const sp<BitTube>& dataChannel,
        Event* events, size_t count)
{
    ssize_t size = dataChannel->read(events, sizeof(events[0])*count);
    ALOGE_IF(size<0,
            "DisplayEventReceiver::getEvents error (%s)",
            strerror(-size));
+0 −1
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ ifeq ($(TARGET_BOARD_PLATFORM), omap3)
endif
ifeq ($(TARGET_BOARD_PLATFORM), omap4)
	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
	LOCAL_CFLAGS += -DUSE_TRIPLE_BUFFERING=1
endif
ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
+30 −9
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ Layer::Layer(SurfaceFlinger* flinger,
        mCurrentTransform(0),
        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
        mCurrentOpacity(true),
        mRefreshPending(0),
        mFrameLatencyNeeded(false),
        mFrameLatencyOffset(0),
        mFormat(PIXEL_FORMAT_NONE),
@@ -97,12 +98,7 @@ void Layer::onFirstRef()
    mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);
    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
    mSurfaceTexture->setSynchronousMode(true);
#ifdef USE_TRIPLE_BUFFERING
#warning "using triple buffering"
    mSurfaceTexture->setBufferCountServer(3);
#else
    mSurfaceTexture->setBufferCountServer(2);
#endif
}

Layer::~Layer()
@@ -113,7 +109,7 @@ Layer::~Layer()

void Layer::onFrameQueued() {
    android_atomic_inc(&mQueuedFrames);
    mFlinger->signalEvent();
    mFlinger->signalLayerUpdate();
}

// called with SurfaceFlinger::mStateLock as soon as the layer is entered
@@ -407,16 +403,37 @@ bool Layer::isCropped() const {
// pageflip handling...
// ----------------------------------------------------------------------------

bool Layer::onPreComposition()
{
    // if there was more than one pending update, request a refresh
    if (mRefreshPending >= 2) {
        mRefreshPending = 0;
        return true;
    }
    mRefreshPending = 0;
    return false;
}

void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
    if (mQueuedFrames > 0) {

        // if we've already called updateTexImage() without going through
        // a composition step, we have to skip this layer at this point
        // because we cannot call updateTeximage() without a corresponding
        // compositionComplete() call.
        // we'll trigger an update in onPreComposition().
        if (mRefreshPending++) {
            return;
        }

        // Capture the old state of the layer for comparisons later
        const bool oldOpacity = isOpaque();
        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;

        // signal another event if we have more frames pending
        if (android_atomic_dec(&mQueuedFrames) > 1) {
            mFlinger->signalEvent();
            mFlinger->signalLayerUpdate();
        }

        if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
@@ -519,6 +536,10 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
void Layer::unlockPageFlip(
        const Transform& planeTransform, Region& outDirtyRegion)
{
    if (mRefreshPending >= 2) {
        return;
    }

    Region dirtyRegion(mPostedDirtyRegion);
    if (!dirtyRegion.isEmpty()) {
        mPostedDirtyRegion.clear();
@@ -552,9 +573,9 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
    snprintf(buffer, SIZE,
            "      "
            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
            " transform-hint=0x%02x, queued-frames=%d\n",
            " transform-hint=0x%02x, queued-frames=%d, mRefreshPending=%d\n",
            mFormat, w0, h0, s0,f0,
            getTransformHint(), mQueuedFrames);
            getTransformHint(), mQueuedFrames, mRefreshPending);

    result.append(buffer);

+4 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ public:
    virtual wp<IBinder> getSurfaceTextureBinder() const;

    virtual void onLayerDisplayed();
    virtual bool onPreComposition();

    // only for debugging
    inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
@@ -115,14 +116,17 @@ private:
    uint32_t mCurrentTransform;
    uint32_t mCurrentScalingMode;
    bool mCurrentOpacity;
    size_t mRefreshPending;
    bool mFrameLatencyNeeded;
    int mFrameLatencyOffset;

    struct Statistics {
        Statistics() : timestamp(0), set(0), vsync(0) { }
        nsecs_t timestamp;  // buffer timestamp
        nsecs_t set;        // buffer displayed timestamp
        nsecs_t vsync;      // vsync immediately before set
    };

    // protected by mLock
    Statistics mFrameStats[128];

Loading