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:
		
				
					committed by
					
						 andrew.boren
						andrew.boren
					
				
			
			
				
	
			
			
			
						parent
						
							272e6ecb11
						
					
				
				
					commit
					02cb316eef
				
			| @@ -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) | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user