hwc: Support for reading FB format from driver

- Instead of assuming the default format(RGBA_8888),
  read FB format from driver and pass the info to SF
- For now, this is limited to primary and HDMI only.
  WB FBformat is assumed to be in RGBA_8888
- If FB doesn't have alpha channel, disable mixed mode

Change-Id: Iefc0080819749b541483ea47357bb37ec150c544
This commit is contained in:
radhakrishna
2015-03-10 17:10:02 +05:30
parent 361b88f0c3
commit c3198ff918
7 changed files with 64 additions and 5 deletions

View File

@@ -13,11 +13,14 @@ LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL liboverlay \
libdl libmemalloc libqservice libsync \ libdl libmemalloc libqservice libsync \
libbinder libmedia libbinder libmedia
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
ifeq ($(TARGET_USES_QCOM_BSP),true) ifeq ($(TARGET_USES_QCOM_BSP),true)
LOCAL_SHARED_LIBRARIES += libskia LOCAL_SHARED_LIBRARIES += libskia
ifeq ($(GET_FRAMEBUFFER_FORMAT_FROM_HWC),true)
LOCAL_CFLAGS += -DGET_FRAMEBUFFER_FORMAT_FROM_HWC
endif
endif #TARGET_USES_QCOM_BSP endif #TARGET_USES_QCOM_BSP
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
#Enable Dynamic FPS if PHASE_OFFSET is not set #Enable Dynamic FPS if PHASE_OFFSET is not set
ifeq ($(VSYNC_EVENT_PHASE_OFFSET_NS),) ifeq ($(VSYNC_EVENT_PHASE_OFFSET_NS),)
LOCAL_CFLAGS += -DDYNAMIC_FPS LOCAL_CFLAGS += -DDYNAMIC_FPS

View File

@@ -805,6 +805,9 @@ int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
HWC_DISPLAY_DPI_X, HWC_DISPLAY_DPI_X,
HWC_DISPLAY_DPI_Y, HWC_DISPLAY_DPI_Y,
HWC_DISPLAY_SECURE, HWC_DISPLAY_SECURE,
#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
HWC_DISPLAY_FBFORMAT,
#endif
HWC_DISPLAY_NO_ATTRIBUTE, HWC_DISPLAY_NO_ATTRIBUTE,
}; };
@@ -855,6 +858,11 @@ int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
case HWC_DISPLAY_SECURE: case HWC_DISPLAY_SECURE:
values[i] = (int32_t) (ctx->dpyAttr[disp].secure); values[i] = (int32_t) (ctx->dpyAttr[disp].secure);
break; break;
#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
case HWC_DISPLAY_FBFORMAT:
values[i] = ctx->dpyAttr[disp].fbformat;
break;
#endif
default: default:
ALOGE("Unknown display attribute %d", ALOGE("Unknown display attribute %d",
attributes[i]); attributes[i]);

View File

@@ -56,7 +56,7 @@ IFBUpdate::IFBUpdate(hwc_context_t *ctx, const int& dpy) : mDpy(dpy) {
yres = ctx->dpyAttr[mDpy].yres_new; yres = ctx->dpyAttr[mDpy].yres_new;
} }
getBufferAttributes((int)xres, (int)yres, getBufferAttributes((int)xres, (int)yres,
HAL_PIXEL_FORMAT_RGBA_8888, ctx->dpyAttr[mDpy].fbformat,
0, 0,
mAlignedFBWidth, mAlignedFBWidth,
mAlignedFBHeight, mAlignedFBHeight,
@@ -136,7 +136,7 @@ bool FBUpdateNonSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *lis
int flags = mTileEnabled ? int flags = mTileEnabled ?
private_handle_t::PRIV_FLAGS_TILE_RENDERED : 0; private_handle_t::PRIV_FLAGS_TILE_RENDERED : 0;
ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight, ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888, flags)); ovutils::getMdpFormat(ctx->dpyAttr[mDpy].fbformat, flags));
Overlay::PipeSpecs pipeSpecs; Overlay::PipeSpecs pipeSpecs;
pipeSpecs.formatClass = Overlay::FORMAT_RGB; pipeSpecs.formatClass = Overlay::FORMAT_RGB;

View File

@@ -1126,8 +1126,8 @@ bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
{ {
if(!sEnableMixedMode) { if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
//Mixed mode is disabled. No need to even try caching. //Mixed mode is disabled/can't be used. No need to even try caching.
return false; return false;
} }

View File

@@ -86,6 +86,32 @@ namespace qhwc {
// Std refresh rates for digital videos- 24p, 30p, 48p and 60p // Std refresh rates for digital videos- 24p, 30p, 48p and 60p
uint32_t stdRefreshRates[] = { 30, 24, 48, 60 }; uint32_t stdRefreshRates[] = { 30, 24, 48, 60 };
static uint32_t getFBformat(fb_var_screeninfo vinfo) {
uint32_t fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
// Here, we are adding the formats that are supported by both GPU and MDP.
// The formats that fall in this category are RGBA_8888, RGB_565, RGB_888
switch(vinfo.bits_per_pixel) {
case 16:
fbformat = HAL_PIXEL_FORMAT_RGB_565;
break;
case 24:
if ((vinfo.transp.offset == 0) && (vinfo.transp.length == 0))
fbformat = HAL_PIXEL_FORMAT_RGB_888;
break;
case 32:
if ((vinfo.red.offset == 0) && (vinfo.green.offset == 8) &&
(vinfo.blue.offset == 16) && (vinfo.transp.offset == 24))
fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
break;
default:
fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
}
#endif
return fbformat;
}
bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres) bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
{ {
return !((xres > qdutils::MDPVersion::getInstance().getMaxPipeWidth() && return !((xres > qdutils::MDPVersion::getInstance().getMaxPipeWidth() &&
@@ -125,6 +151,14 @@ void changeResolution(hwc_context_t *ctx, int xres_orig, int yres_orig,
// Initialize hdmi display attributes based on // Initialize hdmi display attributes based on
// hdmi display class state // hdmi display class state
void updateDisplayInfo(hwc_context_t* ctx, int dpy) { void updateDisplayInfo(hwc_context_t* ctx, int dpy) {
struct fb_var_screeninfo info;
if (ioctl(ctx->mHDMIDisplay->getFd(), FBIOGET_VSCREENINFO, &info) == -1) {
ALOGE("%s:Error in ioctl FBIOGET_VSCREENINFO: %s",
__FUNCTION__, strerror(errno));
}
ctx->dpyAttr[dpy].fbformat = getFBformat(info);
ctx->dpyAttr[dpy].fd = ctx->mHDMIDisplay->getFd(); ctx->dpyAttr[dpy].fd = ctx->mHDMIDisplay->getFd();
ctx->dpyAttr[dpy].xres = ctx->mHDMIDisplay->getWidth(); ctx->dpyAttr[dpy].xres = ctx->mHDMIDisplay->getWidth();
ctx->dpyAttr[dpy].yres = ctx->mHDMIDisplay->getHeight(); ctx->dpyAttr[dpy].yres = ctx->mHDMIDisplay->getHeight();
@@ -233,6 +267,7 @@ static int openFramebufferDevice(hwc_context_t *ctx)
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].secure = true; ctx->dpyAttr[HWC_DISPLAY_PRIMARY].secure = true;
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period =
(uint32_t)(1000000000l / fps); (uint32_t)(1000000000l / fps);
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fbformat = getFBformat(info);
//To change resolution of primary display //To change resolution of primary display
changeResolution(ctx, info.xres, info.yres, info.width, info.height); changeResolution(ctx, info.xres, info.yres, info.width, info.height);
@@ -965,6 +1000,16 @@ bool isAlphaPresent(hwc_layer_1_t const* layer) {
return false; return false;
} }
bool isAlphaPresentinFB(hwc_context_t *ctx, int dpy) {
switch(ctx->dpyAttr[dpy].fbformat) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
return true;
default : return false;
}
return false;
}
static void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform, static void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
hwc_rect_t& crop, hwc_rect_t& dst) { hwc_rect_t& crop, hwc_rect_t& dst) {
int hw_w = ctx->dpyAttr[dpy].xres; int hw_w = ctx->dpyAttr[dpy].xres;

View File

@@ -90,6 +90,7 @@ struct DisplayAttributes {
float xdpi; float xdpi;
float ydpi; float ydpi;
bool secure; bool secure;
uint32_t fbformat;
int fd; int fd;
bool connected; //Applies only to pluggable disp. bool connected; //Applies only to pluggable disp.
//Connected does not mean it ready to use. //Connected does not mean it ready to use.
@@ -300,6 +301,7 @@ bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR, void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
private_handle_t *hnd); private_handle_t *hnd);
bool isAlphaPresent(hwc_layer_1_t const* layer); bool isAlphaPresent(hwc_layer_1_t const* layer);
bool isAlphaPresentinFB(hwc_context_t* ctx, int dpy);
int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable); int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
int getBlending(int blending); int getBlending(int blending);
bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy); bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy);

View File

@@ -90,6 +90,7 @@ int HWCVirtualVDS::prepare(hwc_composer_device_1 *dev,
// it up to the consumer to decide how fast to consume frames. // it up to the consumer to decide how fast to consume frames.
ctx->dpyAttr[dpy].vsync_period ctx->dpyAttr[dpy].vsync_period
= ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period; = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period;
ctx->dpyAttr[dpy].fbformat = HAL_PIXEL_FORMAT_RGBA_8888;
init(ctx); init(ctx);
// Do one padding round for cases where primary has all pipes // Do one padding round for cases where primary has all pipes
// The virtual composition falls back to GPU in such cases. // The virtual composition falls back to GPU in such cases.