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

Commit 36337a7b authored by Harshad Bhutada's avatar Harshad Bhutada Committed by toastcfh
Browse files

frameworks/base: Add support for triple buffering

Change-Id: If3cf17e5eb8c6d29cca490665d5dcae1b3915b6a
parent e1c7a4e0
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -30,7 +30,11 @@


#include <ui/egl/android_natives.h>
#include <ui/egl/android_natives.h>


#ifdef QCOM_HARDWARE
#define NUM_FRAMEBUFFERS_MAX  3
#else
#define NUM_FRAME_BUFFERS  2
#define NUM_FRAME_BUFFERS  2
#endif


extern "C" EGLNativeWindowType android_createDisplaySurface(void);
extern "C" EGLNativeWindowType android_createDisplaySurface(void);


@@ -91,7 +95,11 @@ private:
    framebuffer_device_t* fbDev;
    framebuffer_device_t* fbDev;
    alloc_device_t* grDev;
    alloc_device_t* grDev;


#ifdef QCOM_HARDWARE
    sp<NativeBuffer> buffers[NUM_FRAMEBUFFERS_MAX];
#else
    sp<NativeBuffer> buffers[NUM_FRAME_BUFFERS];
    sp<NativeBuffer> buffers[NUM_FRAME_BUFFERS];
#endif
    sp<NativeBuffer> front;
    sp<NativeBuffer> front;
    
    
    mutable Mutex mutex;
    mutable Mutex mutex;
+4 −0
Original line number Original line Diff line number Diff line
@@ -66,6 +66,10 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_C_INCLUDES := \
LOCAL_C_INCLUDES := \
    external/skia/include/core
    external/skia/include/core


ifeq ($(BOARD_USES_QCOM_HARDWARE),true)
LOCAL_CFLAGS += -DQCOM_HARDWARE
endif

LOCAL_MODULE:= libui
LOCAL_MODULE:= libui


include $(BUILD_SHARED_LIBRARY)
include $(BUILD_SHARED_LIBRARY)
+65 −1
Original line number Original line Diff line number Diff line
@@ -97,9 +97,17 @@ FramebufferNativeWindow::FramebufferNativeWindow()
        mUpdateOnDemand = (fbDev->setUpdateRect != 0);
        mUpdateOnDemand = (fbDev->setUpdateRect != 0);
        
        
        // initialize the buffer FIFO
        // initialize the buffer FIFO
#ifdef QCOM_HARDWARE
	mNumBuffers = fbDev->numFramebuffers;
	mNumFreeBuffers = mNumBuffers;
	mBufferHead = 0;

	LOGD("mNumBuffers = %d", mNumBuffers);
#else
        mNumBuffers = NUM_FRAME_BUFFERS;
        mNumBuffers = NUM_FRAME_BUFFERS;
        mNumFreeBuffers = NUM_FRAME_BUFFERS;
        mNumFreeBuffers = NUM_FRAME_BUFFERS;
        mBufferHead = mNumBuffers-1;
        mBufferHead = mNumBuffers-1;
#endif


        for (i = 0; i < mNumBuffers; i++)
        for (i = 0; i < mNumBuffers; i++)
        {
        {
@@ -142,15 +150,26 @@ FramebufferNativeWindow::FramebufferNativeWindow()
    ANativeWindow::queueBuffer = queueBuffer;
    ANativeWindow::queueBuffer = queueBuffer;
    ANativeWindow::query = query;
    ANativeWindow::query = query;
    ANativeWindow::perform = perform;
    ANativeWindow::perform = perform;
#ifdef QCOM_HARDWARE
    ANativeWindow::cancelBuffer = NULL;
#endif
}
}


FramebufferNativeWindow::~FramebufferNativeWindow() 
FramebufferNativeWindow::~FramebufferNativeWindow() 
{
{
    if (grDev) {
    if (grDev) {
#ifdef QCOM_HARDWARE
       for(int i = 0; i < mNumBuffers; i++) {
            if (buffers[i] != NULL) {
                grDev->free(grDev, buffers[i]->handle);
            }
        }
#else
        if (buffers[0] != NULL)
        if (buffers[0] != NULL)
            grDev->free(grDev, buffers[0]->handle);
            grDev->free(grDev, buffers[0]->handle);
        if (buffers[1] != NULL)
        if (buffers[1] != NULL)
            grDev->free(grDev, buffers[1]->handle);
            grDev->free(grDev, buffers[1]->handle);
#endif
        gralloc_close(grDev);
        gralloc_close(grDev);
    }
    }


@@ -201,23 +220,46 @@ int FramebufferNativeWindow::getCurrentBufferIndex() const
}
}


int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window, 
int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window, 
#ifdef QCOM_HARDWARE
        android_native_buffer_t** buffer)
#else
        ANativeWindowBuffer** buffer)
        ANativeWindowBuffer** buffer)
#endif
{
{
    FramebufferNativeWindow* self = getSelf(window);
    FramebufferNativeWindow* self = getSelf(window);
#ifndef QCOM_HARDWARE
    Mutex::Autolock _l(self->mutex);
    Mutex::Autolock _l(self->mutex);
#endif
    framebuffer_device_t* fb = self->fbDev;
    framebuffer_device_t* fb = self->fbDev;


#ifdef QCOM_HARDWARE
    int index = self->mBufferHead;
#else
    int index = self->mBufferHead++;
    int index = self->mBufferHead++;
    if (self->mBufferHead >= self->mNumBuffers)
    if (self->mBufferHead >= self->mNumBuffers)
        self->mBufferHead = 0;
        self->mBufferHead = 0;
#endif


    GraphicLog& logger(GraphicLog::getInstance());
    GraphicLog& logger(GraphicLog::getInstance());
    logger.log(GraphicLog::SF_FB_DEQUEUE_BEFORE, index);
    logger.log(GraphicLog::SF_FB_DEQUEUE_BEFORE, index);


#ifdef QCOM_HARDWARE
    /* The buffer is available, return it */
    Mutex::Autolock _l(self->mutex);

    // wait if the number of free buffers <= 0
    while (self->mNumFreeBuffers <= 0) {
#else
    // wait for a free buffer
    // wait for a free buffer
    while (!self->mNumFreeBuffers) {
    while (!self->mNumFreeBuffers) {
#endif
        self->mCondition.wait(self->mutex);
        self->mCondition.wait(self->mutex);
    }
    }
#ifdef QCOM_HARDWARE
    self->mBufferHead++;
    if (self->mBufferHead >= self->mNumBuffers)
        self->mBufferHead = 0;
#endif
    // get this buffer
    // get this buffer
    self->mNumFreeBuffers--;
    self->mNumFreeBuffers--;
    self->mCurrentBufferIndex = index;
    self->mCurrentBufferIndex = index;
@@ -229,20 +271,37 @@ int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
}
}


int FramebufferNativeWindow::lockBuffer(ANativeWindow* window, 
int FramebufferNativeWindow::lockBuffer(ANativeWindow* window, 
#ifdef QCOM_HARDWARE
        android_native_buffer_t* buffer)
#else
        ANativeWindowBuffer* buffer)
        ANativeWindowBuffer* buffer)
#endif
{
{
    FramebufferNativeWindow* self = getSelf(window);
    FramebufferNativeWindow* self = getSelf(window);
#ifdef QCOM_HARDWARE
    framebuffer_device_t* fb = self->fbDev;
    int index = -1;

    {
        Mutex::Autolock _l(self->mutex);
        index = self->mCurrentBufferIndex;
    }
#else
    Mutex::Autolock _l(self->mutex);
    Mutex::Autolock _l(self->mutex);


    const int index = self->mCurrentBufferIndex;
    const int index = self->mCurrentBufferIndex;
#endif
    GraphicLog& logger(GraphicLog::getInstance());
    GraphicLog& logger(GraphicLog::getInstance());
    logger.log(GraphicLog::SF_FB_LOCK_BEFORE, index);
    logger.log(GraphicLog::SF_FB_LOCK_BEFORE, index);


#ifdef QCOM_HARDWARE
    fb->lockBuffer(fb, index);
#else
    // wait that the buffer we're locking is not front anymore
    // wait that the buffer we're locking is not front anymore
    while (self->front == buffer) {
    while (self->front == buffer) {
        self->mCondition.wait(self->mutex);
        self->mCondition.wait(self->mutex);
    }
    }

#endif
    logger.log(GraphicLog::SF_FB_LOCK_AFTER, index);
    logger.log(GraphicLog::SF_FB_LOCK_AFTER, index);


    return NO_ERROR;
    return NO_ERROR;
@@ -289,6 +348,11 @@ int FramebufferNativeWindow::query(const ANativeWindow* window,
        case NATIVE_WINDOW_CONCRETE_TYPE:
        case NATIVE_WINDOW_CONCRETE_TYPE:
            *value = NATIVE_WINDOW_FRAMEBUFFER;
            *value = NATIVE_WINDOW_FRAMEBUFFER;
            return NO_ERROR;
            return NO_ERROR;
#ifdef QCOM_HARDWARE
        case NATIVE_WINDOW_NUM_BUFFERS:
            *value = fb->numFramebuffers;
            return NO_ERROR;
#endif
        case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
        case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
            *value = 0;
            *value = 0;
            return NO_ERROR;
            return NO_ERROR;