diff options
author | Saurabh Shah <saurshah@codeaurora.org> | 2012-09-17 16:53:21 -0700 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2012-09-25 22:51:14 -0700 |
commit | 3e858ebde3f2b4e762af8f7f2808d45ba59b890d (patch) | |
tree | b76457440ec55a50451425357c3b5b9e16281734 | |
parent | 52fc4cdb4df6fe5ced235cde7f409481c71a2b21 (diff) | |
download | android_hardware_qcom_display-3e858ebde3f2b4e762af8f7f2808d45ba59b890d.tar.gz android_hardware_qcom_display-3e858ebde3f2b4e762af8f7f2808d45ba59b890d.tar.bz2 android_hardware_qcom_display-3e858ebde3f2b4e762af8f7f2808d45ba59b890d.zip |
hwc: hwc 1.1 implementation
Bug: 7124159
--External disabled
--MDP comp coded but disabled.
--Videos via overlay, so that secure videos can work.
Change-Id: Ie48b264143d5e4237ab9724e28930e3f68ba49ee
Signed-off-by: Iliyan Malchev <malchev@google.com>
-rw-r--r-- | libexternal/external.cpp | 97 | ||||
-rw-r--r-- | libexternal/external.h | 18 | ||||
-rw-r--r-- | libgralloc/framebuffer.cpp | 45 | ||||
-rw-r--r-- | libhwcomposer/Android.mk | 3 | ||||
-rw-r--r-- | libhwcomposer/hwc.cpp | 296 | ||||
-rw-r--r-- | libhwcomposer/hwc_extonly.cpp | 3 | ||||
-rw-r--r-- | libhwcomposer/hwc_mdpcomp.cpp | 60 | ||||
-rw-r--r-- | libhwcomposer/hwc_mdpcomp.h | 17 | ||||
-rw-r--r-- | libhwcomposer/hwc_uevents.cpp | 14 | ||||
-rw-r--r-- | libhwcomposer/hwc_uimirror.cpp | 57 | ||||
-rw-r--r-- | libhwcomposer/hwc_uimirror.h | 6 | ||||
-rw-r--r-- | libhwcomposer/hwc_utils.cpp | 138 | ||||
-rw-r--r-- | libhwcomposer/hwc_utils.h | 59 | ||||
-rw-r--r-- | libhwcomposer/hwc_video.cpp | 293 | ||||
-rw-r--r-- | libhwcomposer/hwc_video.h | 42 |
15 files changed, 556 insertions, 592 deletions
diff --git a/libexternal/external.cpp b/libexternal/external.cpp index 2142125fe..b5a1fdb37 100644 --- a/libexternal/external.cpp +++ b/libexternal/external.cpp @@ -94,11 +94,6 @@ void ExternalDisplay::getEDIDModes(int *out) const { } } -int ExternalDisplay::getExternalDisplay() const { - Mutex::Autolock lock(mExtDispLock); - return mExternalDisplay; -} - ExternalDisplay::~ExternalDisplay() { closeFrameBuffer(); @@ -249,6 +244,9 @@ bool ExternalDisplay::openFramebuffer() if (mFd < 0) ALOGE("%s: /dev/graphics/fb1 not available", __FUNCTION__); } + if(mHwcContext) { + mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd; + } return (mFd > 0); } @@ -259,6 +257,9 @@ bool ExternalDisplay::closeFrameBuffer() ret = close(mFd); mFd = -1; } + if(mHwcContext) { + mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd; + } return (ret == 0); } @@ -411,11 +412,10 @@ void ExternalDisplay::setExternalDisplay(int connected) //Get the best mode and set // TODO: DO NOT call this for WFD setResolution(getBestMode()); + setDpyAttr(); //enable hdmi vsync - enableHDMIVsync(connected); } else { // Disable the hdmi vsync - enableHDMIVsync(connected); closeFrameBuffer(); resetInfo(); } @@ -424,9 +424,9 @@ void ExternalDisplay::setExternalDisplay(int connected) const char* prop = (connected) ? "1" : "0"; // set system property property_set("hw.hdmiON", prop); - /* Trigger redraw */ - ALOGD_IF(DEBUG, "%s: Invalidate !!", __FUNCTION__); - ctx->proc->invalidate(ctx->proc); + //Inform SF + ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false; + ctx->proc->hotplug(ctx->proc, HWC_DISPLAY_EXTERNAL, connected); } return; } @@ -458,7 +458,7 @@ bool ExternalDisplay::writeHPDOption(int userOption) const return ret; } -bool ExternalDisplay::commit() +bool ExternalDisplay::post() { if(mFd == -1) { return false; @@ -470,16 +470,73 @@ bool ExternalDisplay::commit() return true; } -int ExternalDisplay::enableHDMIVsync(int enable) -{ - if(mFd > 0) { - int ret = ioctl(mFd, MSMFB_OVERLAY_VSYNC_CTRL, &enable); - if (ret<0) { - ALOGE("%s: enabling HDMI vsync failed, str: %s", __FUNCTION__, - strerror(errno)); - } +void ExternalDisplay::setDpyAttr() { + int width = 0, height = 0, fps = 0; + getAttrForMode(width, height, fps); + if(mHwcContext) { + mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = width; + mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = height; + mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period = 1000000000l / + fps; + } +} + +void ExternalDisplay::getAttrForMode(int& width, int& height, +int& fps) { + switch (mCurrentMode) { + case m640x480p60_4_3: + width = 640; + height = 480; + fps = 60; + break; + case m720x480p60_4_3: + case m720x480p60_16_9: + width = 720; + height = 480; + fps = 60; + break; + case m720x576p50_4_3: + case m720x576p50_16_9: + width = 720; + height = 576; + fps = 50; + break; + case m1280x720p50_16_9: + width = 1280; + height = 720; + fps = 50; + break; + case m1280x720p60_16_9: + width = 1280; + height = 720; + fps = 60; + break; + case m1920x1080p24_16_9: + width = 1920; + height = 1080; + fps = 24; + break; + case m1920x1080p25_16_9: + width = 1920; + height = 1080; + fps = 25; + break; + case m1920x1080p30_16_9: + width = 1920; + height = 1080; + fps = 30; + break; + case m1920x1080p50_16_9: + width = 1920; + height = 1080; + fps = 50; + break; + case m1920x1080p60_16_9: + width = 1920; + height = 1080; + fps = 60; + break; } - return -errno; } }; diff --git a/libexternal/external.h b/libexternal/external.h index 09cde3bcd..da3ccd5af 100644 --- a/libexternal/external.h +++ b/libexternal/external.h @@ -30,27 +30,13 @@ namespace qhwc { class ExternalDisplay { - //Type of external display - OFF, HDMI, WFD - enum external_display_type { - EXT_TYPE_NONE, - EXT_TYPE_HDMI, - EXT_TYPE_WIFI - }; - - // Mirroring state - enum external_mirroring_state { - EXT_MIRRORING_OFF, - EXT_MIRRORING_ON, - }; public: ExternalDisplay(hwc_context_t* ctx); ~ExternalDisplay(); int getModeCount() const; void getEDIDModes(int *out) const; - int getExternalDisplay() const; void setExternalDisplay(int connected); - bool commit(); - int enableHDMIVsync(int enable); + bool post(); void setHPD(uint32_t startEnd); void setEDIDMode(int resMode); void setActionSafeDimension(int w, int h); @@ -67,6 +53,8 @@ private: int getModeOrder(int mode); int getBestMode(); void resetInfo(); + void setDpyAttr(); + void getAttrForMode(int& width, int& height, int& fps); mutable android::Mutex mExtDispLock; int mFd; diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp index 022d65849..0f67b14fa 100644 --- a/libgralloc/framebuffer.cpp +++ b/libgralloc/framebuffer.cpp @@ -100,51 +100,22 @@ static int fb_setUpdateRect(struct framebuffer_device_t* dev, static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) { - if (private_handle_t::validate(buffer) < 0) - return -EINVAL; fb_context_t* ctx = (fb_context_t*) dev; private_handle_t *hnd = static_cast<private_handle_t*> - (const_cast<native_handle_t*>(buffer)); - + (const_cast<native_handle_t*>(buffer)); private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module); - - if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { - genlock_lock_buffer(hnd, GENLOCK_READ_LOCK, GENLOCK_MAX_TIMEOUT); - - if (m->currentBuffer) { - genlock_unlock_buffer(m->currentBuffer); - m->currentBuffer = 0; - } - - const size_t offset = hnd->base - m->framebuffer->base; - // frame ready to be posted, signal so that hwc can update External - // display - pthread_mutex_lock(&m->fbPostLock); - m->currentOffset = offset; - m->fbPostDone = true; - pthread_cond_signal(&m->fbPostCond); - pthread_mutex_unlock(&m->fbPostLock); - - m->info.activate = FB_ACTIVATE_VBL; - m->info.yoffset = offset / m->finfo.line_length; + if (hnd && hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { + m->info.activate = FB_ACTIVATE_VBL | FB_ACTIVATE_FORCE; + m->info.yoffset = hnd->offset / m->finfo.line_length; if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) { - ALOGE("FBIOPUT_VSCREENINFO failed"); - genlock_unlock_buffer(hnd); + ALOGE("%s: FBIOPUT_VSCREENINFO failed for external, err: %s", __FUNCTION__, + strerror(errno)); return -errno; } - - //Signals the composition thread to unblock and loop over if necessary - pthread_mutex_lock(&m->fbPanLock); - m->fbPanDone = true; - pthread_cond_signal(&m->fbPanCond); - pthread_mutex_unlock(&m->fbPanLock); - - CALC_FPS(); - m->currentBuffer = hnd; } return 0; } @@ -387,7 +358,9 @@ static int fb_close(struct hw_device_t *dev) { fb_context_t* ctx = (fb_context_t*)dev; if (ctx) { - free(ctx); + //Hack until fbdev is removed. Framework could close this causing hwc a + //pain. + //free(ctx); } return 0; } diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk index 343686c15..4e52ede9d 100644 --- a/libhwcomposer/Android.mk +++ b/libhwcomposer/Android.mk @@ -14,10 +14,7 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_SRC_FILES := hwc.cpp \ hwc_video.cpp \ hwc_utils.cpp \ - hwc_uimirror.cpp \ hwc_uevents.cpp \ - hwc_copybit.cpp \ hwc_mdpcomp.cpp \ - hwc_extonly.cpp include $(BUILD_SHARED_LIBRARY) diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp index e688538b4..3be2def2d 100644 --- a/libhwcomposer/hwc.cpp +++ b/libhwcomposer/hwc.cpp @@ -26,13 +26,9 @@ #include <fb_priv.h> #include <mdp_version.h> #include "hwc_utils.h" -#include "hwc_qbuf.h" #include "hwc_video.h" -#include "hwc_uimirror.h" -#include "hwc_copybit.h" #include "external.h" #include "hwc_mdpcomp.h" -#include "hwc_extonly.h" using namespace qhwc; @@ -76,56 +72,66 @@ static void hwc_registerProcs(struct hwc_composer_device_1* dev, } //Helper -static void reset() { - //reset for this draw round - VideoOverlay::reset(); - ExtOnly::reset(); - UIMirrorOverlay::reset(); - ExtOnly::reset(); - //TODO MDPComp +static void reset(hwc_context_t *ctx, int numDisplays) { + memset(ctx->listStats, 0, sizeof(ctx->listStats)); + for(int i = 0; i < numDisplays; i++){ + ctx->listStats[i].yuvIndex = -1; + } +} + +static int hwc_prepare_primary(hwc_composer_device_1 *dev, + hwc_display_contents_1_t *list) { + hwc_context_t* ctx = (hwc_context_t*)(dev); + if (LIKELY(list && list->numHwLayers)) { + setListStats(ctx, list, HWC_DISPLAY_PRIMARY); + if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY)) { + ctx->overlayInUse = true; + } else if(MDPComp::configure(ctx, list)) { + ctx->overlayInUse = true; + } else { + ctx->overlayInUse = false; + } + } + return 0; +} + +static int hwc_prepare_external(hwc_composer_device_1 *dev, + hwc_display_contents_1_t *list) { + + hwc_context_t* ctx = (hwc_context_t*)(dev); + if (LIKELY(list && list->numHwLayers)) { + setListStats(ctx, list, HWC_DISPLAY_EXTERNAL); + //Nothing to do for now + } + return 0; } static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, hwc_display_contents_1_t** displays) { + int ret = 0; hwc_context_t* ctx = (hwc_context_t*)(dev); ctx->overlayInUse = false; - reset(); + reset(ctx, numDisplays); //If securing of h/w in progress skip comp using overlay. if(ctx->mSecuring == true) return 0; for (uint32_t i = 0; i < numDisplays; i++) { hwc_display_contents_1_t *list = displays[i]; - //XXX: Actually handle the multiple displays - if (LIKELY(list && list->numHwLayers)) { - ctx->dpys[i] = list->dpy; - - if(ctx->isPoweredDown) - ALOGW("SF called %s after a POWERDOWN", __FUNCTION__); - - getLayerStats(ctx, list); - if(VideoOverlay::prepare(ctx, list)) { - ctx->overlayInUse = true; - //Nothing here - } else if(ExtOnly::prepare(ctx, list)) { - ctx->overlayInUse = true; - } else if(UIMirrorOverlay::prepare(ctx, list)) { - ctx->overlayInUse = true; - } else if(MDPComp::configure(dev, list)) { - ctx->overlayInUse = true; - } else if (0) { - //Other features - ctx->overlayInUse = true; - } else { // Else set this flag to false, otherwise video cases - // fail in non-overlay targets. - ctx->overlayInUse = false; - } + switch(i) { + case HWC_DISPLAY_PRIMARY: + ret = hwc_prepare_primary(dev, list); + break; + case HWC_DISPLAY_EXTERNAL: + ret = hwc_prepare_external(dev, list); + break; + default: + ret = -EINVAL; } } - - return 0; + return ret; } static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, @@ -135,16 +141,15 @@ static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, hwc_context_t* ctx = (hwc_context_t*)(dev); private_module_t* m = reinterpret_cast<private_module_t*>( ctx->mFbDev->common.module); - //XXX: Handle dpy switch(event) { case HWC_EVENT_VSYNC: - if(ioctl(m->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL, &enabled) < 0) + if(ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL, + &enabled) < 0) { + ALOGE("%s: vsync control failed. Dpy=%d, enabled=%d : %s", + __FUNCTION__, dpy, enabled, strerror(errno)); ret = -errno; - - if(ctx->mExtDisplay->getExternalDisplay()) { - ret = ctx->mExtDisplay->enableHDMIVsync(enabled); } - break; + break; default: ret = -EINVAL; } @@ -153,23 +158,37 @@ static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank) { - //XXX: Handle based on dpy hwc_context_t* ctx = (hwc_context_t*)(dev); private_module_t* m = reinterpret_cast<private_module_t*>( ctx->mFbDev->common.module); - if(blank) { - ctx->mOverlay->setState(ovutils::OV_CLOSED); - ctx->qbuf->unlockAllPrevious(); - ALOGD("HWC Calling POWERDOWN ..."); - ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN); - ALOGD("HWC Done POWERDOWN ..."); - ctx->isPoweredDown = true; - } else { - ALOGD("HWC Calling UNBLANK ..."); - ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK); - ALOGD("HWC Done UNBLANK ..."); - ctx->isPoweredDown = false; + int ret = 0; + ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank); + switch(dpy) { + case HWC_DISPLAY_PRIMARY: + if(blank) { + ctx->mOverlay->setState(ovutils::OV_CLOSED); + ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN); + } else { + ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK); + } + break; + case HWC_DISPLAY_EXTERNAL: + if(blank) { + //TODO actual + } else { + } + break; + default: + return -EINVAL; + } + + if(ret < 0) { + ALOGE("%s: failed. Dpy=%d, blank=%d : %s", + __FUNCTION__, dpy, blank, strerror(errno)); + return ret; } + ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank); + ctx->dpyAttr[dpy].isActive = !blank; return 0; } @@ -179,16 +198,23 @@ static int hwc_query(struct hwc_composer_device_1* dev, hwc_context_t* ctx = (hwc_context_t*)(dev); private_module_t* m = reinterpret_cast<private_module_t*>( ctx->mFbDev->common.module); + int supported = HWC_DISPLAY_PRIMARY_BIT; switch (param) { case HWC_BACKGROUND_LAYER_SUPPORTED: // Not supported for now value[0] = 0; break; - case HWC_VSYNC_PERIOD: + case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1 value[0] = m->fps; ALOGI("fps: %d", value[0]); break; + case HWC_DISPLAY_TYPES_SUPPORTED: + //Enable later + //if(ctx->mMDP.hasOverlay) + //supported |= HWC_DISPLAY_EXTERNAL_BIT; + value[0] = supported; + break; default: return -EINVAL; } @@ -196,45 +222,122 @@ static int hwc_query(struct hwc_composer_device_1* dev, } +static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { + if (LIKELY(list && list->numHwLayers)) { + VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY); + MDPComp::draw(ctx, list); + hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY); + //TODO We dont check for SKIP flag on this layer because we need PAN + //always. Last layer is always FB + uint32_t last = list->numHwLayers - 1; + if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET) { + ctx->mFbDev->post(ctx->mFbDev, list->hwLayers[last].handle); + } + } + return 0; +} + +static int hwc_set_external(hwc_context_t *ctx, + hwc_display_contents_1_t* list) { + if (LIKELY(list && list->numHwLayers)) { + hwc_sync(ctx, list, HWC_DISPLAY_EXTERNAL); + uint32_t last = list->numHwLayers - 1; + if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET && + ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive) { + //ctx->mExtDisplay->post(list->hwLayers[last].handle); + } + } + return 0; +} + static int hwc_set(hwc_composer_device_1 *dev, size_t numDisplays, hwc_display_contents_1_t** displays) { int ret = 0; hwc_context_t* ctx = (hwc_context_t*)(dev); - for (uint32_t i = 0; i <numDisplays; i++) { + for (uint32_t i = 0; i < numDisplays; i++) { hwc_display_contents_1_t* list = displays[i]; - //XXX: Actually handle the multiple displays - if (LIKELY(list)) { - VideoOverlay::draw(ctx, list); - ExtOnly::draw(ctx, list); - MDPComp::draw(ctx, list); - - //Sync TODO better error handling. - hwc_sync(list); - - EGLBoolean success = eglSwapBuffers((EGLDisplay)list->dpy, - (EGLSurface)list->sur); - wait4fbPost(ctx); - //Can draw to HDMI only when fb_post is reached - UIMirrorOverlay::draw(ctx); - //HDMI commit and primary commit (PAN) happening in parallel - if(ctx->mExtDisplay->getExternalDisplay()) - ctx->mExtDisplay->commit(); - //Virtual barrier for threads to finish - wait4Pan(ctx); - } else { - ctx->mOverlay->setState(ovutils::OV_CLOSED); - ctx->qbuf->unlockAll(); + switch(i) { + case HWC_DISPLAY_PRIMARY: + ret = hwc_set_primary(ctx, list); + case HWC_DISPLAY_EXTERNAL: + ret = hwc_set_external(ctx, list); + default: + ret = -EINVAL; } + } + if(!ctx->overlayInUse) + ctx->mOverlay->setState(ovutils::OV_CLOSED); + + return ret; +} - if(!ctx->overlayInUse) - ctx->mOverlay->setState(ovutils::OV_CLOSED); +int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, + uint32_t* configs, size_t* numConfigs) { + int ret = 0; + //in 1.1 there is no way to choose a config, report as config id # 0 + //This config is passed to getDisplayAttributes. Ignore for now. + if(*numConfigs == 1) + *configs = 0; + switch(disp) { + case HWC_DISPLAY_PRIMARY: + ret = 0; + break; + case HWC_DISPLAY_EXTERNAL: + //Hack until hotplug is supported. + //This makes framework ignore external display. + ret = -1; + break; } - ctx->qbuf->unlockAllPrevious(); return ret; } +int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp, + uint32_t config, const uint32_t* attributes, int32_t* values) { + + hwc_context_t* ctx = (hwc_context_t*)(dev); + //From HWComposer + static const uint32_t DISPLAY_ATTRIBUTES[] = { + HWC_DISPLAY_VSYNC_PERIOD, + HWC_DISPLAY_WIDTH, + HWC_DISPLAY_HEIGHT, + HWC_DISPLAY_DPI_X, + HWC_DISPLAY_DPI_Y, + HWC_DISPLAY_NO_ATTRIBUTE, + }; + + const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) / + sizeof(DISPLAY_ATTRIBUTES)[0]); + + for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) { + switch (attributes[i]) { + case HWC_DISPLAY_VSYNC_PERIOD: + values[i] = ctx->dpyAttr[disp].vsync_period; + break; + case HWC_DISPLAY_WIDTH: + values[i] = ctx->dpyAttr[disp].xres; + ALOGD("%s width = %d",__FUNCTION__, ctx->dpyAttr[disp].xres); + break; + case HWC_DISPLAY_HEIGHT: + values[i] = ctx->dpyAttr[disp].yres; + ALOGD("%s height = %d",__FUNCTION__, ctx->dpyAttr[disp].yres); + break; + case HWC_DISPLAY_DPI_X: + values[i] = ctx->dpyAttr[disp].xdpi; + break; + case HWC_DISPLAY_DPI_Y: + values[i] = ctx->dpyAttr[disp].ydpi; + break; + default: + ALOGE("Unknown display attribute %d", + attributes[i]); + return -EINVAL; + } + } + return 0; +} + static int hwc_device_close(struct hw_device_t *dev) { if(!dev) { @@ -261,17 +364,20 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name, initContext(dev); //Setup HWC methods - dev->device.common.tag = HARDWARE_DEVICE_TAG; - dev->device.common.version = HWC_DEVICE_API_VERSION_1_0; - dev->device.common.module = const_cast<hw_module_t*>(module); - dev->device.common.close = hwc_device_close; - dev->device.prepare = hwc_prepare; - dev->device.set = hwc_set; - dev->device.eventControl = hwc_eventControl; - dev->device.blank = hwc_blank; - dev->device.query = hwc_query; - dev->device.registerProcs = hwc_registerProcs; - *device = &dev->device.common; + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = HWC_DEVICE_API_VERSION_1_1; + dev->device.common.module = const_cast<hw_module_t*>(module); + dev->device.common.close = hwc_device_close; + dev->device.prepare = hwc_prepare; + dev->device.set = hwc_set; + dev->device.eventControl = hwc_eventControl; + dev->device.blank = hwc_blank; + dev->device.query = hwc_query; + dev->device.registerProcs = hwc_registerProcs; + dev->device.dump = NULL; + dev->device.getDisplayConfigs = hwc_getDisplayConfigs; + dev->device.getDisplayAttributes = hwc_getDisplayAttributes; + *device = &dev->device.common; status = 0; } return status; diff --git a/libhwcomposer/hwc_extonly.cpp b/libhwcomposer/hwc_extonly.cpp index bc8bfe058..3be9d81d2 100644 --- a/libhwcomposer/hwc_extonly.cpp +++ b/libhwcomposer/hwc_extonly.cpp @@ -17,7 +17,6 @@ #include "hwc_extonly.h" #include "external.h" -#include "hwc_qbuf.h" namespace qhwc { @@ -130,8 +129,6 @@ bool ExtOnly::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) private_handle_t *hnd = (private_handle_t *) list->hwLayers[sExtIndex].handle; - // Lock this buffer for read. - ctx->qbuf->lockAndAdd(hnd); bool ret = true; overlay::Overlay& ov = *(ctx->mOverlay); ovutils::eOverlayState state = ov.getState(); diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp index 146b6f268..6d407411e 100644 --- a/libhwcomposer/hwc_mdpcomp.cpp +++ b/libhwcomposer/hwc_mdpcomp.cpp @@ -17,7 +17,6 @@ */ #include "hwc_mdpcomp.h" -#include "hwc_qbuf.h" #include "external.h" #define SUPPORT_4LAYER 0 @@ -332,23 +331,16 @@ int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer, * 5. Overlay in use */ -bool MDPComp::is_doable(hwc_composer_device_1_t *dev, - hwc_display_contents_1_t* list) { - hwc_context_t* ctx = (hwc_context_t*)(dev); - - if(!ctx) { - ALOGE("%s: hwc context is NULL", __FUNCTION__); - return false; - } - +bool MDPComp::is_doable(hwc_context_t *ctx, hwc_display_contents_1_t* list) { //Number of layers - if(list->numHwLayers < 1 || list->numHwLayers > (uint32_t)sMaxLayers) { + int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; + if(numAppLayers < 1 || numAppLayers > (uint32_t)sMaxLayers) { ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__); return false; } //Disable MDPComp when ext display connected - if(ctx->mExtDisplay->getExternalDisplay()) { + if(isExternalActive(ctx)) { ALOGD_IF(isDebug(), "%s: External display connected.", __FUNCTION__); return false; } @@ -360,7 +352,7 @@ bool MDPComp::is_doable(hwc_composer_device_1_t *dev, } //MDP composition is not efficient if rotation is needed. - for(unsigned int i = 0; i < list->numHwLayers; ++i) { + for(int i = 0; i < numAppLayers; ++i) { if(list->hwLayers[i].transform) { ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__); return false; @@ -410,10 +402,11 @@ void MDPComp::get_layer_info(hwc_layer_1_t* layer, int& flags) { } } -int MDPComp::mark_layers(hwc_display_contents_1_t* list, layer_mdp_info* layer_info, - frame_info& current_frame) { +int MDPComp::mark_layers(hwc_context_t *ctx, + hwc_display_contents_1_t* list, layer_mdp_info* layer_info, + frame_info& current_frame) { - int layer_count = list->numHwLayers; + int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; if(layer_count > sMaxLayers) { if(!sPipeMgr.req_for_pipe(PIPE_REQ_FB)) { @@ -476,10 +469,11 @@ void MDPComp::reset_layer_mdp_info(layer_mdp_info* layer_info, int count) { } } -bool MDPComp::alloc_layer_pipes(hwc_display_contents_1_t* list, - layer_mdp_info* layer_info, frame_info& current_frame) { +bool MDPComp::alloc_layer_pipes(hwc_context_t *ctx, + hwc_display_contents_1_t* list, + layer_mdp_info* layer_info, frame_info& current_frame) { - int layer_count = list->numHwLayers; + int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; int mdp_count = current_frame.count; int fallback_count = layer_count - mdp_count; int frame_pipe_count = 0; @@ -518,10 +512,10 @@ bool MDPComp::alloc_layer_pipes(hwc_display_contents_1_t* list, } //returns array of layers and their allocated pipes -bool MDPComp::parse_and_allocate(hwc_context_t* ctx, hwc_display_contents_1_t* list, - frame_info& current_frame ) { +bool MDPComp::parse_and_allocate(hwc_context_t* ctx, + hwc_display_contents_1_t* list, frame_info& current_frame ) { - int layer_count = list->numHwLayers; + int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; /* clear pipe status */ sPipeMgr.reset(); @@ -532,7 +526,7 @@ bool MDPComp::parse_and_allocate(hwc_context_t* ctx, hwc_display_contents_1_t* l reset_layer_mdp_info(bp_layer_info, layer_count); /* iterate through layer list to mark candidate */ - if(mark_layers(list, bp_layer_info, current_frame) == MDPCOMP_ABORT) { + if(mark_layers(ctx, list, bp_layer_info, current_frame) == MDPCOMP_ABORT) { free(bp_layer_info); current_frame.count = 0; ALOGE_IF(isDebug(), "%s:mark_layers failed!!", __FUNCTION__); @@ -542,7 +536,7 @@ bool MDPComp::parse_and_allocate(hwc_context_t* ctx, hwc_display_contents_1_t* l malloc(sizeof(pipe_layer_pair) * current_frame.count); /* allocate MDP pipes for marked layers */ - alloc_layer_pipes( list, bp_layer_info, current_frame); + alloc_layer_pipes(ctx, list, bp_layer_info, current_frame); free(bp_layer_info); return true; @@ -586,7 +580,7 @@ int MDPComp::configure_var_pipe(hwc_context_t* ctx) { bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) { int nPipeIndex, vsync_wait, isFG; - int numHwLayers = list->numHwLayers; + int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; frame_info ¤t_frame = sCurrentFrame; current_frame.count = 0; @@ -649,9 +643,6 @@ bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) { void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx, hwc_display_contents_1_t* list) { - if (!list) - return; - for (int index = 0 ; index < sCurrentFrame.count; index++) { int l_index = sCurrentFrame.pipe_layer[index].layer_index; if(list->hwLayers[l_index].flags & HWC_MDPCOMP) { @@ -678,7 +669,8 @@ int MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { overlay::Overlay& ov = *(ctx->mOverlay); - for(unsigned int i = 0; i < list->numHwLayers; i++ ) + int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; + for(int i = 0; i < numHwLayers; i++ ) { hwc_layer_1_t *layer = &list->hwLayers[i]; @@ -719,10 +711,6 @@ int MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { return -1; } - //lock buffer before queue - //XXX: Handle lock failure - ctx->qbuf->lockAndAdd(hnd); - ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ using pipe: %d", __FUNCTION__, layer, hnd, index ); @@ -793,17 +781,15 @@ bool MDPComp::init(hwc_context_t *dev) { return true; } -bool MDPComp::configure(hwc_composer_device_1_t *dev, hwc_display_contents_1_t* list) { +bool MDPComp::configure(hwc_context_t *ctx, hwc_display_contents_1_t* list) { if(!isEnabled()) { ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__); return false; } - hwc_context_t* ctx = (hwc_context_t*)(dev); - bool isMDPCompUsed = true; - bool doable = is_doable(dev, list); + bool doable = is_doable(ctx, list); if(doable) { if(setup(ctx, list)) { diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h index 53c85da2d..7fd6cee75 100644 --- a/libhwcomposer/hwc_mdpcomp.h +++ b/libhwcomposer/hwc_mdpcomp.h @@ -154,7 +154,7 @@ public: static bool deinit(); /*sets up mdp comp for the current frame */ - static bool configure(hwc_composer_device_1_t *ctx, hwc_display_contents_1_t* list); + static bool configure(hwc_context_t *ctx, hwc_display_contents_1_t* list); /* draw */ static int draw(hwc_context_t *ctx, hwc_display_contents_1_t *list); @@ -180,8 +180,7 @@ private: mdp_pipe_info& mdp_info); /* checks for conditions where mdpcomp is not possible */ - static bool is_doable(hwc_composer_device_1_t *dev, - hwc_display_contents_1_t* list); + static bool is_doable(hwc_context_t *ctx, hwc_display_contents_1_t* list); static bool setup(hwc_context_t* ctx, hwc_display_contents_1_t* list); @@ -189,8 +188,9 @@ private: static void get_layer_info(hwc_layer_1_t* layer, int& flags); /* iterates through layer list to choose candidate to use overlay */ - static int mark_layers(hwc_display_contents_1_t* list, layer_mdp_info* layer_info, - frame_info& current_frame); + static int mark_layers(hwc_context_t *ctx, hwc_display_contents_1_t* list, + layer_mdp_info* layer_info, frame_info& current_frame); + static bool parse_and_allocate(hwc_context_t* ctx, hwc_display_contents_1_t* list, frame_info& current_frame ); @@ -198,9 +198,10 @@ private: static void reset_layer_mdp_info(layer_mdp_info* layer_mdp_info,int count); /* allocates pipes to selected candidates */ - static bool alloc_layer_pipes(hwc_display_contents_1_t* list, - layer_mdp_info* layer_info, - frame_info& current_frame); + static bool alloc_layer_pipes(hwc_context_t *ctx, + hwc_display_contents_1_t* list, + layer_mdp_info* layer_info, + frame_info& current_frame); /* updates variable pipe mode for the current frame */ static int configure_var_pipe(hwc_context_t* ctx); diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp index 3c1707b21..3df0e253a 100644 --- a/libhwcomposer/hwc_uevents.cpp +++ b/libhwcomposer/hwc_uevents.cpp @@ -38,26 +38,30 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len) char* hdmi; int64_t timestamp = 0; const char *str = udata; - int hdmiconnected = ctx->mExtDisplay->getExternalDisplay(); + int display = HWC_DISPLAY_PRIMARY; if(!strcasestr(str, "@/devices/virtual/graphics/fb")) { ALOGD_IF(UEVENT_DEBUG, "%s: Not Ext Disp Event ", __FUNCTION__); return; } - if(hdmiconnected) + //Check if its primary vsync + vsync = !strncmp(str, MSMFB_DEVICE_FB0, strlen(MSMFB_DEVICE_FB0)); + //If not primary vsync, see if its an external vsync + if(isExternalActive(ctx) && !vsync) { vsync = !strncmp(str, MSMFB_DEVICE_FB1, strlen(MSMFB_DEVICE_FB1)); - else - vsync = !strncmp(str, MSMFB_DEVICE_FB0, strlen(MSMFB_DEVICE_FB0)); + display = HWC_DISPLAY_EXTERNAL; + } hdmi = strcasestr(str, MSMFB_HDMI_NODE); + if(vsync) { str += strlen(str) + 1; while(*str) { if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) { timestamp = strtoull(str + strlen("VSYNC="), NULL, 0); //XXX: Handle vsync from multiple displays - ctx->proc->vsync(ctx->proc, (int)ctx->dpys[0], timestamp); + ctx->proc->vsync(ctx->proc, display, timestamp); } str += strlen(str) + 1; if(str - udata >= len) diff --git a/libhwcomposer/hwc_uimirror.cpp b/libhwcomposer/hwc_uimirror.cpp index f904d6950..1b81421b3 100644 --- a/libhwcomposer/hwc_uimirror.cpp +++ b/libhwcomposer/hwc_uimirror.cpp @@ -60,25 +60,25 @@ void UIMirrorOverlay::reset() { } //Prepare the overlay for the UI mirroring -bool UIMirrorOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) { +bool UIMirrorOverlay::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) { sState = ovutils::OV_CLOSED; sIsUiMirroringOn = false; if(!ctx->mMDP.hasOverlay) { - ALOGD_IF(HWC_UI_MIRROR, "%s, this hw doesnt support mirroring", - __FUNCTION__); + ALOGD_IF(HWC_UI_MIRROR, "%s, this hw doesnt support mirroring", + __FUNCTION__); return false; } - // If external display is connected - if(ctx->mExtDisplay->getExternalDisplay()) { + // If external display is active + if(isExternalActive(ctx)) { sState = ovutils::OV_UI_MIRROR; - configure(ctx, list); + configure(ctx, fblayer); } return sIsUiMirroringOn; } // Configure -bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_display_contents_1_t *list) +bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_1_t *layer) { if (LIKELY(ctx->mOverlay)) { overlay::Overlay& ov = *(ctx->mOverlay); @@ -86,14 +86,8 @@ bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_display_contents_1_t *li ov.setState(sState); framebuffer_device_t *fbDev = ctx->mFbDev; if(fbDev) { - private_module_t* m = reinterpret_cast<private_module_t*>( - fbDev->common.module); - int alignedW = ALIGN_TO(m->info.xres, 32); - - private_handle_t const* hnd = - reinterpret_cast<private_handle_t const*>(m->framebuffer); - unsigned int size = hnd->size/m->numBuffers; - ovutils::Whf info(alignedW, hnd->height, hnd->format, size); + private_handle_t *hnd = (private_handle_t *)layer->handle; + ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); // Determine the RGB pipe for UI depending on the state ovutils::eDest dest = ovutils::OV_PIPE_ALL; if (sState == ovutils::OV_2D_TRUE_UI_MIRROR) { @@ -118,21 +112,26 @@ bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_display_contents_1_t *li ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; ov.setSource(pargs, dest); + hwc_rect_t sourceCrop = layer->sourceCrop; // x,y,w,h - ovutils::Dim dcrop(0, 0, m->info.xres, m->info.yres); + ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, + sourceCrop.right - sourceCrop.left, + sourceCrop.bottom - sourceCrop.top); ov.setCrop(dcrop, dest); + //Get the current orientation on primary panel int transform = getDeviceOrientation(); ovutils::eTransform orient = static_cast<ovutils::eTransform>(transform); ov.setTransform(orient, dest); - ovutils::Dim dim; - dim.x = 0; - dim.y = 0; - dim.w = m->info.xres; - dim.h = m->info.yres; - ov.setPosition(dim, dest); + hwc_rect_t displayFrame = layer->displayFrame; + ovutils::Dim dpos(displayFrame.left, + displayFrame.top, + displayFrame.right - displayFrame.left, + displayFrame.bottom - displayFrame.top); + ov.setPosition(dpos, dest); + if (!ov.commit(dest)) { ALOGE("%s: commit fails", __FUNCTION__); return false; @@ -143,7 +142,7 @@ bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_display_contents_1_t *li return sIsUiMirroringOn; } -bool UIMirrorOverlay::draw(hwc_context_t *ctx) +bool UIMirrorOverlay::draw(hwc_context_t *ctx, hwc_layer_1_t *layer) { if(!sIsUiMirroringOn) { return true; @@ -156,17 +155,21 @@ bool UIMirrorOverlay::draw(hwc_context_t *ctx) if(fbDev) { private_module_t* m = reinterpret_cast<private_module_t*>( fbDev->common.module); + private_handle_t *hnd = (private_handle_t *)layer->handle; switch (state) { case ovutils::OV_UI_MIRROR: - if (!ov.queueBuffer(m->framebuffer->fd, m->currentOffset, - ovutils::OV_PIPE0)) { + //TODO why is this primary fd + if (!ov.queueBuffer(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd, + hnd->offset, //div by line_length like in PAN? + ovutils::OV_PIPE0)) { ALOGE("%s: queueBuffer failed for external", __FUNCTION__); ret = false; } break; case ovutils::OV_2D_TRUE_UI_MIRROR: - if (!ov.queueBuffer(m->framebuffer->fd, m->currentOffset, - ovutils::OV_PIPE2)) { + if (!ov.queueBuffer(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd, + hnd->offset, + ovutils::OV_PIPE2)) { ALOGE("%s: queueBuffer failed for external", __FUNCTION__); ret = false; } diff --git a/libhwcomposer/hwc_uimirror.h b/libhwcomposer/hwc_uimirror.h index a1bf9ba54..c164d424f 100644 --- a/libhwcomposer/hwc_uimirror.h +++ b/libhwcomposer/hwc_uimirror.h @@ -30,14 +30,14 @@ namespace qhwc { class UIMirrorOverlay { public: // Sets up members and prepares overlay if conditions are met - static bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list); + static bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer); // Draws layer if this feature is on - static bool draw(hwc_context_t *ctx); + static bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer); //Reset values static void reset(); private: //Configures overlay - static bool configure(hwc_context_t *ctx, hwc_display_contents_1_t *list); + static bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer); //The chosen overlay state. static ovutils::eOverlayState sState; //Flags if this feature is on. diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp index b95772149..a4c7e3c82 100644 --- a/libhwcomposer/hwc_utils.cpp +++ b/libhwcomposer/hwc_utils.cpp @@ -23,11 +23,8 @@ #include "hwc_utils.h" #include "mdp_version.h" #include "hwc_video.h" -#include "hwc_qbuf.h" -#include "hwc_copybit.h" #include "external.h" #include "hwc_mdpcomp.h" -#include "hwc_extonly.h" #include "QService.h" namespace qhwc { @@ -38,6 +35,16 @@ static void openFramebufferDevice(hwc_context_t *ctx) hw_module_t const *module; if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { framebuffer_open(module, &(ctx->mFbDev)); + private_module_t* m = reinterpret_cast<private_module_t*>( + ctx->mFbDev->common.module); + //xres, yres may not be 32 aligned + ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = m->info.xres; + ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = m->info.yres; + ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = ctx->mFbDev->xdpi; + ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ctx->mFbDev->ydpi; + ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period = + 1000000000l / ctx->mFbDev->fps; + ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = openFb(HWC_DISPLAY_PRIMARY); } } @@ -46,12 +53,10 @@ void initContext(hwc_context_t *ctx) openFramebufferDevice(ctx); ctx->mOverlay = overlay::Overlay::getInstance(); ctx->mQService = qService::QService::getInstance(ctx); - ctx->qbuf = new QueuedBufferStore(); ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion(); ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay(); ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType(); ctx->mExtDisplay = new ExternalDisplay(ctx); - memset(ctx->dpys,(int)EGL_NO_DISPLAY, MAX_NUM_DISPLAYS); MDPComp::init(ctx); ALOGI("Initializing Qualcomm Hardware Composer"); @@ -65,19 +70,11 @@ void closeContext(hwc_context_t *ctx) ctx->mOverlay = NULL; } - if(ctx->mCopybitEngine) { - delete ctx->mCopybitEngine; - ctx->mCopybitEngine = NULL; - } - if(ctx->mFbDev) { framebuffer_close(ctx->mFbDev); ctx->mFbDev = NULL; - } - - if(ctx->qbuf) { - delete ctx->qbuf; - ctx->qbuf = NULL; + close(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd); + ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1; } if(ctx->mExtDisplay) { @@ -101,56 +98,28 @@ void dumpLayer(hwc_layer_1_t const* l) l->displayFrame.bottom); } -void getLayerStats(hwc_context_t *ctx, const hwc_display_contents_1_t *list) -{ - //Video specific stats - int yuvCount = 0; - int yuvLayerIndex = -1; - bool isYuvLayerSkip = false; - int skipCount = 0; - int ccLayerIndex = -1; //closed caption - int extLayerIndex = -1; //ext-only or block except closed caption - int extCount = 0; //ext-only except closed caption - bool isExtBlockPresent = false; //is BLOCK layer present - bool yuvSecure = false; +void setListStats(hwc_context_t *ctx, + const hwc_display_contents_1_t *list, int dpy) { + + ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1; + ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1; for (size_t i = 0; i < list->numHwLayers; i++) { private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle; - if (UNLIKELY(isYuvBuffer(hnd))) { - yuvCount++; - yuvLayerIndex = i; - yuvSecure = isSecureBuffer(hnd); - //Animating - //Do not mark as SKIP if it is secure buffer - if (isSkipLayer(&list->hwLayers[i]) && !yuvSecure) { - isYuvLayerSkip = true; - skipCount++; - } - } else if(UNLIKELY(isExtCC(hnd))) { - ccLayerIndex = i; - } else if(UNLIKELY(isExtBlock(hnd))) { - extCount++; - extLayerIndex = i; - isExtBlockPresent = true; - } else if(UNLIKELY(isExtOnly(hnd))) { - extCount++; - //If BLOCK layer present, dont cache index, display BLOCK only. - if(isExtBlockPresent == false) extLayerIndex = i; + if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { + continue; + //We disregard FB being skip for now! so the else if } else if (isSkipLayer(&list->hwLayers[i])) { - skipCount++; + ctx->listStats[dpy].skipCount++; } - } - - VideoOverlay::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip, - ccLayerIndex); - ExtOnly::setStats(extCount, extLayerIndex, isExtBlockPresent); - CopyBit::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip); - MDPComp::setStats(skipCount); - ctx->numHwLayers = list->numHwLayers; - return; + if (UNLIKELY(isYuvBuffer(hnd))) { + ctx->listStats[dpy].yuvCount++; + ctx->listStats[dpy].yuvIndex = i; + } + } } //Crops source buffer against destination and FB boundaries @@ -209,41 +178,15 @@ void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst, } } -void wait4fbPost(hwc_context_t* ctx) { - framebuffer_device_t *fbDev = ctx->mFbDev; - if(fbDev) { - private_module_t* m = reinterpret_cast<private_module_t*>( - fbDev->common.module); - //wait for the fb_post to be called - pthread_mutex_lock(&m->fbPostLock); - while(m->fbPostDone == false) { - pthread_cond_wait(&(m->fbPostCond), &(m->fbPostLock)); - } - m->fbPostDone = false; - pthread_mutex_unlock(&m->fbPostLock); - } -} - -void wait4Pan(hwc_context_t* ctx) { - framebuffer_device_t *fbDev = ctx->mFbDev; - if(fbDev) { - private_module_t* m = reinterpret_cast<private_module_t*>( - fbDev->common.module); - //wait for the fb_post's PAN to finish - pthread_mutex_lock(&m->fbPanLock); - while(m->fbPanDone == false) { - pthread_cond_wait(&(m->fbPanCond), &(m->fbPanLock)); - } - m->fbPanDone = false; - pthread_mutex_unlock(&m->fbPanLock); - } +bool isExternalActive(hwc_context_t* ctx) { + return ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive; } -int hwc_sync(hwc_display_contents_1_t* list) { +int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy) { int ret = 0; #ifdef USE_FENCE_SYNC struct mdp_buf_sync data; - int acquireFd[10]; + int acquireFd[4]; int count = 0; int releaseFd = -1; int fbFd = -1; @@ -252,7 +195,8 @@ int hwc_sync(hwc_display_contents_1_t* list) { data.rel_fen_fd = &releaseFd; //Accumulate acquireFenceFds for(uint32_t i = 0; i < list->numHwLayers; i++) { - if(list->hwLayers[i].compositionType == HWC_OVERLAY && + if((list->hwLayers[i].compositionType == HWC_OVERLAY || + list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) && list->hwLayers[i].acquireFenceFd != -1) { acquireFd[count++] = list->hwLayers[i].acquireFenceFd; } @@ -260,13 +204,7 @@ int hwc_sync(hwc_display_contents_1_t* list) { if (count) { data.acq_fen_fd_cnt = count; - - //Open fb0 for ioctl - fbFd = open("/dev/graphics/fb0", O_RDWR); - if (fbFd < 0) { - ALOGE("%s: /dev/graphics/fb0 not available", __FUNCTION__); - return -1; - } + fbFd = ctx->dpyAttr[dpy].fd; //Waits for acquire fences, returns a release fence ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data); @@ -274,22 +212,20 @@ int hwc_sync(hwc_display_contents_1_t* list) { ALOGE("ioctl MSMFB_BUFFER_SYNC failed, err=%s", strerror(errno)); } - close(fbFd); for(uint32_t i = 0; i < list->numHwLayers; i++) { - if(list->hwLayers[i].compositionType == HWC_OVERLAY) { + if((list->hwLayers[i].compositionType == HWC_OVERLAY || + list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET)) { //Close the acquireFenceFds if(list->hwLayers[i].acquireFenceFd > 0) { close(list->hwLayers[i].acquireFenceFd); list->hwLayers[i].acquireFenceFd = -1; } //Populate releaseFenceFds. - if (releaseFd != -1) - list->hwLayers[i].releaseFenceFd = dup(releaseFd); + list->hwLayers[i].releaseFenceFd = dup(releaseFd); } } - if (releaseFd != -1) - close(releaseFd); + list->retireFenceFd = releaseFd; } #endif return ret; diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h index 1153cc782..1b1d4d653 100644 --- a/libhwcomposer/hwc_utils.h +++ b/libhwcomposer/hwc_utils.h @@ -19,6 +19,7 @@ #define HWC_UTILS_H #define HWC_REMOVE_DEPRECATED_VERSIONS 1 +#include <fcntl.h> #include <hardware/hwcomposer.h> #include <gralloc_priv.h> @@ -44,7 +45,6 @@ namespace qhwc { //fwrd decl class QueuedBufferStore; class ExternalDisplay; -class CopybitEngine; struct MDPInfo { int version; @@ -52,16 +52,23 @@ struct MDPInfo { bool hasOverlay; }; -enum external_display_type { - EXT_TYPE_NONE, - EXT_TYPE_HDMI, - EXT_TYPE_WIFI +struct DisplayAttributes { + uint32_t vsync_period; //nanos + uint32_t xres; + uint32_t yres; + uint32_t xdpi; + uint32_t ydpi; + int fd; + bool isActive; }; -enum HWCCompositionType { - HWC_USE_GPU = HWC_FRAMEBUFFER, // This layer is to be handled by - // Surfaceflinger - HWC_USE_OVERLAY = HWC_OVERLAY, // This layer is to be handled by the overlay - HWC_USE_COPYBIT // This layer is to be handled by copybit + +struct ListStats { + int numAppLayers; //Total - 1, excluding FB layer. + int skipCount; + int fbLayerIndex; //Always last for now. = numAppLayers + //Video specific + int yuvCount; + int yuvIndex; }; enum { @@ -74,21 +81,18 @@ enum { // ----------------------------------------------------------------------------- // Utility functions - implemented in hwc_utils.cpp void dumpLayer(hwc_layer_1_t const* l); -void getLayerStats(hwc_context_t *ctx, const hwc_display_contents_1_t *list); +void setListStats(hwc_context_t *ctx, const hwc_display_contents_1_t *list, + int dpy); void initContext(hwc_context_t *ctx); void closeContext(hwc_context_t *ctx); //Crops source buffer against destination and FB boundaries void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst, const int fbWidth, const int fbHeight); -// Waits for the fb_post to be called -void wait4fbPost(hwc_context_t* ctx); - -// Waits for the fb_post to finish PAN (primary commit) -void wait4Pan(hwc_context_t* ctx); +bool isExternalActive(hwc_context_t* ctx); //Sync point impl. -int hwc_sync(hwc_display_contents_1_t* list); +int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy); // Inline utility functions static inline bool isSkipLayer(const hwc_layer_1_t* l) { @@ -134,6 +138,16 @@ inline void getLayerResolution(const hwc_layer_1_t* layer, width = displayFrame.right - displayFrame.left; height = displayFrame.bottom - displayFrame.top; } + +static inline int openFb(int dpy) { + int fd = -1; + const char *devtmpl = "/dev/graphics/fb%u"; + char name[64] = {0}; + snprintf(name, 64, devtmpl, dpy); + fd = open(name, O_RDWR); + return fd; +} + }; //qhwc namespace // ----------------------------------------------------------------------------- @@ -144,20 +158,13 @@ struct hwc_context_t { const hwc_procs_t* proc; int numHwLayers; int overlayInUse; - hwc_display_t dpys[MAX_NUM_DISPLAYS]; //Framebuffer device framebuffer_device_t *mFbDev; - //Copybit Engine - qhwc::CopybitEngine* mCopybitEngine; - //Overlay object - NULL for non overlay devices overlay::Overlay *mOverlay; - //QueuedBufferStore to hold buffers for overlay - qhwc::QueuedBufferStore *qbuf; - //QService object qService::QService *mQService; @@ -166,7 +173,9 @@ struct hwc_context_t { qhwc::MDPInfo mMDP; - bool isPoweredDown; + qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES]; + + qhwc::ListStats listStats[HWC_NUM_DISPLAY_TYPES]; //Securing in progress indicator bool mSecuring; diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp index daf3f80df..3aa7e7a18 100644 --- a/libhwcomposer/hwc_video.cpp +++ b/libhwcomposer/hwc_video.cpp @@ -17,9 +17,8 @@ #define VIDEO_DEBUG 0 #include <overlay.h> -#include "hwc_qbuf.h" #include "hwc_video.h" -#include "external.h" +#include "hwc_utils.h" namespace qhwc { @@ -27,88 +26,81 @@ namespace qhwc { //Static Members ovutils::eOverlayState VideoOverlay::sState = ovutils::OV_CLOSED; -int VideoOverlay::sYuvCount = 0; -int VideoOverlay::sYuvLayerIndex = -1; -bool VideoOverlay::sIsYuvLayerSkip = false; -int VideoOverlay::sCCLayerIndex = -1; bool VideoOverlay::sIsModeOn = false; //Cache stats, figure out the state, config overlay -bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) { - sIsModeOn = false; +bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list, + int dpy) { + int yuvIndex = ctx->listStats[dpy].yuvIndex; + if(!ctx->mMDP.hasOverlay) { ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__); return false; } - if(sYuvLayerIndex == -1) { + if(yuvIndex == -1) { return false; } - chooseState(ctx); - //if the state chosen above is CLOSED, skip this block. - if(sState != ovutils::OV_CLOSED) { - hwc_layer_1_t *yuvLayer = &list->hwLayers[sYuvLayerIndex]; - hwc_layer_1_t *ccLayer = NULL; - if(sCCLayerIndex != -1) - ccLayer = &list->hwLayers[sCCLayerIndex]; - - if(configure(ctx, yuvLayer, ccLayer)) { - markFlags(yuvLayer, ccLayer); - sIsModeOn = true; - } - } - ALOGD_IF(VIDEO_DEBUG, "%s: stats: yuvCount = %d, yuvIndex = %d," - "IsYuvLayerSkip = %d, ccLayerIndex = %d, IsModeOn = %d", - __FUNCTION__, sYuvCount, sYuvLayerIndex, - sIsYuvLayerSkip, sCCLayerIndex, sIsModeOn); + //index guaranteed to be not -1 at this point + hwc_layer_1_t *yuvLayer = &list->hwLayers[yuvIndex]; + chooseState(ctx, dpy, yuvLayer); + if(configure(ctx, dpy, yuvLayer)) { + markFlags(yuvLayer); + sIsModeOn = true; + } return sIsModeOn; } -void VideoOverlay::chooseState(hwc_context_t *ctx) { +void VideoOverlay::chooseState(hwc_context_t *ctx, int dpy, + hwc_layer_1_t *yuvLayer) { ALOGD_IF(VIDEO_DEBUG, "%s: old state = %s", __FUNCTION__, ovutils::getStateString(sState)); + private_handle_t *hnd = NULL; + if(yuvLayer) { + hnd = (private_handle_t *)yuvLayer->handle; + } ovutils::eOverlayState newState = ovutils::OV_CLOSED; - - //Support 1 video layer - if(sYuvCount == 1) { - //Skip on primary, display on ext. - if(sIsYuvLayerSkip && ctx->mExtDisplay->getExternalDisplay()) { - newState = ovutils::OV_2D_VIDEO_ON_TV; - } else if(sIsYuvLayerSkip) { //skip on primary, no ext - newState = ovutils::OV_CLOSED; - } else if(ctx->mExtDisplay->getExternalDisplay()) { - //display on both - newState = ovutils::OV_2D_VIDEO_ON_PANEL_TV; - } else { //display on primary only - newState = ovutils::OV_2D_VIDEO_ON_PANEL; - } + switch(dpy) { + case HWC_DISPLAY_PRIMARY: + if(ctx->listStats[dpy].yuvCount == 1) { + newState = ovutils::OV_2D_VIDEO_ON_PANEL; + if(isSkipLayer(yuvLayer) && !isSecureBuffer(hnd)) { + newState = ovutils::OV_CLOSED; + } + } + break; + case HWC_DISPLAY_EXTERNAL: + //TODO needs overlay state change for UI also + newState = sState; //Previously set by HWC_DISPLAY_PRIMARY + /*if(ctx->listStats[dpy].yuvCount == 1 && isExternalActive(ctx)) { + if(!isSkipLayer(yuvLayer) || isSecureBuffer(hnd)) { + switch(sState) { //set by primary chooseState + case ovutils::OV_2D_VIDEO_ON_PANEL: + //upgrade + sState = ovutils::OV_2D_VIDEO_PANEL_TV; + break; + case ovutils::OV_CLOSED: + sState = ovutils::OV_2D_VIDEO_ON_TV; + break; + } + } + }*/ + break; + default: + break; } + sState = newState; ALOGD_IF(VIDEO_DEBUG, "%s: new chosen state = %s", __FUNCTION__, ovutils::getStateString(sState)); } -void VideoOverlay::markFlags(hwc_layer_1_t *yuvLayer, hwc_layer_1_t *ccLayer) { - switch(sState) { - case ovutils::OV_2D_VIDEO_ON_PANEL: - case ovutils::OV_2D_VIDEO_ON_PANEL_TV: - if(yuvLayer) { - yuvLayer->compositionType = HWC_OVERLAY; - yuvLayer->hints |= HWC_HINT_CLEAR_FB; - } - if(ccLayer) { - ccLayer->compositionType = HWC_OVERLAY; - } - break; - case ovutils::OV_2D_VIDEO_ON_TV: - if(ccLayer) { - ccLayer->compositionType = HWC_OVERLAY; - } - break; //dont update video layer flags. - default: - break; +void VideoOverlay::markFlags(hwc_layer_1_t *yuvLayer) { + if(yuvLayer) { + yuvLayer->compositionType = HWC_OVERLAY; + yuvLayer->hints |= HWC_HINT_CLEAR_FB; } } @@ -119,7 +111,7 @@ bool configPrimVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; - if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { + if (isSecureBuffer(hnd)) { ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION); } @@ -161,7 +153,7 @@ bool configPrimVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { //Only for Primary ov.setCrop(dcrop, ovutils::OV_PIPE0); - int transform = layer->transform & FINAL_TRANSFORM_MASK; + int transform = layer->transform; ovutils::eTransform orient = static_cast<ovutils::eTransform>(transform); ov.setTransform(orient, ovutils::OV_PIPE0); @@ -186,7 +178,7 @@ bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; - if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { + if (isSecureBuffer(hnd)) { ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION); } @@ -233,144 +225,83 @@ bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { return true; } -bool configExtCC(hwc_context_t *ctx, hwc_layer_1_t *layer) { - if(layer == NULL) - return true; - - overlay::Overlay& ov = *(ctx->mOverlay); - private_handle_t *hnd = (private_handle_t *)layer->handle; - ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); - ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF; - ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; - ovutils::PipeArgs parg(mdpFlags, - info, - ovutils::ZORDER_1, - isFgFlag, - ovutils::ROT_FLAG_DISABLED); - ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; - ov.setSource(pargs, ovutils::OV_PIPE2); - - hwc_rect_t sourceCrop = layer->sourceCrop; - // x,y,w,h - ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, - sourceCrop.right - sourceCrop.left, - sourceCrop.bottom - sourceCrop.top); - //Only for External - ov.setCrop(dcrop, ovutils::OV_PIPE2); - - // FIXME: Use source orientation for TV when source is portrait - //Only for External - ov.setTransform(0, ovutils::OV_PIPE2); - - //Setting position same as crop - //FIXME stretch to full screen - ov.setPosition(dcrop, ovutils::OV_PIPE2); - - if (!ov.commit(ovutils::OV_PIPE2)) { - ALOGE("%s: commit fails", __FUNCTION__); - return false; - } - return true; -} - -bool VideoOverlay::configure(hwc_context_t *ctx, hwc_layer_1_t *yuvLayer, - hwc_layer_1_t *ccLayer) { - +bool VideoOverlay::configure(hwc_context_t *ctx, int dpy, + hwc_layer_1_t *yuvLayer) { bool ret = true; - if (LIKELY(ctx->mOverlay)) { - overlay::Overlay& ov = *(ctx->mOverlay); - // Set overlay state - ov.setState(sState); - switch(sState) { - case ovutils::OV_2D_VIDEO_ON_PANEL: - ret &= configPrimVid(ctx, yuvLayer); - break; - case ovutils::OV_2D_VIDEO_ON_PANEL_TV: - ret &= configExtVid(ctx, yuvLayer); - ret &= configExtCC(ctx, ccLayer); - ret &= configPrimVid(ctx, yuvLayer); - break; - case ovutils::OV_2D_VIDEO_ON_TV: - ret &= configExtVid(ctx, yuvLayer); - ret &= configExtCC(ctx, ccLayer); - break; - default: - return false; - } - } else { - //Ov null - return false; + overlay::Overlay& ov = *(ctx->mOverlay); + switch(dpy) { + case HWC_DISPLAY_PRIMARY: + // Set overlay state + ov.setState(sState); + switch(sState) { + case ovutils::OV_2D_VIDEO_ON_PANEL: + ret &= configPrimVid(ctx, yuvLayer); + break; + default: + return false; + } + break; + case HWC_DISPLAY_EXTERNAL: + ov.setState(sState); + switch(sState) { + case ovutils::OV_2D_VIDEO_ON_PANEL_TV: + case ovutils::OV_2D_VIDEO_ON_TV: + ret = configExtVid(ctx, yuvLayer); + break; + default: + return false; + } + break; } return ret; } -bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) +bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, + int dpy) { - if(!sIsModeOn || sYuvLayerIndex == -1) { + int yuvIndex = ctx->listStats[dpy].yuvIndex; + if(!sIsModeOn || yuvIndex == -1) { return true; } private_handle_t *hnd = (private_handle_t *) - list->hwLayers[sYuvLayerIndex].handle; - - private_handle_t *cchnd = NULL; - if(sCCLayerIndex != -1) { - cchnd = (private_handle_t *)list->hwLayers[sCCLayerIndex].handle; - ctx->qbuf->lockAndAdd(cchnd); - } - - // Lock this buffer for read. - ctx->qbuf->lockAndAdd(hnd); + list->hwLayers[yuvIndex].handle; bool ret = true; overlay::Overlay& ov = *(ctx->mOverlay); ovutils::eOverlayState state = ov.getState(); - switch (state) { - case ovutils::OV_2D_VIDEO_ON_PANEL_TV: - // Play external - if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) { - ALOGE("%s: queueBuffer failed for external", __FUNCTION__); - ret = false; - } - //Play CC on external - if (cchnd && !ov.queueBuffer(cchnd->fd, cchnd->offset, - ovutils::OV_PIPE2)) { - ALOGE("%s: queueBuffer failed for cc external", __FUNCTION__); - ret = false; - } - // Play primary - if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) { - ALOGE("%s: queueBuffer failed for primary", __FUNCTION__); - ret = false; - } - break; - case ovutils::OV_2D_VIDEO_ON_PANEL: - // Play primary - if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) { - ALOGE("%s: queueBuffer failed for primary", __FUNCTION__); - ret = false; + switch(dpy) { + case HWC_DISPLAY_PRIMARY: + switch (state) { + case ovutils::OV_2D_VIDEO_ON_PANEL: + // Play primary + if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) { + ALOGE("%s: queueBuffer failed for primary", __FUNCTION__); + ret = false; + } + break; + default: + ret = false; + break; } break; - case ovutils::OV_2D_VIDEO_ON_TV: - // Play external - if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) { - ALOGE("%s: queueBuffer failed for external", __FUNCTION__); - ret = false; + case HWC_DISPLAY_EXTERNAL: + switch(state) { + case ovutils::OV_2D_VIDEO_ON_PANEL_TV: + case ovutils::OV_2D_VIDEO_ON_TV: + // Play external + if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) { + ALOGE("%s: queueBuffer failed for external", __FUNCTION__); + ret = false; + } + break; + default: + ret = false; + break; } - //Play CC on external - if (cchnd && !ov.queueBuffer(cchnd->fd, cchnd->offset, - ovutils::OV_PIPE2)) { - ALOGE("%s: queueBuffer failed for cc external", __FUNCTION__); - ret = false; - } - break; - default: - ALOGE("%s Unused state %s", __FUNCTION__, - ovutils::getStateString(state)); break; } - return ret; } diff --git a/libhwcomposer/hwc_video.h b/libhwcomposer/hwc_video.h index ec8fa21c0..f5a970987 100644 --- a/libhwcomposer/hwc_video.h +++ b/libhwcomposer/hwc_video.h @@ -26,53 +26,29 @@ namespace qhwc { class VideoOverlay { public: //Sets up members and prepares overlay if conditions are met - static bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list); + static bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list, + int dpy); //Draws layer if this feature is on - static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list); - //Receives data from hwc - static void setStats(int yuvCount, int yuvLayerIndex, bool isYuvLayerSkip, - int ccLayerIndex); + static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, + int dpy); //resets values static void reset(); private: //Choose an appropriate overlay state based on conditions - static void chooseState(hwc_context_t *ctx); + static void chooseState(hwc_context_t *ctx, int dpy, + hwc_layer_1_t *yuvLayer); //Configures overlay for video prim and ext - static bool configure(hwc_context_t *ctx, hwc_layer_1_t *yuvlayer, - hwc_layer_1_t *ccLayer); + static bool configure(hwc_context_t *ctx, int dpy, + hwc_layer_1_t *yuvlayer); //Marks layer flags if this feature is used - static void markFlags(hwc_layer_1_t *yuvLayer, hwc_layer_1_t *ccLayer); - //returns yuv count - static int getYuvCount(); - + static void markFlags(hwc_layer_1_t *yuvLayer); //The chosen overlay state. static ovutils::eOverlayState sState; - //Number of yuv layers in this drawing round - static int sYuvCount; - //Index of YUV layer, relevant only if count is 1 - static int sYuvLayerIndex; - //Flags if a yuv layer is animating or below something that is animating - static bool sIsYuvLayerSkip; - //Holds the closed caption layer index, -1 by default - static int sCCLayerIndex; //Flags if this feature is on. static bool sIsModeOn; }; -inline void VideoOverlay::setStats(int yuvCount, int yuvLayerIndex, - bool isYuvLayerSkip, int ccLayerIndex) { - sYuvCount = yuvCount; - sYuvLayerIndex = yuvLayerIndex; - sIsYuvLayerSkip = isYuvLayerSkip; - sCCLayerIndex = ccLayerIndex; -} - -inline int VideoOverlay::getYuvCount() { return sYuvCount; } inline void VideoOverlay::reset() { - sYuvCount = 0; - sYuvLayerIndex = -1; - sIsYuvLayerSkip = false; - sCCLayerIndex = -1; sIsModeOn = false; sState = ovutils::OV_CLOSED; } |