hwcomposer: Add workaround for cropped layers during bypass

* Some hardware cannot handle cropping during bypass, or reports
   invalid rects during orientation change. If the invalid rect is
   cropped, MDP gets into a weird broken state where layers turn
   transparent, display blinks, etc.
 * Also use the VG pipe for 2 layers instead of just 1 in this case, it
   eliminates flicker when unlocking the device.

Change-Id: Ia5cb1a368bcc8949ba224a8510f577450449f22e
This commit is contained in:
Steve Kondik 2012-05-25 13:26:43 -07:00 committed by andrew.boren
parent 272e6ecb11
commit 02cb316eef
2 changed files with 45 additions and 9 deletions

View File

@ -38,5 +38,8 @@ ifeq ($(TARGET_USES_POST_PROCESSING),true)
LOCAL_CFLAGS += -DUSES_POST_PROCESSING
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/pp/inc
endif
ifeq ($(TARGET_NO_BYPASS_CROPPING),true)
LOCAL_CFLAGS += -DNO_BYPASS_CROPPING
endif
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)

View File

@ -165,6 +165,15 @@ static inline int min(const int& a, const int& b) {
static inline int max(const int& a, const int& b) {
return (a > b) ? a : b;
}
inline void getLayerResolution(const hwc_layer_t* layer, int& width, int& height)
{
hwc_rect_t displayFrame = layer->displayFrame;
width = displayFrame.right - displayFrame.left;
height = displayFrame.bottom - displayFrame.top;
}
#ifdef COMPOSITION_BYPASS
static void timeout_handler(void *udata) {
LOGD("Comp bypass timeout_handler...");
@ -381,7 +390,12 @@ static int prepareBypass(hwc_context_t *ctx, hwc_layer_t *layer,
int fbnum = 0;
int orientation = layer->transform;
const bool useVGPipe = (nPipeIndex != (MAX_BYPASS_LAYERS-1));
const bool useVGPipe =
#ifdef NO_BYPASS_CROPPING
(nPipeIndex != (MAX_BYPASS_LAYERS - 2));
#else
(nPipeIndex != (MAX_BYPASS_LAYERS - 1));
#endif
//only last layer should wait for vsync
const bool waitForVsync = vsync_wait;
const bool isFg = isFG;
@ -407,6 +421,23 @@ static int prepareBypass(hwc_context_t *ctx, hwc_layer_t *layer,
return 0;
}
#ifdef NO_BYPASS_CROPPING
inline bool isLayerCropped(const hwc_layer_t* layer, int hw_w, int hw_h) {
int dst_w, dst_h;
getLayerResolution(layer, dst_w, dst_h);
hwc_rect_t sourceCrop = layer->sourceCrop;
const int src_w = sourceCrop.right - sourceCrop.left;
const int src_h = sourceCrop.bottom - sourceCrop.top;
hwc_rect_t dst = layer->displayFrame;
return dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h ||
src_w > dst_w || src_h > dst_h;
}
#endif
/*
* Checks if doing comp. bypass is possible.
* It is possible if
@ -450,6 +481,11 @@ inline static bool isBypassDoable(hwc_composer_device_t *dev, const int yuvCount
return false;
}
#ifdef NO_BYPASS_CROPPING
int hw_w = hwcModule->fbDevice->width;
int hw_h = hwcModule->fbDevice->height;
#endif
//Bypass is not efficient if rotation or asynchronous mode is needed.
for(int i = 0; i < list->numHwLayers; ++i) {
if(list->hwLayers[i].transform) {
@ -459,6 +495,11 @@ inline static bool isBypassDoable(hwc_composer_device_t *dev, const int yuvCount
if (ctx->swapInterval > 0)
return false;
}
#ifdef NO_BYPASS_CROPPING
if (isLayerCropped(&(list->hwLayers[i]), hw_w, hw_h)) {
return false;
}
#endif
}
return (yuvCount == 0) && (ctx->hwcOverlayStatus == HWC_OVERLAY_CLOSED)
@ -806,14 +847,6 @@ bool canSkipComposition(hwc_context_t* ctx, int yuvBufferCount, int currentLayer
return false;
}
inline void getLayerResolution(const hwc_layer_t* layer, int& width, int& height)
{
hwc_rect_t displayFrame = layer->displayFrame;
width = displayFrame.right - displayFrame.left;
height = displayFrame.bottom - displayFrame.top;
}
static bool canUseCopybit(const framebuffer_device_t* fbDev, const hwc_layer_list_t* list) {
if(!fbDev) {