android_hardware_aw/hwc/tulip/hwc_debug.cpp
2016-08-06 18:02:22 -04:00

477 lines
16 KiB
C++
Executable file

/*-------------------------------------------------------------------------
-------------------------------------------------------------------------*/
/*
* Copyright (C) Allwinner Tech All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hwc.h"
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>
char dump_src[40] = "/data/dump_layer";
static const char *hwc_print_info(AssignDUETO_T eError)
{
switch(eError)
{
#define AssignDUETO(x) \
case x: \
return #x;
AssignDUETO(I_OVERLAY)
AssignDUETO(D_NULL_BUF)
AssignDUETO(D_CONTIG_MEM)
AssignDUETO(D_VIDEO_PD)
AssignDUETO(D_CANNT_SCALE)
AssignDUETO(D_SKIP_LAYER)
AssignDUETO(D_NO_FORMAT)
AssignDUETO(D_BACKGROUND)
AssignDUETO(D_TR_N_0)
AssignDUETO(D_ALPHA)
AssignDUETO(D_X_FB)
AssignDUETO(D_SW_OFTEN)
AssignDUETO(D_SCALE_OUT)
AssignDUETO(D_STOP_HWC)
AssignDUETO(D_NO_PIPE)
AssignDUETO(D_NO_MEM)
AssignDUETO(D_MEM_CTRL)
#undef AssignDUETO
default:
return "Unknown reason";
}
}
void show_displays(HwcDisContext_t *Localctx)
{
int i;
SUNXI_hwcdev_context_t *Globctx = &gSunxiHwcDevice;
layer_info *AllLayers = Localctx->psAllLayer;
layer_info *sunxiLayers = NULL;
const DisplayInfo *PsDisplayInfo = Localctx->psDisplayInfo;
static char const* compositionTypeName[] = {
"GLES",
"HWC",
"BKGD",
"FB",
"SIDE",
"CURS",
"NULL"};
if(Globctx->hwcdebug && Globctx->show_layer)
{
if(PsDisplayInfo == NULL)
{
return;
}
ALOGD("\n\n+Disp info:\n"
"+ Fram Num|DP|Vsy|STP|CA(U)|Ad|IST|FPS (20,40,60)|MAX_LMTD|Cur_LMTD|TR_LMTD |All_Used|DSP_Used|CHNNEL_0|CHNNEL_1|CHNNEL_2|CHNNEL_3|timestamp\n"
"+---------+--+---+---+-----+--+---+--------------+--------+--------+--------+--------+--------+--------+--------+--------+--------+----------+");
ALOGD("+%9d| %d|%3s|%3s|%-2d(%d)|%2d|%3s|%02.1f,%02.1f,%02.1f|%8d|%8d|%8d|%8d|%8d|%8d|%8d|%8d|%8d|%lld\n"
,Globctx->HWCFramecount-1
,PsDisplayInfo->VirtualToHWDisplay
,PsDisplayInfo->VsyncEnable?"Yes":"No"
,Globctx->ForceGPUComp[0] ? "Yes":"No"
,Globctx->NumManagemax
,Globctx->NumManageUsed
,Globctx->AbandonCount
,Globctx->in_stabilization ? "Yes":"No"
,Globctx->fps[0]
,Globctx->fps[1]
,Globctx->fps[2]
,Globctx->max_mem_limit
,Globctx->memlimit
,Globctx->tr_mem_limit
,Globctx->currentmem
,Localctx->cur_de_thruput
,Localctx->ChannelInfo[0].memthruput
,Localctx->ChannelInfo[1].memthruput
,Localctx->ChannelInfo[2].memthruput
,Localctx->ChannelInfo[3].memthruput
,PsDisplayInfo->mytimestamp);
ALOGD("+---------+--+---+---+-----+--+---+--------------+--------+--------+--------+--------+--------+--------+--------+--------+--------+----------+");
ALOGD("+\n"
"+Type|CH|V|SC H|SC W|PL|S| Handle | Phyaddr | Usage | Flags |Tr|Bld| Format | Source Crop | Frame Crop | Reason\n"
"+----+--+-+----+----+--+-+-----------------+-----------------+---------+---------+--+---+---------+-------------------------+-------------------------+-------------\n");
if(AllLayers == NULL)
{
return ;
}
for(i = 0; i < Localctx->numberofLayer; i++)
{
sunxiLayers = AllLayers+i;
hwc_layer_1_t *l = sunxiLayers->psLayer;
struct private_handle_t *handle = (private_handle_t*)l->handle;
ALOGD("+%4s|%2d|%s|%1.2f|%1.2f|%02x|%d| %016x| %016x| %08x| %08x|%02x|%3x| %08x|[%5d,%5d,%5d,%5d]|[%5d,%5d,%5d,%5d]|%s\n",
compositionTypeName[l->compositionType],
sunxiLayers->hwchannel,
sunxiLayers->virchannel >= 0 ?
(Localctx->ChannelInfo[sunxiLayers->virchannel].hasVideo ? "Y" : "N"):"N",
sunxiLayers->virchannel >= 0 ?
Localctx->ChannelInfo[sunxiLayers->virchannel].HTScaleFactor :0,
sunxiLayers->virchannel >= 0 ?
Localctx->ChannelInfo[sunxiLayers->virchannel].WTScaleFactor :0,
sunxiLayers->virchannel >= 0 ?
Localctx->ChannelInfo[sunxiLayers->virchannel].planeAlpha : 0xff,
sunxiLayers->need_sync,
l->handle,
handle == 0 ? 0 :
((handle->flags & private_handle_t::PRIV_FLAGS_USES_CONFIG) ? ion_get_addr_fromfd(handle->share_fd):0),
handle == 0 ? 0 : handle->usage,
l->flags,
l->transform,
l->blending,
handle==0?0:handle->format,
#if !defined(HWC_1_3)
l->sourceCrop.left,
l->sourceCrop.top,
l->sourceCrop.right,
l->sourceCrop.bottom,
#else
(int)ceilf(l->sourceCropf.left),
(int)ceilf(l->sourceCropf.top),
(int)ceilf(l->sourceCropf.right),
(int)ceilf(l->sourceCropf.bottom),
#endif
l->displayFrame.left,
l->displayFrame.top,
l->displayFrame.right,
l->displayFrame.bottom,
sunxiLayers->info != DEFAULT? hwc_print_info(sunxiLayers->info): "NOT_ASSIGNED");
}
ALOGD("+----+--+-+----+----+--+-+-----------------+-----------------+---------+---------+--+---+---------+-------------------------+-------------------------+-------------\n");
}
}
static void hwc_show_fps(SUNXI_hwcdev_context_t *psCtx)
{
double fCurrentTime = 0.0;
timeval tv = { 0, 0 };
gettimeofday(&tv, NULL);
fCurrentTime = tv.tv_sec + tv.tv_usec / 1.0e6;
if(fCurrentTime - psCtx->fBeginTime >= 1)
{
if(psCtx->hwcdebug && psCtx->fps_layer)
{
ALOGD(">>>fps:: %d\n",
(int)((psCtx->HWCFramecount - psCtx->uiBeginFrame) * 1.0f
/ (fCurrentTime - psCtx->fBeginTime)));
}
psCtx->uiBeginFrame = psCtx->HWCFramecount;
psCtx->fBeginTime = fCurrentTime;
}
}
bool hwc_cmp(const char *s1, const char *s2)
{
while (*s1 == *s2 && *s1++ != 0 && *s2++ != 0)
{
}
if (*s1 == 0)
return 0;
return 1;
}
void hwc_set_debug(SUNXI_hwcdev_context_t *psCtx)
{
char property[PROPERTY_VALUE_MAX];
char *ps_fix = property;
if (property_get("debug.hwc.showfps", property, NULL) >= 0)
{
if(!hwc_cmp("debug", ps_fix))
{
if(psCtx->hwcdebug == 0)
{
ALOGD("####hwc open debug mode####");
}
psCtx->hwcdebug = 1;
ps_fix += 6;
if(!hwc_cmp("fps", ps_fix) && psCtx->fps_layer == 0)
{
psCtx->fps_layer = 1;
ALOGD("hwc open show fps mode");
}
if(!hwc_cmp("dump", ps_fix) && psCtx->dump_layer == 0)
{
psCtx->dump_layer = 1;
ALOGD("hwc open dump layer mode");
}
if(!hwc_cmp("show", ps_fix) && psCtx->show_layer == 0)
{
psCtx->show_layer = 1;
ALOGD("hwc open show layer mode");
}
if(!hwc_cmp("close", ps_fix) && psCtx->close_layer == 0)
{
psCtx->close_layer = 1;
ALOGD("hwc open close layer mode");
}
if(!hwc_cmp("pause", ps_fix) && psCtx->pause == 0)
{
psCtx->pause = 1;
ALOGD("hwc open pause layer mode");
}
}
if((!strcmp("clear", property) || !strcmp("0", ps_fix) )
&& psCtx->hwcdebug == 1)
{
psCtx->hwcdebug = 0;
psCtx->close_layer = 0;
psCtx->dump_layer = 0;
psCtx->fps_layer = 0;
psCtx->disp_st = -1;
psCtx->layer_st = -1;
psCtx->show_layer = 0;
psCtx->channel_st = -1;
psCtx->pause = 0;
ALOGD("####hwc close debug mode####");
}
if(!strcmp("1", ps_fix) && psCtx->fps_layer == 0)
{
psCtx->hwcdebug = 1;
psCtx->fps_layer = 1;
ALOGD("hwc open show fps mode");
}
if(!strcmp("2", ps_fix) && psCtx->show_layer == 0)
{
psCtx->hwcdebug = 1;
psCtx->show_layer = 1;
ALOGD("hwc open show layer mode");
}
}else{
psCtx->hwcdebug = 0;
}
hwc_show_fps(psCtx);
}
void hwc_debug_close_layer(SUNXI_hwcdev_context_t *psCtx, hwc_commit_data_t *commit_data)
{
if(psCtx->hwcdebug && psCtx->close_layer)
{
disp_layer_config *fix_layer = NULL;
hwc_commit_layer_t *hwc_layer_info = NULL;
int lyr = -1;
char property[PROPERTY_VALUE_MAX];
char *ps_fix = property;
bool change = 0;
if (property_get("debug.hwc.showfps", property, NULL) >= 0)
{
if(!hwc_cmp("set", ps_fix))
{
ps_fix += 4;
if(!hwc_cmp("d", ps_fix))
{
ps_fix++;
if(psCtx->disp_st != ((*ps_fix) - 48))
{
psCtx->disp_st = (*ps_fix) - 48;
change = 1;
}
}
ps_fix++;
if(!hwc_cmp("c", ps_fix))
{
ps_fix++;
if(psCtx->channel_st != ((*ps_fix) - 48))
{
psCtx->channel_st = (*ps_fix) - 48;
change = 1;
}
}
ps_fix++;
if(!hwc_cmp("l", ps_fix))
{
ps_fix++;
if(psCtx->layer_st != ((*ps_fix) - 48))
{
psCtx->layer_st = (*ps_fix) - 48;
change = 1;
}
}
if(change)
{
ALOGD("###will to close the disp[%d]--channel[%d]--layer[%d]###",
psCtx->disp_st, psCtx->channel_st, psCtx->layer_st);
}
}
}
if(psCtx->disp_st >= 0 && psCtx->disp_st < NUMBEROFDISPLAY)
{
if(psCtx->layer_st > -1
&& (psCtx->layer_st
< psCtx->SunxiDisplay[psCtx->disp_st].LayerNumofCH))
{
if(psCtx->channel_st > -1
&& (psCtx->channel_st
< psCtx->SunxiDisplay[psCtx->disp_st].HwChannelNum))
{
lyr = psCtx->channel_st
* psCtx->SunxiDisplay[psCtx->disp_st].LayerNumofCH
+ psCtx->layer_st;
fix_layer = &commit_data->hwc_layer_info[psCtx->disp_st][lyr];
}
}
}
if(fix_layer != NULL)
{
fix_layer->enable = 0;
ALOGD("###close the disp[%d]--channel[%d]--layer[%d]###",
psCtx->disp_st, psCtx->channel_st, psCtx->layer_st);
}
}
}
static int inline hwc_disp_pixel_bytes(disp_pixel_format format)
{
switch(format)
{
case DISP_FORMAT_YUV420_P:
case DISP_FORMAT_YUV420_SP_VUVU:
case DISP_FORMAT_YUV420_SP_UVUV:
return 12;
case DISP_FORMAT_ABGR_8888:
case DISP_FORMAT_XBGR_8888:
case DISP_FORMAT_ARGB_8888:
case DISP_FORMAT_XRGB_8888:
return 32;
case DISP_FORMAT_BGR_888:
return 24;
case DISP_FORMAT_RGB_565:
return 16;
default:
return 0;
}
return 0;
}
void hwc_debug_dump_layer(SUNXI_hwcdev_context_t *psCtx,
hwc_commit_layer_t *hwc_layer_info, int disp, int sync_count)
{
if(psCtx->hwcdebug && psCtx->dump_layer)
{
char property[PROPERTY_VALUE_MAX];
char *ps_fix = property;
if (property_get("debug.hwc.showfps", property, NULL) >= 0)
{
bool change = 0;
if(!hwc_cmp("set", ps_fix))
{
ps_fix += 4;
if(!hwc_cmp("d", ps_fix))
{
ps_fix++;
if(psCtx->disp_st != ((*ps_fix) - 48))
{
psCtx->disp_st = (*ps_fix) - 48;
change = 1;
}
}
ps_fix++;
if(!hwc_cmp("c", ps_fix))
{
ps_fix++;
if(psCtx->channel_st != ((*ps_fix) - 48))
{
psCtx->channel_st = (*ps_fix) - 48;
change = 1;
}
}
ps_fix++;
if(!hwc_cmp("l", ps_fix))
{
ps_fix++;
if(psCtx->layer_st != ((*ps_fix) - 48))
{
psCtx->layer_st = (*ps_fix) - 48;
change = 1;
}
}
if(change)
{
ALOGD("###dump the disp[%d]--channel[%d]--layer[%d]###",
psCtx->disp_st, psCtx->channel_st, psCtx->layer_st);
}
}
}
if(psCtx->disp_st == disp
&& psCtx->channel_st == (int)hwc_layer_info->hwc_layer_info.channel
&& psCtx->layer_st == (int)hwc_layer_info->hwc_layer_info.layer_id)
{
void *addr_0 = NULL;
int size = 0;
int fd = 0;
int ret = -1;
unsigned int width;
unsigned int height;
disp_pixel_format format = hwc_layer_info->hwc_layer_info.info.fb.format;
width = hwc_layer_info->hwc_layer_info.info.fb.size[0].width;
height = hwc_layer_info->hwc_layer_info.info.fb.size[0].height;
sprintf(dump_src, "/data/dump_%d_%02x", sync_count, hwc_layer_info->tr);
fd = open(dump_src, O_RDWR|O_CREAT,0644);
if(fd < 0)
{
ALOGD("open %s %d", dump_src, fd);
return ;
}
size = width * height * hwc_disp_pixel_bytes(format) / 8;
ALOGD("### Width:%d Height:%d Size:%d at frame:%d###",
width, height, size, sync_count);
addr_0 = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
hwc_layer_info->share_fd, 0);
ret = ::write(fd, addr_0, size);
if(ret != size)
{
ALOGD("write %s err %d", ret, dump_src);
}
munmap(addr_0,size);
close(fd);
ALOGD("###dump the disp[%d]--channel[%d]--layer[%d]--frame[%d]###",
psCtx->disp_st, psCtx->channel_st, psCtx->layer_st, sync_count);
}
}
}
bool hwc_debug_pause(SUNXI_hwcdev_context_t *psCtx, int sync_count, bool paused)
{
if(psCtx->hwcdebug && psCtx->pause && !paused)
{
char property[PROPERTY_VALUE_MAX];
char *ps_fix = property;
if (property_get("debug.hwc.showfps", property, NULL) >= 0)
{
bool change = 0;
if(!hwc_cmp("set", ps_fix))
{
ALOGD("###Pause at frame:%d ###", sync_count-1);
return 1;
}
}
}
return paused && psCtx->pause;
}