diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk index 44108c7..e3ca6f9 100644 --- a/libgralloc/Android.mk +++ b/libgralloc/Android.mk @@ -26,7 +26,7 @@ LOCAL_C_INCLUDES += hardware/qcom/display/libqcomui LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM) LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS := -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).gralloc\" \ - -DDEBUG_CALC_FPS + -DDEBUG_CALC_FPS -Wno-missing-field-initializers LOCAL_SRC_FILES := gpu.cpp gralloc.cpp framebuffer.cpp mapper.cpp ifeq ($(TARGET_USES_POST_PROCESSING),true) diff --git a/libgralloc/fb_priv.h b/libgralloc/fb_priv.h index 677d1c1..21bfac4 100644 --- a/libgralloc/fb_priv.h +++ b/libgralloc/fb_priv.h @@ -26,84 +26,6 @@ #define NO_SURFACEFLINGER_SWAPINTERVAL #define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF -#ifdef __cplusplus -template -struct Node -{ - T data; - Node *next; -}; - -template -class Queue -{ - public: - Queue(): front(NULL), back(NULL), len(0) {dummy = new T;} - ~Queue() - { - clear(); - delete dummy; - } - void push(const T& item) //add an item to the back of the queue - { - if(len != 0) { //if the queue is not empty - back->next = new Node; //create a new node - back = back->next; //set the new node as the back node - back->data = item; - back->next = NULL; - } else { - back = new Node; - back->data = item; - back->next = NULL; - front = back; - } - len++; - } - void pop() //remove the first item from the queue - { - if (isEmpty()) - return; //if the queue is empty, no node to dequeue - T item = front->data; - Node *tmp = front; - front = front->next; - delete tmp; - if(front == NULL) //if the queue is empty, update the back pointer - back = NULL; - len--; - return; - } - T& getHeadValue() const //return the value of the first item in the queue - { //without modification to the structure - if (isEmpty()) { - ALOGE("Error can't get head of empty queue"); - return *dummy; - } - return front->data; - } - - bool isEmpty() const //returns true if no elements are in the queue - { - return (front == NULL); - } - - size_t size() const //returns the amount of elements in the queue - { - return len; - } - - private: - Node *front; - Node *back; - size_t len; - void clear() - { - while (!isEmpty()) - pop(); - } - T *dummy; -}; -#endif - enum hdmi_mirroring_state { HDMI_NO_MIRRORING, HDMI_UI_MIRRORING, @@ -111,17 +33,6 @@ enum hdmi_mirroring_state { struct private_handle_t; -struct qbuf_t { - buffer_handle_t buf; - int idx; -}; - -enum buf_state { - SUB, - REF, - AVL -}; - enum { // flag to indicate we'll post this buffer PRIV_USAGE_LOCKED_FOR_POST = 0x80000000, @@ -129,17 +40,8 @@ enum { PRIV_MAX_SWAP_INTERVAL = 1, }; - -struct avail_t { - pthread_mutex_t lock; - pthread_cond_t cond; - bool is_avail; - buf_state state; -}; - struct private_module_t { gralloc_module_t base; - struct private_handle_t* framebuffer; uint32_t fbFormat; uint32_t flags; @@ -147,18 +49,12 @@ struct private_module_t { uint32_t bufferMask; pthread_mutex_t lock; buffer_handle_t currentBuffer; - struct fb_var_screeninfo info; struct fb_fix_screeninfo finfo; float xdpi; float ydpi; float fps; uint32_t swapInterval; - Queue disp; // non-empty when buffer is ready for display - int currentIdx; - struct avail_t avail[NUM_FRAMEBUFFERS_MAX]; - pthread_mutex_t qlock; - pthread_cond_t qpost; #if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY) int orientation; int videoOverlay; // VIDEO_OVERLAY - 2D or 3D diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp index 4935785..d55c298 100644 --- a/libgralloc/framebuffer.cpp +++ b/libgralloc/framebuffer.cpp @@ -55,8 +55,6 @@ static inline int max(int a, int b) { return (a>b) ? a : b; } -char framebufferStateName[] = {'S', 'R', 'A'}; - enum { PAGE_FLIP = 0x00000001, LOCKED = 0x00000002 @@ -70,6 +68,8 @@ struct fb_context_t { static int fb_setSwapInterval(struct framebuffer_device_t* dev, int interval) { + //XXX: Get the value here and implement along with + //single vsync in HWC char pval[PROPERTY_VALUE_MAX]; property_get("debug.egl.swapinterval", pval, "-1"); int property_interval = atoi(pval); @@ -100,81 +100,6 @@ static int fb_setUpdateRect(struct framebuffer_device_t* dev, return 0; } -static void *disp_loop(void *ptr) -{ - struct qbuf_t nxtBuf; - static int cur_buf=-1; - private_module_t *m = reinterpret_cast(ptr); - - while (1) { - pthread_mutex_lock(&(m->qlock)); - - // wait (sleep) while display queue is empty; - if (m->disp.isEmpty()) { - pthread_cond_wait(&(m->qpost),&(m->qlock)); - } - - // dequeue next buff to display and lock it - nxtBuf = m->disp.getHeadValue(); - m->disp.pop(); - pthread_mutex_unlock(&(m->qlock)); - - // post buf out to display synchronously - private_handle_t const* hnd = reinterpret_cast - (nxtBuf.buf); - const size_t offset = hnd->base - m->framebuffer->base; - m->info.activate = FB_ACTIVATE_VBL; - m->info.yoffset = offset / m->finfo.line_length; - -#if defined(HDMI_DUAL_DISPLAY) - pthread_mutex_lock(&m->overlayLock); - m->orientation = neworientation; - m->currentOffset = offset; - m->hdmiStateChanged = true; - pthread_cond_signal(&(m->overlayPost)); - pthread_mutex_unlock(&m->overlayLock); -#endif - if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) { - ALOGE("ERROR FBIOPUT_VSCREENINFO failed; frame not displayed"); - } - - CALC_FPS(); - - if (cur_buf == -1) { - int nxtAvail = ((nxtBuf.idx + 1) % m->numBuffers); - pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock)); - m->avail[nxtBuf.idx].is_avail = true; - m->avail[nxtBuf.idx].state = SUB; - pthread_cond_signal(&(m->avail[nxtBuf.idx].cond)); - pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock)); - } else { -#if 0 //XXX: Triple FB - pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock)); - if (m->avail[nxtBuf.idx].state != SUB) { - ALOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", nxtBuf.idx, - framebufferStateName[m->avail[nxtBuf.idx].state], - framebufferStateName[SUB]); - } - - m->avail[nxtBuf.idx].state = REF; - pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock)); - if (m->avail[cur_buf].state != REF) { - ALOGE_IF(m->swapInterval != 0, "[%d] state %c, expected %c", cur_buf, - framebufferStateName[m->avail[cur_buf].state], - framebufferStateName[SUB]); - } - m->avail[cur_buf].state = AVL; -#endif - pthread_mutex_lock(&(m->avail[cur_buf].lock)); - m->avail[cur_buf].is_avail = true; - pthread_cond_signal(&(m->avail[cur_buf].cond)); - pthread_mutex_unlock(&(m->avail[cur_buf].lock)); - } - cur_buf = nxtBuf.idx; - } - return NULL; -} - #if defined(HDMI_DUAL_DISPLAY) static int closeHDMIChannel(private_module_t* m) { @@ -577,9 +502,6 @@ static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) if (private_handle_t::validate(buffer) < 0) return -EINVAL; - int nxtIdx;//, futureIdx = -1; - bool reuse; - struct qbuf_t qb; fb_context_t* ctx = (fb_context_t*)dev; private_handle_t const* hnd = reinterpret_cast(buffer); @@ -587,67 +509,25 @@ static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) dev->common.module); if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { + m->base.lock(&m->base, buffer, + PRIV_USAGE_LOCKED_FOR_POST, + 0, 0, m->info.xres, m->info.yres, NULL); - reuse = false; - nxtIdx = (m->currentIdx + 1) % m->numBuffers; - //futureIdx = (nxtIdx + 1) % m->numBuffers; - if (m->swapInterval == 0) { - // if SwapInterval = 0 and no buffers available then reuse - // current buf for next rendering so don't post new buffer - if (pthread_mutex_trylock(&(m->avail[nxtIdx].lock))) { - reuse = true; - } else { - if (! m->avail[nxtIdx].is_avail) - reuse = true; - pthread_mutex_unlock(&(m->avail[nxtIdx].lock)); - } + if (m->currentBuffer) { + m->base.unlock(&m->base, m->currentBuffer); + m->currentBuffer = 0; } - if(!reuse){ - // unlock previous ("current") Buffer and lock the new buffer - m->base.lock(&m->base, buffer, - PRIV_USAGE_LOCKED_FOR_POST, - 0,0, m->info.xres, m->info.yres, NULL); - - // post/queue the new buffer - pthread_mutex_lock(&(m->avail[nxtIdx].lock)); - m->avail[nxtIdx].is_avail = false; -#if 0 //XXX: Triple FB - if (m->avail[nxtIdx].is_avail != true) { - ALOGE_IF(m->swapInterval != 0, "Found %d buf to be not avail", nxtIdx); - } - - if (m->avail[nxtIdx].state != AVL) { - ALOGD("[%d] state %c, expected %c", nxtIdx, - framebufferStateName[m->avail[nxtIdx].state], - framebufferStateName[AVL]); - } - - m->avail[nxtIdx].state = SUB; -#endif - pthread_mutex_unlock(&(m->avail[nxtIdx].lock)); - - qb.idx = nxtIdx; - qb.buf = buffer; - pthread_mutex_lock(&(m->qlock)); - m->disp.push(qb); - pthread_cond_signal(&(m->qpost)); - pthread_mutex_unlock(&(m->qlock)); - - if (m->currentBuffer) - m->base.unlock(&m->base, m->currentBuffer); - - m->currentBuffer = buffer; - m->currentIdx = nxtIdx; - } else { - if (m->currentBuffer) - m->base.unlock(&m->base, m->currentBuffer); - m->base.lock(&m->base, buffer, - PRIV_USAGE_LOCKED_FOR_POST, - 0,0, m->info.xres, m->info.yres, NULL); - m->currentBuffer = buffer; + const size_t offset = hnd->base - m->framebuffer->base; + m->info.activate = FB_ACTIVATE_VBL; + m->info.yoffset = offset / m->finfo.line_length; + if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) { + ALOGE("FBIOPUT_VSCREENINFO failed"); + m->base.unlock(&m->base, buffer); + return -errno; } - + CALC_FPS(); + m->currentBuffer = buffer; } return 0; } @@ -660,25 +540,6 @@ static int fb_compositionComplete(struct framebuffer_device_t* dev) return 0; } -static int fb_lockBuffer(struct framebuffer_device_t* dev, int index) -{ - private_module_t* m = reinterpret_cast( - dev->common.module); - - // Return immediately if the buffer is available - if ((m->avail[index].state == AVL) || (m->swapInterval == 0)) - return 0; - - pthread_mutex_lock(&(m->avail[index].lock)); - while (m->avail[index].state != AVL) { - pthread_cond_wait(&(m->avail[index].cond), - &(m->avail[index].lock)); - } - pthread_mutex_unlock(&(m->avail[index].lock)); - - return 0; -} - int mapFrameBufferLocked(struct private_module_t* module) { // already initialized... @@ -862,42 +723,10 @@ int mapFrameBufferLocked(struct private_module_t* module) module->xdpi = xdpi; module->ydpi = ydpi; module->fps = fps; - -#ifdef NO_SURFACEFLINGER_SWAPINTERVAL - char pval[PROPERTY_VALUE_MAX]; - property_get("debug.gr.swapinterval", pval, "1"); - module->swapInterval = atoi(pval); - if (module->swapInterval < PRIV_MIN_SWAP_INTERVAL || - module->swapInterval > PRIV_MAX_SWAP_INTERVAL) { - module->swapInterval = 1; - ALOGW("Out of range (%d to %d) value for debug.gr.swapinterval, using 1", - PRIV_MIN_SWAP_INTERVAL, - PRIV_MAX_SWAP_INTERVAL); - } - -#else - /* when surfaceflinger supports swapInterval then can just do this */ module->swapInterval = 1; -#endif CALC_INIT(); - module->currentIdx = -1; - pthread_cond_init(&(module->qpost), NULL); - pthread_mutex_init(&(module->qlock), NULL); - for (i = 0; i < NUM_FRAMEBUFFERS_MAX; i++) { - pthread_mutex_init(&(module->avail[i].lock), NULL); - pthread_cond_init(&(module->avail[i].cond), NULL); - module->avail[i].is_avail = true; - module->avail[i].state = AVL; - } - - /* create display update thread */ - pthread_t disp_thread; - if (pthread_create(&disp_thread, NULL, &disp_loop, (void *) module)) { - return -errno; - } - /* * map the framebuffer */