From 8afdc162ea8f5ef8a241a6bd988345b90633d6fa Mon Sep 17 00:00:00 2001 From: Naomi Luis Date: Fri, 16 Sep 2011 14:30:10 -0700 Subject: [PATCH] Upgrades to the updateOverlay functionality. Update the overlay when we have a channel up. Previously, we did updates only when the width and height changed. Now, we always update the overlay when the channel is open, and not close the channel to update parameters such as orientation change, flags etc. Change-Id: I0b2ef8b19bd860d5361c391e040ff497f1023ae3 --- libhwcomposer/hwcomposer.cpp | 46 ++---- liboverlay/overlayLib.cpp | 293 ++++++++++++++++++----------------- liboverlay/overlayLib.h | 19 ++- liboverlay/overlayLibUI.cpp | 5 +- 4 files changed, 169 insertions(+), 194 deletions(-) mode change 100644 => 100755 liboverlay/overlayLib.cpp mode change 100644 => 100755 liboverlay/overlayLib.h diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp index 401766f..e371ab8 100755 --- a/libhwcomposer/hwcomposer.cpp +++ b/libhwcomposer/hwcomposer.cpp @@ -198,39 +198,24 @@ static int prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer) { private_handle_t *hnd = (private_handle_t *)layer->handle; overlay::Overlay *ovLibObject = ctx->mOverlayLibObject; - int orientation = 0; overlay_buffer_info info; info.width = hnd->width; info.height = hnd->height; info.format = hnd->format; info.size = hnd->size; - if (OVERLAY_CHANNEL_UP == ovLibObject->getChannelStatus()) - ovLibObject->getOrientation(orientation); - - if ((OVERLAY_CHANNEL_DOWN == ovLibObject->getChannelStatus()) - || (layer->transform != orientation) || - (hnd->flags & private_handle_t::PRIV_FLAGS_FORMAT_CHANGED)) { - // Overlay channel is not started, or we have an orientation change - // or there is a format change, call setSource to open the overlay - // if necessary - ret = ovLibObject->setSource(info, layer->transform, + ret = ovLibObject->setSource(info, layer->transform, (ovLibObject->getHDMIStatus()?true:false), false); - if (!ret) { - LOGE("prepareOverlay setSource failed"); - return -1; - } - // Reset this flag so that we don't keep opening and closing channels - // unnecessarily - hnd->flags &= ~private_handle_t::PRIV_FLAGS_FORMAT_CHANGED; - } else { - // The overlay goemetry may have changed, we only need to update the - // overlay - ret = ovLibObject->updateOverlaySource(info, layer->transform); - if (!ret) { - LOGE("prepareOverlay updateOverlaySource failed"); - return -1; - } + if (!ret) { + LOGE("prepareOverlay setSource failed"); + return -1; + } + + ret = ovLibObject->setParameter(OVERLAY_TRANSFORM, layer->transform); + if (!ret) { + LOGE("prepareOverlay setParameter failed transform %x", + layer->transform); + return -1; } hwc_rect_t sourceCrop = layer->sourceCrop; @@ -242,15 +227,6 @@ static int prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer) { return -1; } - ovLibObject->getOrientation(orientation); - if (orientation != layer->transform) - ret = ovLibObject->setParameter(OVERLAY_TRANSFORM, layer->transform); - if (!ret) { - LOGE("prepareOverlay setParameter failed transform %x", - layer->transform); - return -1; - } - if (layer->flags == HWC_USE_ORIGINAL_RESOLUTION) { framebuffer_device_t* fbDev = hwcModule->fbDevice; ret = ovLibObject->setPosition(0, 0, diff --git a/liboverlay/overlayLib.cpp b/liboverlay/overlayLib.cpp old mode 100644 new mode 100755 index 186ea97..7d098f0 --- a/liboverlay/overlayLib.cpp +++ b/liboverlay/overlayLib.cpp @@ -45,38 +45,42 @@ int overlay::get_mdp_format(int format) { return MDP_Y_CRCB_H2V2_TILE; case HAL_PIXEL_FORMAT_YV12: return MDP_Y_CR_CB_H2V2; + default: + LOGE("%s: unknown color format [0x%x]", __FUNCTION__, format); + return -1; } return -1; } -int overlay::get_mdp_orientation(int rotation, int flip) { - switch(flip) { - case HAL_TRANSFORM_FLIP_V: - switch(rotation) { - case 0: return MDP_FLIP_UD; - case HAL_TRANSFORM_ROT_90: return (MDP_ROT_90 | MDP_FLIP_LR); - default: return -1; - break; - } - break; - case HAL_TRANSFORM_FLIP_H: - switch(rotation) { - case 0: return MDP_FLIP_LR; - case HAL_TRANSFORM_ROT_90: return (MDP_ROT_90 | MDP_FLIP_UD); - default: return -1; - break; - } - break; - default: - switch(rotation) { - case 0: return MDP_ROT_NOP; +int overlay::get_mdp_orientation(int value) { + switch(value) { + case 0: return 0; + case HAL_TRANSFORM_FLIP_V: return MDP_FLIP_UD; + case HAL_TRANSFORM_FLIP_H: return MDP_FLIP_LR; case HAL_TRANSFORM_ROT_90: return MDP_ROT_90; + case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V: + return MDP_ROT_90|MDP_FLIP_LR; + case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H: + return MDP_ROT_90|MDP_FLIP_UD; case HAL_TRANSFORM_ROT_180: return MDP_ROT_180; case HAL_TRANSFORM_ROT_270: return MDP_ROT_270; - default: return -1; - break; - } - break; + default: + LOGE("%s: invalid rotation value (value = 0x%x", + __FUNCTION__, value); + return -1; + } + return -1; +} + +// Rotator - input to output mapping +int overlay::get_rot_output_format(int format) { + switch (format) { + case MDP_Y_CRCB_H2V2_TILE: + return MDP_Y_CRCB_H2V2; + case MDP_Y_CB_CR_H2V2: + return MDP_Y_CBCR_H2V2; + default: + return format; } return -1; } @@ -233,6 +237,12 @@ bool overlay::enableBarrier (unsigned int orientation) { return false; } +int overlay::getColorFormat(int format) +{ + return (format == HAL_PIXEL_FORMAT_YV12) ? + format : COLOR_FORMAT(format); +} + unsigned int overlay::getOverlayConfig (unsigned int format3D, bool poll, bool isHDMI) { bool isTV3D = false; @@ -393,20 +403,44 @@ bool Overlay::setChannelPosition(int x, int y, uint32_t w, uint32_t h, int chann return objOvCtrlChannel[channel].setPosition(x, y, w, h); } -bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientation) { - if (hasHDMIStatusChanged()) { - return setSource(info, orientation, mHDMIConnected); +bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientation, + bool waitForVsync) { + bool ret = false; + int currentFlags = 0; + if (objOvCtrlChannel[0].isChannelUP()) { + currentFlags = objOvCtrlChannel[0].getOverlayFlags(); } - bool ret = false; + bool needUpdateFlags = false; + if (waitForVsync) { + if (currentFlags & MDP_OV_PLAY_NOWAIT) { + needUpdateFlags = true; + } + } else { + if (!(currentFlags & MDP_OV_PLAY_NOWAIT)) { + needUpdateFlags = true; + } + } + + bool geometryChanged = true; if (info.width == mOVBufferInfo.width && - info.height == mOVBufferInfo.height) { + info.height == mOVBufferInfo.height && + info.format == mOVBufferInfo.format) { + geometryChanged = false; + } + + if ((false == needUpdateFlags) && (false == geometryChanged)) { objOvDataChannel[0].updateDataChannel(0, 0); return true; } // Disable rotation for the HDMI channels - int orient[2] = {orientation, 0}; + int orientHdmi = 0; + int orient[2] = {true, orientHdmi}; + // enable waitForVsync on HDMI + bool waitForHDMI = true; + bool wait[2] = {waitForVsync, waitForHDMI}; + switch(mState) { case OV_3D_VIDEO_3D_PANEL: orient[1] = orientation; @@ -418,10 +452,19 @@ bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientati break; } + int numChannelsToUpdate = NUM_CHANNELS; + if (!geometryChanged) { + // Only update the primary channel - we only need to update the + // wait/no-wait flags + if (objOvCtrlChannel[0].isChannelUP()) { + return objOvCtrlChannel[0].updateWaitForVsyncFlags(waitForVsync); + } + } + // Set the overlay source info for (int i = 0; i < NUM_CHANNELS; i++) { if (objOvCtrlChannel[i].isChannelUP()) { - ret = objOvCtrlChannel[i].updateOverlaySource(info, orient[i]); + ret = objOvCtrlChannel[i].updateOverlaySource(info, orient[i], wait[i]); if (!ret) { LOGE("objOvCtrlChannel[%d].updateOverlaySource failed", i); return false; @@ -438,22 +481,6 @@ bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientati return ret; } -int Overlay::hasHDMIStatusChanged() { - int hdmiChanged = 0; - if (mHDMIConnected) { - // If HDMI is connected and both channels are not up, set the status - if (!objOvCtrlChannel[0].isChannelUP() || !objOvCtrlChannel[1].isChannelUP()) { - hdmiChanged = 0x1; - } - } else { - // HDMI is disconnected and both channels are up, set the status - if (objOvCtrlChannel[0].isChannelUP() && objOvCtrlChannel[1].isChannelUP()) { - hdmiChanged = 0x1; - } - } - return hdmiChanged; -} - int Overlay::getS3DFormat(int format) { // The S3D is part of the HAL_PIXEL_FORMAT_YV12 value. Add // an explicit check for the format @@ -474,22 +501,20 @@ int Overlay::getS3DFormat(int format) { } bool Overlay::setSource(const overlay_buffer_info& info, int orientation, - bool hdmiConnected, bool ignoreFB, int num_buffers) { + bool hdmiConnected, bool waitForVsync, int num_buffers) { // Separate the color format from the 3D format. // If there is 3D content; the effective format passed by the client is: // effectiveFormat = 3D_IN | 3D_OUT | ColorFormat int newState = mState; - bool stateChange = false, ret = true; + bool stateChange = false, ret = false; unsigned int format3D = getS3DFormat(info.format); int colorFormat = getColorFormat(info.format); - newState = getOverlayConfig (format3D, false, hdmiConnected); - stateChange = (mState == newState) ? false : true; - // Check if the orientation of the primary channel changed - if (mState != OV_3D_VIDEO_3D_TV) - if (mChannelUP) - ret = objOvCtrlChannel[0].setSource(info.width, info.height, - colorFormat, orientation, ignoreFB); - if (stateChange || !ret) { + if (-1 == mState) { + newState = getOverlayConfig (format3D, false, hdmiConnected); + stateChange = (mState == newState) ? false : true; + } + + if (stateChange) { closeChannel(); mHDMIConnected = hdmiConnected; mState = newState; @@ -498,17 +523,18 @@ bool Overlay::setSource(const overlay_buffer_info& info, int orientation, LOGI("3D content on 2D display: set the output format as monoscopic"); mS3DFormat = FORMAT_3D_INPUT(format3D) | HAL_3D_OUT_MONOSCOPIC_MASK; } - bool noRot = !orientation; + // We always enable the rotator for the primary. + bool noRot = false; switch(mState) { case OV_2D_VIDEO_ON_PANEL: case OV_3D_VIDEO_2D_PANEL: return startChannel(info, FRAMEBUFFER_0, noRot, false, - mS3DFormat, VG0_PIPE, ignoreFB, num_buffers); + mS3DFormat, VG0_PIPE, waitForVsync, num_buffers); break; case OV_3D_VIDEO_3D_PANEL: for (int i=0; i mFBWidth) mOVInfo.dst_rect.w = mFBWidth; if (h > mFBHeight) @@ -900,9 +935,12 @@ bool OverlayControlChannel::setOverlayInformation(const overlay_buffer_info& inf mOVInfo.alpha = 0xff; mOVInfo.transp_mask = 0xffffffff; mOVInfo.flags = flags; - if (!ignoreFB) - mOVInfo.flags |= MDP_OV_PLAY_NOWAIT; } + if (!ignoreFB) + mOVInfo.flags |= MDP_OV_PLAY_NOWAIT; + else + mOVInfo.flags &= ~MDP_OV_PLAY_NOWAIT; + return true; } @@ -930,9 +968,8 @@ bool OverlayControlChannel::startOVRotatorSessions( mRotInfo.dst.width = (((w-1)/64 +1)*64); mRotInfo.dst.height = (((h-1)/32 +1)*32); mRotInfo.dst.format = MDP_Y_CRCB_H2V2; - } else { - mRotInfo.dst.format = format; } + mRotInfo.dst.format = get_rot_output_format(format); mRotInfo.dst_x = 0; mRotInfo.dst_y = 0; mRotInfo.src_rect.x = 0; @@ -963,19 +1000,22 @@ bool OverlayControlChannel::startOVRotatorSessions( if (!ret) closeControlChannel(); - + else + mIsChannelUpdated = true; return ret; } bool OverlayControlChannel::updateOverlaySource(const overlay_buffer_info& info, - int orientation) + int orientation, bool waitForVsync) { - int hw_format = get_mdp_format(COLOR_FORMAT(info.format)); + int colorFormat = getColorFormat(info.format); + int hw_format = get_mdp_format(colorFormat); overlay_buffer_info ovBufInfo; ovBufInfo.width = info.width; ovBufInfo.height = info.height; ovBufInfo.format = hw_format; - if (!setOverlayInformation(ovBufInfo, 0, orientation, 0, 0, UPDATE_REQUEST)) + + if (!setOverlayInformation(ovBufInfo, 0, orientation, 0, waitForVsync, UPDATE_REQUEST)) return false; return startOVRotatorSessions(ovBufInfo, orientation, UPDATE_REQUEST); @@ -1053,59 +1093,18 @@ bool OverlayControlChannel::closeControlChannel() { return true; } -bool OverlayControlChannel::setSource(uint32_t w, uint32_t h, - int cFormat, int orientation, bool ignoreFB) { - int format = cFormat & INTERLACE_MASK ? - (cFormat ^ HAL_PIXEL_FORMAT_INTERLACE) : cFormat; - format = get_mdp_format(format); - if (orientation == mOrientation && orientation != 0){ - //set format to non-tiled and align w, h to 64-bit and 32-bit respectively. - if (format == MDP_Y_CRCB_H2V2_TILE) { - format = MDP_Y_CRCB_H2V2; - w = (((w-1)/64 +1)*64); - h = (((h-1)/32 +1)*32); - } - switch(orientation){ - case (HAL_TRANSFORM_ROT_90 | HAL_TRANSFORM_FLIP_H): - case (HAL_TRANSFORM_ROT_90 | HAL_TRANSFORM_FLIP_V): - case HAL_TRANSFORM_ROT_90: - case HAL_TRANSFORM_ROT_270: - { - int tmp = w; - w = h; - h = tmp; - } - default: - break; - } +bool OverlayControlChannel::updateWaitForVsyncFlags(bool waitForVsync) { + if (!waitForVsync) + mOVInfo.flags |= MDP_OV_PLAY_NOWAIT; + else + mOVInfo.flags &= ~MDP_OV_PLAY_NOWAIT; + + if (ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) { + LOGE("%s: OVERLAY_SET failed", __FUNCTION__); + dump(mOVInfo); + return false; } - - if (w == mOVInfo.src.width && h == mOVInfo.src.height - && format == mOVInfo.src.format && orientation == mOrientation) { - mdp_overlay ov; - ov.id = mOVInfo.id; - if (ioctl(mFD, MSMFB_OVERLAY_GET, &ov)) - return false; - mOVInfo = ov; - int flags = mOVInfo.flags; - - if (!ignoreFB) - mOVInfo.flags |= MDP_OV_PLAY_NOWAIT; - else - mOVInfo.flags &= ~MDP_OV_PLAY_NOWAIT; - - if (flags != mOVInfo.flags) { - if (ioctl(mFD, MSMFB_OVERLAY_SET, &mOVInfo)) { - LOGE("setSource, OVERLAY_SET failed"); - dump(mOVInfo); - return false; - } - } - - return true; - } - mOrientation = orientation; - return false; + return true; } bool OverlayControlChannel::setPosition(int x, int y, uint32_t w, uint32_t h) { @@ -1177,8 +1176,10 @@ bool OverlayControlChannel::useVirtualFB() { } bool OverlayControlChannel::setParameter(int param, int value, bool fetch) { - if (!isChannelUP()) + if (!isChannelUP()) { + LOGE("%s: channel is not up", __FUNCTION__); return false; + } mdp_overlay ov = mOVInfo; if (fetch && ioctl(mFD, MSMFB_OVERLAY_GET, &ov)) { @@ -1186,6 +1187,13 @@ bool OverlayControlChannel::setParameter(int param, int value, bool fetch) { return false; } mOVInfo = ov; + if (!mIsChannelUpdated && (OVERLAY_TRANSFORM == param)) { + int orientation = get_mdp_orientation(value); + if (orientation == mOVInfo.user_data[0]) { + return true; + } + } + mIsChannelUpdated = false; switch (param) { case OVERLAY_DITHER: @@ -1197,7 +1205,6 @@ bool OverlayControlChannel::setParameter(int param, int value, bool fetch) { return true; int rot = value; - int flip = 0; switch(rot) { case 0: @@ -1218,8 +1225,6 @@ bool OverlayControlChannel::setParameter(int param, int value, bool fetch) { mOVInfo.src_rect.y = tmp; swapOVRotWidthHeight(); } - rot = 0; - flip = value & (HAL_TRANSFORM_FLIP_H|HAL_TRANSFORM_FLIP_V); break; } case HAL_TRANSFORM_ROT_90: @@ -1239,8 +1244,6 @@ bool OverlayControlChannel::setParameter(int param, int value, bool fetch) { mOVInfo.src_rect.y = tmp; swapOVRotWidthHeight(); } - rot = HAL_TRANSFORM_ROT_90; - flip = value & (HAL_TRANSFORM_FLIP_H|HAL_TRANSFORM_FLIP_V); break; } case HAL_TRANSFORM_ROT_180: @@ -1280,7 +1283,7 @@ bool OverlayControlChannel::setParameter(int param, int value, bool fetch) { } default: return false; } - int mdp_rotation = get_mdp_orientation(rot, flip); + int mdp_rotation = get_mdp_orientation(rot); if (mdp_rotation == -1) return false; diff --git a/liboverlay/overlayLib.h b/liboverlay/overlayLib.h old mode 100644 new mode 100755 index 87a697c..e711a2a --- a/liboverlay/overlayLib.h +++ b/liboverlay/overlayLib.h @@ -122,10 +122,11 @@ bool send3DInfoPacket(unsigned int format3D); bool enableBarrier(unsigned int orientation); unsigned int getOverlayConfig (unsigned int format3D, bool poll = true, bool isHDMI = false); - +int getColorFormat(int format); int get_mdp_format(int format); int get_size(int format, int w, int h); -int get_mdp_orientation(int rotation, int flip); +int get_rot_output_format(int format); +int get_mdp_orientation(int value); void normalize_crop(uint32_t& xy, uint32_t& wh); /* Print values being sent to driver in case of ioctl failures @@ -155,6 +156,7 @@ class OverlayControlChannel { mdp_overlay mOVInfo; msm_rotator_img_info mRotInfo; msmfb_overlay_3d m3DOVInfo; + bool mIsChannelUpdated; bool openDevices(int fbnum = -1); bool setOverlayInformation(const overlay_buffer_info& info, int flags, int orientation, int zorder = 0, bool ignoreFB = false, @@ -183,13 +185,13 @@ public: int getFBHeight() const { return mFBHeight; } int getFormat3D() const { return mFormat3D; } bool getOrientation(int& orientation) const; - bool setSource(uint32_t w, uint32_t h, int format, - int orientation, bool ignoreFB); + bool updateWaitForVsyncFlags(bool waitForVsync); bool getAspectRatioPosition(int w, int h, overlay_rect *rect); bool getPositionS3D(int channel, int format, overlay_rect *rect); - bool updateOverlaySource(const overlay_buffer_info& info, int orientation); + bool updateOverlaySource(const overlay_buffer_info& info, int orientation, bool waitForVsync); bool getFormat() const { return mFormat; } bool useVirtualFB (); + int getOverlayFlags() const { return mOVInfo.flags; } }; class OverlayDataChannel { @@ -272,17 +274,14 @@ public: bool ignoreFB = false, int numBuffers = 2); bool setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h); int getChannelStatus() const { return (mChannelUP ? OVERLAY_CHANNEL_UP: OVERLAY_CHANNEL_DOWN); } - void setHDMIStatus (bool isHDMIConnected) { mHDMIConnected = isHDMIConnected; } + void setHDMIStatus (bool isHDMIConnected) { mHDMIConnected = isHDMIConnected; mState = -1; } int getHDMIStatus() const {return (mHDMIConnected ? HDMI_ON : HDMI_OFF); } - bool updateOverlaySource(const overlay_buffer_info& info, int orientation); private: bool setChannelPosition(int x, int y, uint32_t w, uint32_t h, int channel = 0); bool setChannelCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h, int channel); bool queueBuffer(int fd, uint32_t offset, int channel); - int hasHDMIStatusChanged(); - int getColorFormat(int format) { return (format == HAL_PIXEL_FORMAT_YV12) ? - format : COLOR_FORMAT(format); } + bool updateOverlaySource(const overlay_buffer_info& info, int orientation, bool waitForVsync); int getS3DFormat(int format); }; diff --git a/liboverlay/overlayLibUI.cpp b/liboverlay/overlayLibUI.cpp index 5e184fc..ccd97c0 100644 --- a/liboverlay/overlayLibUI.cpp +++ b/liboverlay/overlayLibUI.cpp @@ -89,13 +89,11 @@ void setupOvRotInfo(int w, int h, int format, int orientation, rotInfo.dst.height = srch; int rot = orientation; - int flip = 0; switch(rot) { case 0: case HAL_TRANSFORM_FLIP_H: case HAL_TRANSFORM_FLIP_V: rot = 0; - flip = orientation & (HAL_TRANSFORM_FLIP_H|HAL_TRANSFORM_FLIP_V); break; case HAL_TRANSFORM_ROT_90: case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H): @@ -106,7 +104,6 @@ void setupOvRotInfo(int w, int h, int format, int orientation, ovInfo.src_rect.y = tmp; swapOVRotWidthHeight(rotInfo, ovInfo); rot = HAL_TRANSFORM_ROT_90; - flip = orientation & (HAL_TRANSFORM_FLIP_H|HAL_TRANSFORM_FLIP_V); break; } case HAL_TRANSFORM_ROT_180: @@ -123,7 +120,7 @@ void setupOvRotInfo(int w, int h, int format, int orientation, break; } - int mdp_rotation = overlay::get_mdp_orientation(rot, flip); + int mdp_rotation = overlay::get_mdp_orientation(rot); if (mdp_rotation < 0) mdp_rotation = 0; ovInfo.user_data[0] = mdp_rotation;