hwc/fb/overlay: wait for fbpost and pan display
Draw sequence in hwc_set --eglSwapBuffers --wait for fb_post. Its ok to draw to External only at this point. --draw to external | Parallel with PAN --commit to external | Parallel with PAN --wait for pan (happening in fb_post) to finish. Call MSMFB_OVERLAY_SET ioctl only when params change. These thing together ensure a correct sequence and should fix tearing and stuttering, the latter assuming there are no other display pipeline delays. Acked-by: Arun Kumar K.R <akumarkr@codeaurora.org> Change-Id: Ibb0ad8485fa6b30dc6ac07ae8b25a760941c08ce
This commit is contained in:
committed by
Iliyan Malchev
parent
94822ee87c
commit
fc2acbe754
@@ -54,6 +54,9 @@ struct private_module_t {
|
||||
pthread_mutex_t fbPostLock;
|
||||
//Condition to inform HWC that fb_post called
|
||||
pthread_cond_t fbPostCond;
|
||||
bool fbPanDone;
|
||||
pthread_mutex_t fbPanLock;
|
||||
pthread_cond_t fbPanCond;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -136,6 +136,13 @@ static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
|
||||
genlock_unlock_buffer(hnd);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
//Signals the composition thread to unblock and loop over if necessary
|
||||
pthread_mutex_lock(&m->fbPanLock);
|
||||
m->fbPanDone = true;
|
||||
pthread_cond_signal(&m->fbPanCond);
|
||||
pthread_mutex_unlock(&m->fbPanLock);
|
||||
|
||||
CALC_FPS();
|
||||
m->currentBuffer = hnd;
|
||||
}
|
||||
@@ -365,6 +372,9 @@ int mapFrameBufferLocked(struct private_module_t* module)
|
||||
module->fbPostDone = false;
|
||||
pthread_mutex_init(&(module->fbPostLock), NULL);
|
||||
pthread_cond_init(&(module->fbPostCond), NULL);
|
||||
module->fbPanDone = false;
|
||||
pthread_mutex_init(&(module->fbPanLock), NULL);
|
||||
pthread_cond_init(&(module->fbPanCond), NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,9 +193,14 @@ static int hwc_set(hwc_composer_device_1 *dev,
|
||||
MDPComp::draw(ctx, list);
|
||||
EGLBoolean success = eglSwapBuffers((EGLDisplay)list->dpy,
|
||||
(EGLSurface)list->sur);
|
||||
wait4fbPost(ctx);
|
||||
//Can draw to HDMI only when fb_post is reached
|
||||
UIMirrorOverlay::draw(ctx);
|
||||
//HDMI commit and primary commit (PAN) happening in parallel
|
||||
if(ctx->mExtDisplay->getExternalDisplay())
|
||||
ctx->mExtDisplay->commit();
|
||||
//Virtual barrier for threads to finish
|
||||
wait4Pan(ctx);
|
||||
} else {
|
||||
ctx->mOverlay->setState(ovutils::OV_CLOSED);
|
||||
ctx->qbuf->unlockAll();
|
||||
|
||||
@@ -154,12 +154,6 @@ bool UIMirrorOverlay::draw(hwc_context_t *ctx)
|
||||
if(fbDev) {
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
fbDev->common.module);
|
||||
//wait for the fb_post to be called
|
||||
pthread_mutex_lock(&m->fbPostLock);
|
||||
while(m->fbPostDone == false) {
|
||||
pthread_cond_wait(&(m->fbPostCond), &(m->fbPostLock));
|
||||
}
|
||||
pthread_mutex_unlock(&m->fbPostLock);
|
||||
switch (state) {
|
||||
case ovutils::OV_UI_MIRROR:
|
||||
if (!ov.queueBuffer(m->framebuffer->fd, m->currentOffset,
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <overlay.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <gralloc_priv.h>
|
||||
#include <fb_priv.h>
|
||||
#include "hwc_utils.h"
|
||||
#include "mdp_version.h"
|
||||
#include "hwc_video.h"
|
||||
@@ -205,4 +208,33 @@ void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
|
||||
}
|
||||
}
|
||||
|
||||
void wait4fbPost(hwc_context_t* ctx) {
|
||||
framebuffer_device_t *fbDev = ctx->mFbDev;
|
||||
if(fbDev) {
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
fbDev->common.module);
|
||||
//wait for the fb_post to be called
|
||||
pthread_mutex_lock(&m->fbPostLock);
|
||||
while(m->fbPostDone == false) {
|
||||
pthread_cond_wait(&(m->fbPostCond), &(m->fbPostLock));
|
||||
}
|
||||
m->fbPostDone = false;
|
||||
pthread_mutex_unlock(&m->fbPostLock);
|
||||
}
|
||||
}
|
||||
|
||||
void wait4Pan(hwc_context_t* ctx) {
|
||||
framebuffer_device_t *fbDev = ctx->mFbDev;
|
||||
if(fbDev) {
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
fbDev->common.module);
|
||||
//wait for the fb_post's PAN to finish
|
||||
pthread_mutex_lock(&m->fbPanLock);
|
||||
while(m->fbPanDone == false) {
|
||||
pthread_cond_wait(&(m->fbPanCond), &(m->fbPanLock));
|
||||
}
|
||||
m->fbPanDone = false;
|
||||
pthread_mutex_unlock(&m->fbPanLock);
|
||||
}
|
||||
}
|
||||
};//namespace
|
||||
|
||||
@@ -77,6 +77,12 @@ void closeContext(hwc_context_t *ctx);
|
||||
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
|
||||
const int fbWidth, const int fbHeight);
|
||||
|
||||
// Waits for the fb_post to be called
|
||||
void wait4fbPost(hwc_context_t* ctx);
|
||||
|
||||
// Waits for the fb_post to finish PAN (primary commit)
|
||||
void wait4Pan(hwc_context_t* ctx);
|
||||
|
||||
// Inline utility functions
|
||||
static inline bool isSkipLayer(const hwc_layer_1_t* l) {
|
||||
return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
|
||||
|
||||
@@ -131,6 +131,7 @@ void MdpCtrl::doTransform() {
|
||||
bool MdpCtrl::set() {
|
||||
//deferred calcs, so APIs could be called in any order.
|
||||
doTransform();
|
||||
if(this->ovChanged()) {
|
||||
if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
|
||||
ALOGE("MdpCtrl failed to setOverlay, restoring last known "
|
||||
"good ov info");
|
||||
@@ -140,6 +141,7 @@ bool MdpCtrl::set() {
|
||||
return false;
|
||||
}
|
||||
this->save();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user