如何使用跳表法取代switch...case

    跳表法要实现起来很简单,定义一个函数指针,有多少个case我们就定义一个多大的函数指针数组就好了,这里我把自己在实际用用到的一个案例拿出来说一下,这个是根据片源分辨率和屏幕参数然后给底层设置比例模式的一个算法,我们可以先看看原始的代码.

#define LOG_NDEBUG 0
#define LOG_TAG "HWC_WIDEMODE"
#include <utils/Log.h>

#include <widemode.h>

int32_t rtk_zoom_get_output_window(
    PANEL_TYPE panelType,
    EN_WIDE_MODE wideMode,
    SrcInputRegion srcInputRegion,
    ZoomOutputRegion *pZoomOutputRegion)
{
    if ((pZoomOutputRegion == NULL) || (wideMode > E_AR_LETTERBOX_14_9)) {
        ALOGE("%s failed for bad param:panelType = %d, wideMode = %d\n", __FUNCTION__, panelType, wideMode);
        return -1;
    }

    ALOGI("%s PanelType = %d,WideMode = %d\n",__FUNCTION__, panelType, wideMode);

    switch (wideMode) {
        case E_AR_4x3://E_AR_4x3:
        case E_AR_PILLARBOX:
        {
            if (PANEL_1920_1080 == panelType) {
                //1920x1080
                pZoomOutputRegion->un16_hposition = 240;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1440;
                pZoomOutputRegion->un16_vsize = 1080;
            }
            else if (PANEL_1366_768 == panelType) {
                //1366x768
                pZoomOutputRegion->un16_hposition = 170;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1024;
                pZoomOutputRegion->un16_vsize = 768;
            }
            else {
                //1920x1080 and 3840*2160
                pZoomOutputRegion->un16_hposition = 240;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1440;
                pZoomOutputRegion->un16_vsize = 1080;
            }
        } break;

        case E_AR_14x9://E_AR_14x9:
        case E_AR_14x9_ZOOM://E_AR_14x9:
        {
            if (PANEL_1920_1080 == panelType) {
                //1920x1080
                pZoomOutputRegion->un16_hposition = 120;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1680;
                pZoomOutputRegion->un16_vsize = 1080;
            }
            else if (PANEL_1366_768 == panelType) {
                //1366x768
                pZoomOutputRegion->un16_hposition = 88;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1190;
                pZoomOutputRegion->un16_vsize = 765;
            }
            else {
                //1920x1080
                pZoomOutputRegion->un16_hposition = 120;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1680;
                pZoomOutputRegion->un16_vsize = 1080;
            }
        } break;

        case E_AR_AUTO:
        {
            if (PANEL_1920_1080 == panelType) {
                //1920x1080
                if(srcInputRegion.un32_width== 0 || srcInputRegion.un32_height == 0) {
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = 1920;//1920;
                    pZoomOutputRegion->un16_vsize = 1080;//1080;
                    return 0;
                }
                float scale_video = (float)(srcInputRegion.un32_width)/(float)(srcInputRegion.un32_height);
                float scale = 0;
                if (scale_video >= 1920.0/1080.0) {
                    scale = 1920.0/srcInputRegion.un32_width;
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = (1080-(uint16_t)(srcInputRegion.un32_height*scale))/2;
                    pZoomOutputRegion->un16_hsize = 1920;
                    pZoomOutputRegion->un16_vsize = (uint16_t)(srcInputRegion.un32_height*scale);
                }
                else {
                    scale = 1080.0/srcInputRegion.un32_height;
                    pZoomOutputRegion->un16_hposition = (1920-(uint16_t)(srcInputRegion.un32_width*scale))/2;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = (uint16_t)(srcInputRegion.un32_width*scale);
                    pZoomOutputRegion->un16_vsize = 1080;
                }
            }
            else if (PANEL_1366_768 == panelType) {
                //1366x768
                if (srcInputRegion.un32_width== 0 || srcInputRegion.un32_height == 0) {
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = 1366;//1920;
                    pZoomOutputRegion->un16_vsize = 768;//1080;
                    return 0;
                }
                float scale_video = (float)(srcInputRegion.un32_width)/(float)(srcInputRegion.un32_height);
                float scale = 0;
                if (scale_video >= 1366.0/768.0) {
                    scale = 1366.0/srcInputRegion.un32_width;
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = (768-(uint16_t)(srcInputRegion.un32_height*scale))/2;
                    pZoomOutputRegion->un16_hsize = 1366;
                    pZoomOutputRegion->un16_vsize = (uint16_t)(srcInputRegion.un32_height*scale);
                }
                else {
                    scale = 768.0/srcInputRegion.un32_height;
                    pZoomOutputRegion->un16_hposition = (1366-(uint16_t)(srcInputRegion.un32_width*scale))/2;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = (uint16_t)(srcInputRegion.un32_width*scale);
                    pZoomOutputRegion->un16_vsize = 768;
                }
            }
			else if (PANEL_3840_2160 == panelType) {
				//3840*2160
				if (srcInputRegion.un32_width >= 3840 || srcInputRegion.un32_height >= 2160){
					pZoomOutputRegion->un16_hposition = 0;
					pZoomOutputRegion->un16_vposition = 0;
					pZoomOutputRegion->un16_hsize = 1920;//3840/2;
					pZoomOutputRegion->un16_vsize = 1080;//2160/2;		
				}
				else{
					if (srcInputRegion.un32_width== 0 || srcInputRegion.un32_height == 0) {
						pZoomOutputRegion->un16_hposition = 0;
						pZoomOutputRegion->un16_vposition = 0;
						pZoomOutputRegion->un16_hsize = 1920;//3840/2;
						pZoomOutputRegion->un16_vsize = 1080;//2160/2;
						return 0;
					}
					float scale_video = (float)(srcInputRegion.un32_width)/(float)(srcInputRegion.un32_height);
					float scale = 0;
					if (scale_video >= 3840.0/2160.0) {
						scale = 3840.0/srcInputRegion.un32_width;
						pZoomOutputRegion->un16_hposition = 0;
						pZoomOutputRegion->un16_vposition = (2160-(uint16_t)(srcInputRegion.un32_height*scale))/4;
						pZoomOutputRegion->un16_hsize = 1920;
						pZoomOutputRegion->un16_vsize = (uint16_t)(srcInputRegion.un32_height*scale)/2;
					}
					else {
						scale = 2160.0/srcInputRegion.un32_height;
						pZoomOutputRegion->un16_hposition = (3840-(uint16_t)(srcInputRegion.un32_width*scale))/4;
						pZoomOutputRegion->un16_vposition = 0;
						pZoomOutputRegion->un16_hsize = (uint16_t)(srcInputRegion.un32_width*scale)/2;
						pZoomOutputRegion->un16_vsize = 1080;
					}
				}
			}	
            else {
                //1920x1080
                if (srcInputRegion.un32_width == 0 || srcInputRegion.un32_height == 0) {
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = 1920;//1920;
                    pZoomOutputRegion->un16_vsize = 1080;//1080;
                    return 0;
                }
                float scale_video = (float)(srcInputRegion.un32_width)/(float)(srcInputRegion.un32_height);
                float scale = 0;
                if (scale_video >= 1920.0/1080.0) {
                    scale = 1920.0/srcInputRegion.un32_width;
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = (1080-(uint16_t)(srcInputRegion.un32_height*scale))/2;
                    pZoomOutputRegion->un16_hsize = 1920;
                    pZoomOutputRegion->un16_vsize = (uint16_t)(srcInputRegion.un32_height*scale);
                }
                else {
                    scale = 1080.0/srcInputRegion.un32_height;
                    pZoomOutputRegion->un16_hposition = (1920-(uint16_t)(srcInputRegion.un32_width*scale))/2;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = (uint16_t)(srcInputRegion.un32_width*scale);
                    pZoomOutputRegion->un16_vsize = 1080;
                }
            }
        } break;
        case E_AR_DOTBYDOt:
        {
            if (PANEL_1920_1080 == panelType) {
                //1920x1080
                if (srcInputRegion.un32_width== 0 || srcInputRegion.un32_height == 0) {
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = 1920;//1920;
                    pZoomOutputRegion->un16_vsize = 1080;//1080;
                    return 0;
                }
                if (srcInputRegion.un32_width > 1920) {
                    if(srcInputRegion.un32_height > 1080) {
                        pZoomOutputRegion->un16_hposition = 0;
                        pZoomOutputRegion->un16_vposition = 0;
                        pZoomOutputRegion->un16_hsize = 1920;//1920;
                        pZoomOutputRegion->un16_vsize = 1080;//1080;
                    }
                    else {
                        pZoomOutputRegion->un16_hposition = 0;
                        pZoomOutputRegion->un16_vposition = (1080-(uint16_t)srcInputRegion.un32_height)/2;
                        pZoomOutputRegion->un16_hsize = 1920;//1920;
                        pZoomOutputRegion->un16_vsize = srcInputRegion.un32_height;//1080;
                    }
                }
                else {
                    if (srcInputRegion.un32_height > 1080) {
                        pZoomOutputRegion->un16_hposition = (1920-(uint16_t)srcInputRegion.un32_width)/2;
                        pZoomOutputRegion->un16_vposition = 0;
                        pZoomOutputRegion->un16_hsize = srcInputRegion.un32_width;//1920;
                        pZoomOutputRegion->un16_vsize = 1080;//1080;
                    }
                    else {
                        pZoomOutputRegion->un16_hposition = (1920-(uint16_t)srcInputRegion.un32_width)/2;
                        pZoomOutputRegion->un16_vposition = (1080-(uint16_t)srcInputRegion.un32_height)/2;
                        pZoomOutputRegion->un16_hsize = srcInputRegion.un32_width;//1920;
                        pZoomOutputRegion->un16_vsize = srcInputRegion.un32_height;//1080;
                        //fpi_info("pZoomOutputRegion->un16_hposition = %d, pZoomOutputRegion->un16_vposition = %d, pZoomOutputRegion->un16_hsize = %d, pZoomOutputRegion->un16_vsize = %d\n",pZoomOutputRegion->un16_hposition,pZoomOutputRegion->un16_vposition,pZoomOutputRegion->un16_hsize,pZoomOutputRegion->un16_vsize);
                    }
                }
            }
            else if (PANEL_1366_768 == panelType) {
                //1366x768
                if (srcInputRegion.un32_width== 0 || srcInputRegion.un32_height == 0) {
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = 1366;
                    pZoomOutputRegion->un16_vsize = 768;
                    return 0;
                }
                if (srcInputRegion.un32_width> 1366) {
                    if (srcInputRegion.un32_height>768) {
                        pZoomOutputRegion->un16_hposition = 0;
                        pZoomOutputRegion->un16_vposition = 0;
                        pZoomOutputRegion->un16_hsize = 1366;
                        pZoomOutputRegion->un16_vsize = 768;
                    }
                    else {
                        pZoomOutputRegion->un16_hposition = 0;
                        pZoomOutputRegion->un16_vposition = (768-(uint16_t)srcInputRegion.un32_height)/2;
                        pZoomOutputRegion->un16_hsize = 1366;
                        pZoomOutputRegion->un16_vsize = srcInputRegion.un32_height;
                    }
                }
                else {
                    if (srcInputRegion.un32_height>768) {
                        pZoomOutputRegion->un16_hposition = (1366-(uint16_t)srcInputRegion.un32_width)/2;
                        pZoomOutputRegion->un16_vposition = 0;
                        pZoomOutputRegion->un16_hsize = srcInputRegion.un32_width;
                        pZoomOutputRegion->un16_vsize = 768;
                    }
                    else {
                        pZoomOutputRegion->un16_hposition = (1366-(uint16_t)srcInputRegion.un32_width)/2;
                        pZoomOutputRegion->un16_vposition = (768-(uint16_t)srcInputRegion.un32_height)/2;
                        pZoomOutputRegion->un16_hsize = srcInputRegion.un32_width;
                        pZoomOutputRegion->un16_vsize = srcInputRegion.un32_height ;
                    }
                }
            }
			else if (PANEL_3840_2160 == panelType) {
                //1920x1080
                if (srcInputRegion.un32_width== 0 || srcInputRegion.un32_height == 0) {
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = 1920;//1920;
                    pZoomOutputRegion->un16_vsize = 1080;//1080;
                    return 0;
                }
                if (srcInputRegion.un32_width> 3840) {
                    if (srcInputRegion.un32_height>2160) {
                        pZoomOutputRegion->un16_hposition = 0;
                        pZoomOutputRegion->un16_vposition = 0;
                        pZoomOutputRegion->un16_hsize = 1920;//1920;
                        pZoomOutputRegion->un16_vsize = 1080;//1080;
                    }
                    else {
                        pZoomOutputRegion->un16_hposition = 0;
                        pZoomOutputRegion->un16_vposition = (2160-(uint16_t)srcInputRegion.un32_width)/4;
                        pZoomOutputRegion->un16_hsize = 1920;//3840/2
                        pZoomOutputRegion->un16_vsize = srcInputRegion.un32_width/2;//1080;
                    }
                }
                else {
                    if (srcInputRegion.un32_height>2160) {
                        pZoomOutputRegion->un16_hposition = (3840-(uint16_t)srcInputRegion.un32_height)/4;
                        pZoomOutputRegion->un16_vposition = 0;
                        pZoomOutputRegion->un16_hsize = srcInputRegion.un32_height/2;//1920;
                        pZoomOutputRegion->un16_vsize = 1080;//1080;
                    } else {
                        pZoomOutputRegion->un16_hposition = (3840-(uint16_t)srcInputRegion.un32_height)/4;
                        pZoomOutputRegion->un16_vposition = (2160-(uint16_t)srcInputRegion.un32_width)/4;
                        pZoomOutputRegion->un16_hsize = srcInputRegion.un32_height/2;//1920;
                        pZoomOutputRegion->un16_vsize = srcInputRegion.un32_width/2;//1080;
                    }
                }
            }			
            else {
                //1920x1080
                if (srcInputRegion.un32_width== 0 || srcInputRegion.un32_height == 0) {
                    pZoomOutputRegion->un16_hposition = 0;
                    pZoomOutputRegion->un16_vposition = 0;
                    pZoomOutputRegion->un16_hsize = 1920;//1920;
                    pZoomOutputRegion->un16_vsize = 1080;//1080;
                    return 0;
                }
                if (srcInputRegion.un32_width> 1920) {
                    if (srcInputRegion.un32_height>1080) {
                        pZoomOutputRegion->un16_hposition = 0;
                        pZoomOutputRegion->un16_vposition = 0;
                        pZoomOutputRegion->un16_hsize = 1920;//1920;
                        pZoomOutputRegion->un16_vsize = 1080;//1080;
                    }
                    else {
                        pZoomOutputRegion->un16_hposition = 0;
                        pZoomOutputRegion->un16_vposition = (1080-(uint16_t)srcInputRegion.un32_width)/2;
                        pZoomOutputRegion->un16_hsize = 1920;//1920;
                        pZoomOutputRegion->un16_vsize = srcInputRegion.un32_width;//1080;
                    }
                }
                else {
                    if (srcInputRegion.un32_height>1080) {
                        pZoomOutputRegion->un16_hposition = (1920-(uint16_t)srcInputRegion.un32_height)/2;
                        pZoomOutputRegion->un16_vposition = 0;
                        pZoomOutputRegion->un16_hsize = srcInputRegion.un32_height;//1920;
                        pZoomOutputRegion->un16_vsize = 1080;//1080;
                    } else {
                        pZoomOutputRegion->un16_hposition = (1920-(uint16_t)srcInputRegion.un32_height)/2;
                        pZoomOutputRegion->un16_vposition = (1080-(uint16_t)srcInputRegion.un32_width)/2;
                        pZoomOutputRegion->un16_hsize = srcInputRegion.un32_height;//1920;
                        pZoomOutputRegion->un16_vsize = srcInputRegion.un32_width;//1080;
                    }
                }
            }
        } break;

		case E_AR_LETTERBOX_14_9://for mheg 14:9 letter box
		//case E_AR_CENTER_CUT_OUT:
		{
            if (PANEL_1920_1080 == panelType) {
                //1920x1080
                pZoomOutputRegion->un16_hposition = 120;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1680;
                pZoomOutputRegion->un16_vsize = 1080;
            }
            else if (PANEL_1366_768 == panelType) {
                //1366x768
                pZoomOutputRegion->un16_hposition = 88;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1190;
                pZoomOutputRegion->un16_vsize = 765;
            }
            else {
                //1920x1080
                pZoomOutputRegion->un16_hposition = 120;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1680;
                pZoomOutputRegion->un16_vsize = 1080;
            }
		} break;

        default:
        {
            if (PANEL_1920_1080 == panelType) {
                //1920x1080
                pZoomOutputRegion->un16_hposition = 0;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1920;//1920;
                pZoomOutputRegion->un16_vsize = 1080;//1080;
            }
            else if (PANEL_1366_768 == panelType) {
                //1366x768
                pZoomOutputRegion->un16_hposition = 0;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1366;
                pZoomOutputRegion->un16_vsize = 768;
            }
            else {
                //1920x1080
                pZoomOutputRegion->un16_hposition = 0;
                pZoomOutputRegion->un16_vposition = 0;
                pZoomOutputRegion->un16_hsize = 1920;
                pZoomOutputRegion->un16_vsize = 1080;
            }
        } break;
    }
    return 0;
}

可以看到原始的代码使用了一个很长的switch...case和非常多的if...else,实际上这样做是非常影响代码美观的,总之我不怎么能看的下去,所以首先是要想办法去把switch...case取代掉,方法非常简单,使用一个函数指针,然后创建一个函数指针数组.

typedef int32_t (*DataRetriver)(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype);

DataRetriver dataRetriver[24] = {
    &getOutputRegion_E_AR_DEFAULT,          //Default
    &getOutputRegion_E_AR_16x9,             //16x9
    &getOutputRegion_E_AR_4x3,              //4x3
    &getOutputRegion_E_AR_14x9,             //14x9
    &getOutputRegion_E_AR_CINERAMA,         //Cinerama
    &getOutputRegion_E_AR_16x9_ZOOM,        //16X9 zoom
    &getOutputRegion_E_AR_16x9_ZOOM_UP,     //16X9 zoom up
    &getOutputRegion_E_AR_14x9_ZOOM,        //14X9 zoom
    &getOutputRegion_E_AR_STETCH_ZOOM,      //STETCH ZOOM
    &getOutputRegion_E_AR_WIDE_ZOOM,        //WIDE ZOOM
    &getOutputRegion_E_AR_ZOOM2,            //10 Zoom 2
    &getOutputRegion_E_AR_WIDE_ZOOM2,       //WIDE ZOOM2
    &getOutputRegion_E_AR_AUTO,             //Auto
    &getOutputRegion_E_AR_PANORAMA,         //Panorama
    &getOutputRegion_E_AR_JUSTSCAN,         //Just Scan
    &getOutputRegion_E_AR_ZOOM1,            //Zoom 1
    &getOutputRegion_E_AR_DOTBYDOt,         //point to point
    &getOutputRegion_E_AR_SUBTITLE,         //Subtitle
    &getOutputRegion_E_AR_MOVIE,            //movie
    &getOutputRegion_E_AR_PERSONAL,         //Personal
    &getOutputRegion_E_AR_LETTERBOX,        //DEC_FC_LETTERBOX
    &getOutputRegion_E_AR_CENTER_CUT_OUT,   //CENTER_CUT_OUT
    &getOutputRegion_E_AR_PILLARBOX,        //PILLARBOX
    &getOutputRegion_E_AR_LETTERBOX_14_9   //LETTERBOX_14_9
};

可以看到我的case 是有24种情况,我们根据switch的widemode的情况  然后去选择对应的函数指针所指向的函数

    OutType outtype = setOutType(wideMode);
    DataRetriver pRetriver = dataRetriver[wideMode];
    if (pRetriver != nullptr) {
        pRetriver(panelType, srcInputRegion, pZoomOutputRegion, outtype);
    }

这个地方其实是有一个问题,就是我们其实是不会运用到所有的case类型,但是如果我们使用了这种方式,就必须要定义所有的类型,那如果是defualt的时候我们应该怎么办呢,我在这里是采取了一个取巧的办法.

#define TYPE_ONE(NAME)\
    int32_t getOutputRegion_##NAME(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)\
    {\
        getOutInfo(outtype, panelType, pZoomOutputRegion); \
        if (srcInputRegion.un32_height == 0)\
            return 0; \
        return 0; \
    }\

TYPE_ONE(E_AR_4x3)
TYPE_ONE(E_AR_PILLARBOX)

#undef TYPE_ONE

#define TYPE_TWO(NAME)\
    int32_t getOutputRegion_##NAME(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)\
    {\
        getOutInfo(outtype, panelType, pZoomOutputRegion);\
        if (srcInputRegion.un32_height == 0)\
            return 0;\
        return 0;\
    }\

TYPE_TWO(E_AR_14x9)
TYPE_TWO(E_AR_14x9_ZOOM)

#undef TYPE_TWO

#define TYPE_DEFAULT(NAME)\
    int32_t getOutputRegion_##NAME(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)\
    {\
        getOutInfo(outtype, panelType, pZoomOutputRegion);\
        if (srcInputRegion.un32_height == 0)\
            return 0;\
        return 0;\
    }\

TYPE_DEFAULT(E_AR_DEFAULT)
TYPE_DEFAULT(E_AR_16x9)
TYPE_DEFAULT(E_AR_CINERAMA)
TYPE_DEFAULT(E_AR_16x9_ZOOM)
TYPE_DEFAULT(E_AR_16x9_ZOOM_UP)
TYPE_DEFAULT(E_AR_STETCH_ZOOM)
TYPE_DEFAULT(E_AR_WIDE_ZOOM)
TYPE_DEFAULT(E_AR_ZOOM2)
TYPE_DEFAULT(E_AR_WIDE_ZOOM2)
TYPE_DEFAULT(E_AR_PANORAMA)
TYPE_DEFAULT(E_AR_JUSTSCAN)
TYPE_DEFAULT(E_AR_ZOOM1)
TYPE_DEFAULT(E_AR_SUBTITLE)
TYPE_DEFAULT(E_AR_MOVIE)
TYPE_DEFAULT(E_AR_PERSONAL)
TYPE_DEFAULT(E_AR_LETTERBOX)
TYPE_DEFAULT(E_AR_CENTER_CUT_OUT)

#undef TYPE_DEFAULT

这样的话 我们就可以通过很少的代码然后定义全部的函数了(这个地方是有重复的地方,主要是为了方便之后算法拓展,我们可以调换修改),然后if...else的赋值部分 我们可以通过创建一个结构体数组,然后去查询,就可以避免之前让人讨厌的赋值工作了,如

static OutType setOutType(const EN_WIDE_MODE wideMode)
{
    if (wideMode == E_AR_14x9 || wideMode == E_AR_14x9_ZOOM) {
        return Out_two;
    }
    else if (wideMode == E_AR_4x3 || wideMode == E_AR_PILLARBOX) {
        return Out_one;
    }
    else if (E_AR_DOTBYDOt) {
        return Out_three;
    }
    else if (E_AR_LETTERBOX_14_9) {
        return Out_four;
    }
    else if (E_AR_AUTO) {
        return Out_five;
    }
    else {
        return Out_default;
    }
}

static const struct {
    OutType    outtype;
    PANEL_TYPE paneltype;
    uint16_t   un16_hposition;
    uint16_t   un16_vposition;
    uint16_t   un16_hsize;
    uint16_t   un16_vsize;
} OUT_TYPE_MAP[] = {
    {Out_default, PANEL_1920_1080, 0, 0, 1920, 1080},
    {Out_default, PANEL_1366_768, 0, 0, 1366, 768},
    {Out_default, PANEL_3840_2160, 0, 0, 1920, 1080},
    {Out_default, PANEL_OTHER, 240, 0, 1440, 1080},
    {Out_one, PANEL_1920_1080, 170, 0, 1024, 768},
    {Out_one, PANEL_1366_768, 240, 0, 1440, 1080},
    {Out_one, PANEL_3840_2160, 240, 0, 1440, 1080},
    {Out_one, PANEL_OTHER, 120, 0, 1680, 1080},
    {Out_two, PANEL_1920_1080, 0, 0, 1920, 1080},
    {Out_two, PANEL_1366_768, 120, 0, 1680, 1080},
    {Out_two, PANEL_3840_2160, 88, 0, 1190, 765},
    {Out_two, PANEL_OTHER, 120, 0, 1680, 1080},
    {Out_three, PANEL_1920_1080, 0, 0, 1920, 1080},
    {Out_three, PANEL_1366_768, 0, 0, 1366, 768},
    {Out_three, PANEL_3840_2160, 0, 0, 1920, 1080},
    {Out_three, PANEL_OTHER, 0, 0, 1920, 1080},
    {Out_four, PANEL_1920_1080, 120, 0, 1680, 1080},
    {Out_four, PANEL_1366_768, 88, 0, 1190, 765},
    {Out_four, PANEL_3840_2160, 120, 0, 1680, 1080},
    {Out_four, PANEL_OTHER, 120, 0, 1680, 1080},
    {Out_five, PANEL_1920_1080, 0, 0, 1920, 1080},
    {Out_five, PANEL_1366_768, 0, 0, 1366, 768},
    {Out_five, PANEL_3840_2160, 0, 0, 1920, 1080},
    {Out_five, PANEL_OTHER, 0, 0, 1920, 1080},
};

static void getOutInfo(const OutType outtype, const PANEL_TYPE paneltype, ZoomOutputRegion *pZoomOutputRegion)
{
    for (unsigned int i = 0; i < sizeof(OUT_TYPE_MAP) / sizeof(OUT_TYPE_MAP[0]); i++) {
        if (outtype == OUT_TYPE_MAP[i].outtype && paneltype == OUT_TYPE_MAP[i].paneltype) {
            pZoomOutputRegion->un16_hposition = OUT_TYPE_MAP[i].un16_hposition;
            pZoomOutputRegion->un16_vposition = OUT_TYPE_MAP[i].un16_vposition;
            pZoomOutputRegion->un16_hsize = OUT_TYPE_MAP[i].un16_hsize;
            pZoomOutputRegion->un16_vsize = OUT_TYPE_MAP[i].un16_vsize;
            break;
        }
    }
    return ;
}

然后具体到单独的地方,我们可以单独去写函数逻辑

int32_t getOutputRegion_E_AR_DOTBYDOt(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)
{
    getOutInfo(outtype, panelType, pZoomOutputRegion);
    int zl = 1;
    if (PANEL_3840_2160 == panelType) {
        zl = 2;
    }

    if (srcInputRegion.un32_width == 0 || srcInputRegion.un32_height == 0) {
        return 0;
    }
    if ((uint16_t)srcInputRegion.un32_width > (pZoomOutputRegion->un16_hsize * zl)) {
        if ((uint16_t)srcInputRegion.un32_height > (pZoomOutputRegion->un16_vsize * zl)) {
            return 0;
        }
        else {
            pZoomOutputRegion->un16_vposition = ((pZoomOutputRegion->un16_vsize * zl) - (uint16_t)srcInputRegion.un32_height) / (zl * 2);
            pZoomOutputRegion->un16_vsize = srcInputRegion.un32_height / zl;//1080;
        }
    }
    else {
        if ((uint16_t)srcInputRegion.un32_height > (pZoomOutputRegion->un16_vsize * zl)) {
            pZoomOutputRegion->un16_hposition = ((pZoomOutputRegion->un16_hsize * zl) - (uint16_t)srcInputRegion.un32_width) / (zl * 2);
            pZoomOutputRegion->un16_hsize = srcInputRegion.un32_width / zl;//1920;
        }
        else {
            pZoomOutputRegion->un16_hposition = ((pZoomOutputRegion->un16_hsize * zl) - (uint16_t)srcInputRegion.un32_width) / (zl * 2);
            pZoomOutputRegion->un16_vposition = ((pZoomOutputRegion->un16_vsize * zl) - (uint16_t)srcInputRegion.un32_height) / (zl * 2);
            pZoomOutputRegion->un16_hsize = srcInputRegion.un32_width / zl;//1920;
            pZoomOutputRegion->un16_vsize = srcInputRegion.un32_height / zl; //1080;
            //fpi_info("pZoomOutputRegion->un16_hposition = %d, pZoomOutputRegion->un16_vposition = %d, pZoomOutputRegion->un16_hsize = %d, pZoomOutputRegion->un16_vsize = %d\n",pZoomOutputRegion->un16_hposition,pZoomOutputRegion->un16_vposition,pZoomOutputRegion->un16_hsize,pZoomOutputRegion->un16_vsize);
        }
    }
    return 0;
}

int32_t getOutputRegion_E_AR_LETTERBOX_14_9(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)
{
    getOutInfo(outtype, panelType, pZoomOutputRegion);
    if (srcInputRegion.un32_height == 0) {
        return 0;
    }
    return 0;
}

int32_t getOutputRegion_E_AR_AUTO(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)
{
    getOutInfo(outtype, panelType, pZoomOutputRegion);

    int zl = 1;
    if (PANEL_3840_2160 == panelType) {
        if (srcInputRegion.un32_width >= 3840 || srcInputRegion.un32_height >= 2160) {
            return 0;
        }
        zl = 2;
    }

    if (srcInputRegion.un32_width == 0 || srcInputRegion.un32_height == 0) {
        return 0;
    }
    float scale_video = (float)(srcInputRegion.un32_width) / (float)(srcInputRegion.un32_height);
    float scale = 0;
    if (scale_video >= (float)(pZoomOutputRegion->un16_hsize * zl) / (float)(pZoomOutputRegion->un16_vsize * zl)) {
        scale = (float)(pZoomOutputRegion->un16_hsize * zl) / (float)(srcInputRegion.un32_width);
        pZoomOutputRegion->un16_vposition = ((pZoomOutputRegion->un16_vsize * zl) - (uint16_t)(srcInputRegion.un32_height * scale)) / (zl * 2);
        pZoomOutputRegion->un16_vsize = (uint16_t)(srcInputRegion.un32_height * scale) / zl;
    }
    else {
        scale = (float)(pZoomOutputRegion->un16_vsize * zl) / (float)(srcInputRegion.un32_height);
        pZoomOutputRegion->un16_hposition = ((pZoomOutputRegion->un16_hsize * zl) - (uint16_t)(srcInputRegion.un32_width * scale)) / (zl * 2);
        pZoomOutputRegion->un16_hsize = (uint16_t)(srcInputRegion.un32_width * scale) / zl;
    }

    return 0;
}

这个就是我理解的跳表法了,可以把一些长的 没用的赋值语句和switch...case 都省掉,附上修改完整之后

#define LOG_NDEBUG 0
#define LOG_TAG "HWC_WIDEMODE"
#include <utils/Log.h>

#include <widemode.h>

static const struct {
    OutType    outtype;
    PANEL_TYPE paneltype;
    uint16_t   un16_hposition;
    uint16_t   un16_vposition;
    uint16_t   un16_hsize;
    uint16_t   un16_vsize;
} OUT_TYPE_MAP[] = {
    {Out_default, PANEL_1920_1080, 0, 0, 1920, 1080},
    {Out_default, PANEL_1366_768, 0, 0, 1366, 768},
    {Out_default, PANEL_3840_2160, 0, 0, 1920, 1080},
    {Out_default, PANEL_OTHER, 240, 0, 1440, 1080},
    {Out_one, PANEL_1920_1080, 170, 0, 1024, 768},
    {Out_one, PANEL_1366_768, 240, 0, 1440, 1080},
    {Out_one, PANEL_3840_2160, 240, 0, 1440, 1080},
    {Out_one, PANEL_OTHER, 120, 0, 1680, 1080},
    {Out_two, PANEL_1920_1080, 0, 0, 1920, 1080},
    {Out_two, PANEL_1366_768, 120, 0, 1680, 1080},
    {Out_two, PANEL_3840_2160, 88, 0, 1190, 765},
    {Out_two, PANEL_OTHER, 120, 0, 1680, 1080},
    {Out_three, PANEL_1920_1080, 0, 0, 1920, 1080},
    {Out_three, PANEL_1366_768, 0, 0, 1366, 768},
    {Out_three, PANEL_3840_2160, 0, 0, 1920, 1080},
    {Out_three, PANEL_OTHER, 0, 0, 1920, 1080},
    {Out_four, PANEL_1920_1080, 120, 0, 1680, 1080},
    {Out_four, PANEL_1366_768, 88, 0, 1190, 765},
    {Out_four, PANEL_3840_2160, 120, 0, 1680, 1080},
    {Out_four, PANEL_OTHER, 120, 0, 1680, 1080},
    {Out_five, PANEL_1920_1080, 0, 0, 1920, 1080},
    {Out_five, PANEL_1366_768, 0, 0, 1366, 768},
    {Out_five, PANEL_3840_2160, 0, 0, 1920, 1080},
    {Out_five, PANEL_OTHER, 0, 0, 1920, 1080},
};

static void getOutInfo(const OutType outtype, const PANEL_TYPE paneltype, ZoomOutputRegion *pZoomOutputRegion)
{
    for (unsigned int i = 0; i < sizeof(OUT_TYPE_MAP) / sizeof(OUT_TYPE_MAP[0]); i++) {
        if (outtype == OUT_TYPE_MAP[i].outtype && paneltype == OUT_TYPE_MAP[i].paneltype) {
            pZoomOutputRegion->un16_hposition = OUT_TYPE_MAP[i].un16_hposition;
            pZoomOutputRegion->un16_vposition = OUT_TYPE_MAP[i].un16_vposition;
            pZoomOutputRegion->un16_hsize = OUT_TYPE_MAP[i].un16_hsize;
            pZoomOutputRegion->un16_vsize = OUT_TYPE_MAP[i].un16_vsize;
            break;
        }
    }
    return ;
}

static OutType setOutType(const EN_WIDE_MODE wideMode)
{
    if (wideMode == E_AR_14x9 || wideMode == E_AR_14x9_ZOOM) {
        return Out_two;
    }
    else if (wideMode == E_AR_4x3 || wideMode == E_AR_PILLARBOX) {
        return Out_one;
    }
    else if (E_AR_DOTBYDOt) {
        return Out_three;
    }
    else if (E_AR_LETTERBOX_14_9) {
        return Out_four;
    }
    else if (E_AR_AUTO) {
        return Out_five;
    }
    else {
        return Out_default;
    }
}

int32_t getOutputRegion_E_AR_DOTBYDOt(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)
{
    getOutInfo(outtype, panelType, pZoomOutputRegion);
    int zl = 1;
    if (PANEL_3840_2160 == panelType) {
        zl = 2;
    }

    if (srcInputRegion.un32_width == 0 || srcInputRegion.un32_height == 0) {
        return 0;
    }
    if ((uint16_t)srcInputRegion.un32_width > (pZoomOutputRegion->un16_hsize * zl)) {
        if ((uint16_t)srcInputRegion.un32_height > (pZoomOutputRegion->un16_vsize * zl)) {
            return 0;
        }
        else {
            pZoomOutputRegion->un16_vposition = ((pZoomOutputRegion->un16_vsize * zl) - (uint16_t)srcInputRegion.un32_height) / (zl * 2);
            pZoomOutputRegion->un16_vsize = srcInputRegion.un32_height / zl;//1080;
        }
    }
    else {
        if ((uint16_t)srcInputRegion.un32_height > (pZoomOutputRegion->un16_vsize * zl)) {
            pZoomOutputRegion->un16_hposition = ((pZoomOutputRegion->un16_hsize * zl) - (uint16_t)srcInputRegion.un32_width) / (zl * 2);
            pZoomOutputRegion->un16_hsize = srcInputRegion.un32_width / zl;//1920;
        }
        else {
            pZoomOutputRegion->un16_hposition = ((pZoomOutputRegion->un16_hsize * zl) - (uint16_t)srcInputRegion.un32_width) / (zl * 2);
            pZoomOutputRegion->un16_vposition = ((pZoomOutputRegion->un16_vsize * zl) - (uint16_t)srcInputRegion.un32_height) / (zl * 2);
            pZoomOutputRegion->un16_hsize = srcInputRegion.un32_width / zl;//1920;
            pZoomOutputRegion->un16_vsize = srcInputRegion.un32_height / zl; //1080;
            //fpi_info("pZoomOutputRegion->un16_hposition = %d, pZoomOutputRegion->un16_vposition = %d, pZoomOutputRegion->un16_hsize = %d, pZoomOutputRegion->un16_vsize = %d\n",pZoomOutputRegion->un16_hposition,pZoomOutputRegion->un16_vposition,pZoomOutputRegion->un16_hsize,pZoomOutputRegion->un16_vsize);
        }
    }
    return 0;
}

int32_t getOutputRegion_E_AR_LETTERBOX_14_9(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)
{
    getOutInfo(outtype, panelType, pZoomOutputRegion);
    if (srcInputRegion.un32_height == 0) {
        return 0;
    }
    return 0;
}

int32_t getOutputRegion_E_AR_AUTO(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)
{
    getOutInfo(outtype, panelType, pZoomOutputRegion);

    int zl = 1;
    if (PANEL_3840_2160 == panelType) {
        if (srcInputRegion.un32_width >= 3840 || srcInputRegion.un32_height >= 2160) {
            return 0;
        }
        zl = 2;
    }

    if (srcInputRegion.un32_width == 0 || srcInputRegion.un32_height == 0) {
        return 0;
    }
    float scale_video = (float)(srcInputRegion.un32_width) / (float)(srcInputRegion.un32_height);
    float scale = 0;
    if (scale_video >= (float)(pZoomOutputRegion->un16_hsize * zl) / (float)(pZoomOutputRegion->un16_vsize * zl)) {
        scale = (float)(pZoomOutputRegion->un16_hsize * zl) / (float)(srcInputRegion.un32_width);
        pZoomOutputRegion->un16_vposition = ((pZoomOutputRegion->un16_vsize * zl) - (uint16_t)(srcInputRegion.un32_height * scale)) / (zl * 2);
        pZoomOutputRegion->un16_vsize = (uint16_t)(srcInputRegion.un32_height * scale) / zl;
    }
    else {
        scale = (float)(pZoomOutputRegion->un16_vsize * zl) / (float)(srcInputRegion.un32_height);
        pZoomOutputRegion->un16_hposition = ((pZoomOutputRegion->un16_hsize * zl) - (uint16_t)(srcInputRegion.un32_width * scale)) / (zl * 2);
        pZoomOutputRegion->un16_hsize = (uint16_t)(srcInputRegion.un32_width * scale) / zl;
    }

    return 0;
}

#define TYPE_ONE(NAME)\
    int32_t getOutputRegion_##NAME(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)\
    {\
        getOutInfo(outtype, panelType, pZoomOutputRegion); \
        if (srcInputRegion.un32_height == 0)\
            return 0; \
        return 0; \
    }\

TYPE_ONE(E_AR_4x3)
TYPE_ONE(E_AR_PILLARBOX)

#undef TYPE_ONE

#define TYPE_TWO(NAME)\
    int32_t getOutputRegion_##NAME(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)\
    {\
        getOutInfo(outtype, panelType, pZoomOutputRegion);\
        if (srcInputRegion.un32_height == 0)\
            return 0;\
        return 0;\
    }\

TYPE_TWO(E_AR_14x9)
TYPE_TWO(E_AR_14x9_ZOOM)

#undef TYPE_TWO

#define TYPE_DEFAULT(NAME)\
    int32_t getOutputRegion_##NAME(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype)\
    {\
        getOutInfo(outtype, panelType, pZoomOutputRegion);\
        if (srcInputRegion.un32_height == 0)\
            return 0;\
        return 0;\
    }\

TYPE_DEFAULT(E_AR_DEFAULT)
TYPE_DEFAULT(E_AR_16x9)
TYPE_DEFAULT(E_AR_CINERAMA)
TYPE_DEFAULT(E_AR_16x9_ZOOM)
TYPE_DEFAULT(E_AR_16x9_ZOOM_UP)
TYPE_DEFAULT(E_AR_STETCH_ZOOM)
TYPE_DEFAULT(E_AR_WIDE_ZOOM)
TYPE_DEFAULT(E_AR_ZOOM2)
TYPE_DEFAULT(E_AR_WIDE_ZOOM2)
TYPE_DEFAULT(E_AR_PANORAMA)
TYPE_DEFAULT(E_AR_JUSTSCAN)
TYPE_DEFAULT(E_AR_ZOOM1)
TYPE_DEFAULT(E_AR_SUBTITLE)
TYPE_DEFAULT(E_AR_MOVIE)
TYPE_DEFAULT(E_AR_PERSONAL)
TYPE_DEFAULT(E_AR_LETTERBOX)
TYPE_DEFAULT(E_AR_CENTER_CUT_OUT)

#undef TYPE_DEFAULT

typedef int32_t (*DataRetriver)(const PANEL_TYPE panelType, const SrcInputRegion srcInputRegion, ZoomOutputRegion *pZoomOutputRegion, const OutType outtype);

DataRetriver dataRetriver[24] = {
    &getOutputRegion_E_AR_DEFAULT,          //Default
    &getOutputRegion_E_AR_16x9,             //16x9
    &getOutputRegion_E_AR_4x3,              //4x3
    &getOutputRegion_E_AR_14x9,             //14x9
    &getOutputRegion_E_AR_CINERAMA,         //Cinerama
    &getOutputRegion_E_AR_16x9_ZOOM,        //16X9 zoom
    &getOutputRegion_E_AR_16x9_ZOOM_UP,     //16X9 zoom up
    &getOutputRegion_E_AR_14x9_ZOOM,        //14X9 zoom
    &getOutputRegion_E_AR_STETCH_ZOOM,      //STETCH ZOOM
    &getOutputRegion_E_AR_WIDE_ZOOM,        //WIDE ZOOM
    &getOutputRegion_E_AR_ZOOM2,            //10 Zoom 2
    &getOutputRegion_E_AR_WIDE_ZOOM2,       //WIDE ZOOM2
    &getOutputRegion_E_AR_AUTO,             //Auto
    &getOutputRegion_E_AR_PANORAMA,         //Panorama
    &getOutputRegion_E_AR_JUSTSCAN,         //Just Scan
    &getOutputRegion_E_AR_ZOOM1,            //Zoom 1
    &getOutputRegion_E_AR_DOTBYDOt,         //point to point
    &getOutputRegion_E_AR_SUBTITLE,         //Subtitle
    &getOutputRegion_E_AR_MOVIE,            //movie
    &getOutputRegion_E_AR_PERSONAL,         //Personal
    &getOutputRegion_E_AR_LETTERBOX,        //DEC_FC_LETTERBOX
    &getOutputRegion_E_AR_CENTER_CUT_OUT,   //CENTER_CUT_OUT
    &getOutputRegion_E_AR_PILLARBOX,        //PILLARBOX
    &getOutputRegion_E_AR_LETTERBOX_14_9   //LETTERBOX_14_9
};

int32_t rtk_zoom_get_output_window(
            PANEL_TYPE panelType,
            EN_WIDE_MODE wideMode,
            SrcInputRegion srcInputRegion,
            ZoomOutputRegion *pZoomOutputRegion)
{
    if ((pZoomOutputRegion == NULL) || (wideMode > E_AR_LETTERBOX_14_9)) {
        ALOGE("%s failed for bad param:panelType = %d, wideMode = %d\n", __FUNCTION__, panelType, wideMode);
        return -1;
    }

    ALOGI("%s PanelType = %d,WideMode = %d\n", __FUNCTION__, panelType, wideMode);

    OutType outtype = setOutType(wideMode);
    DataRetriver pRetriver = dataRetriver[wideMode];
    if (pRetriver != nullptr) {
        pRetriver(panelType, srcInputRegion, pZoomOutputRegion, outtype);
    }
    return 0;

}

如何加上行数,可以看到有缩减掉100行代码,很多时候大家都只会停留在流程代码上,忽视了优化,这样的话就不会有进步了.

更多的可以看这篇文章

https://blog.csdn.net/acaiwlj/article/details/49444099?readlog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值