Merge "sde: resource manager: rotator resource allocation"
diff --git a/common.mk b/common.mk
index cdac0fa..768696a 100644
--- a/common.mk
+++ b/common.mk
@@ -27,15 +27,8 @@
ifeq ($(call is-board-platform-in-list, $(MSM_VIDC_TARGET_LIST)), true)
common_flags += -DVENUS_COLOR_FORMAT
-endif
-
-ifeq ($(call is-board-platform-in-list, msm8974 msm8226 msm8610 apq8084 \
- mpq8092 msm_bronze msm8916 msm8994), true)
common_flags += -DMDSS_TARGET
endif
-ifeq ($(call is-board-platform-in-list, msm8909), true)
- common_flags += -DVENUS_COLOR_FORMAT
-endif
common_deps :=
kernel_includes :=
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
index 3a0f2d0..93bec4d 100644
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -345,7 +345,7 @@
timing_mode->back_porch_v + timing_mode->pulse_width_v;
display_attributes->x_dpi = 0;
display_attributes->y_dpi = 0;
- display_attributes->fps = FLOAT(timing_mode->refresh_rate);
+ display_attributes->fps = FLOAT(timing_mode->refresh_rate) / 1000.0f;
display_attributes->vsync_period_ns = UINT32(1000000000L / display_attributes->fps);
display_attributes->split_left = display_attributes->x_pixels;
if (display_attributes->x_pixels > hw_resource_.max_mixer_width) {
@@ -442,9 +442,28 @@
DisplayError HWFrameBuffer::PowerOff(Handle device) {
HWContext *hw_context = reinterpret_cast<HWContext *>(device);
- if (ioctl_(hw_context->device_fd, FBIOBLANK, FB_BLANK_POWERDOWN) == -1) {
- IOCTL_LOGE(FB_BLANK_POWERDOWN, hw_context->type);
- return kErrorHardware;
+ switch (hw_context->type) {
+ case kDevicePrimary:
+ if (ioctl_(hw_context->device_fd, FBIOBLANK, FB_BLANK_POWERDOWN) == -1) {
+ IOCTL_LOGE(FB_BLANK_POWERDOWN, hw_context->type);
+ return kErrorHardware;
+ }
+ break;
+ case kDeviceHDMI:
+ {
+ hw_context->ResetMDPCommit();
+ mdp_layer_commit_v1 &mdp_commit = hw_context->mdp_commit.commit_v1;
+ mdp_commit.input_layer_cnt = 0;
+ mdp_commit.flags &= ~MDP_VALIDATE_LAYER;
+ if (ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &hw_context->mdp_commit) == -1) {
+ IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, hw_context->type);
+ return kErrorHardware;
+ }
+ }
+ break;
+ case kDeviceVirtual:
+ default:
+ break;
}
return kErrorNone;
@@ -513,6 +532,15 @@
if (error != kErrorNone) {
return error;
}
+
+ if (layer.transform.flip_vertical) {
+ mdp_layer.flags |= MDP_LAYER_FLIP_UD;
+ }
+
+ if (layer.transform.flip_horizontal) {
+ mdp_layer.flags |= MDP_LAYER_FLIP_LR;
+ }
+
mdp_layer_count++;
}
}
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index 7827af2..771c07f 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -369,6 +369,8 @@
return -EINVAL;
}
+ int status = 0;
+
size_t num_hw_layers = content_list->numHwLayers;
if (num_hw_layers <= 1) {
if (!num_hw_layers) {
@@ -401,7 +403,7 @@
DisplayError error = display_intf_->Commit(&layer_stack_);
if (UNLIKELY(error != kErrorNone)) {
DLOGE("Commit failed. Error = %d", error);
- return -EINVAL;
+ status = -EINVAL;
}
for (size_t i = 0; i < num_hw_layers; i++) {
@@ -409,7 +411,8 @@
Layer &layer = layer_stack_.layers[i];
LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
- if (layer.composition == kCompositionSDE || layer.composition == kCompositionGPUTarget) {
+ if ((status == 0) && (layer.composition == kCompositionSDE ||
+ layer.composition == kCompositionGPUTarget)) {
hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
}
@@ -418,7 +421,7 @@
}
}
- return 0;
+ return status;
}
bool HWCDisplay::NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list) {
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index a5bf0b5..7e7b44b 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
* Not a Contribution, Apache license notifications and license are retained
* for attribution purposes only.
*
@@ -19,6 +19,7 @@
#include <math.h>
#include "hwc_mdpcomp.h"
#include <sys/ioctl.h>
+#include <dlfcn.h>
#include "hdmi.h"
#include "qdMetaData.h"
#include "mdp_version.h"
@@ -50,6 +51,12 @@
int MDPComp::sMaxSecLayers = 1;
bool MDPComp::enablePartialUpdateForMDP3 = false;
bool MDPComp::sIsPartialUpdateActive = true;
+void *MDPComp::sLibPerfHint = NULL;
+int MDPComp::sPerfLockHandle = 0;
+int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
+int (*MDPComp::sPerfLockRelease)(int value) = NULL;
+int MDPComp::sPerfHintWindow = -1;
+
MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
sSrcSplitEnabled = true;
@@ -194,6 +201,14 @@
sIsPartialUpdateActive = getPartialUpdatePref(ctx);
+ if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
+ int val = atoi(property);
+ if(val > 0 && loadPerfLib()) {
+ sPerfHintWindow = val;
+ ALOGI("PerfHintWindow = %d", sPerfHintWindow);
+ }
+ }
+
return true;
}
@@ -1325,6 +1340,11 @@
if(!postHeuristicsHandling(ctx, list)) {
ALOGD_IF(isDebug(), "post heuristic handling failed");
+ if(errno == ENOBUFS) {
+ ALOGD_IF(isDebug(), "SMP Allocation failed");
+ //On SMP allocation failure in video only comp add padding round
+ ctx->isPaddingRound = true;
+ }
reset(ctx);
return false;
}
@@ -1372,6 +1392,12 @@
}
}
+ /* Bail out if we dont have any secure RGB layers */
+ if (!ctx->listStats[mDpy].secureRGBCount) {
+ reset(ctx);
+ return false;
+ }
+
mCurrentFrame.reset(numAppLayers);
mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
@@ -1895,25 +1921,38 @@
return true;
}
+// Checks only if videos or single layer(RGB) is updating
+// which is used for setting dynamic fps or perf hint for single
+// layer video playback
+bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list) {
+ bool support = false;
+ FrameInfo frame;
+ frame.reset(mCurrentFrame.layerCount);
+ memset(&frame.drop, 0, sizeof(frame.drop));
+ frame.dropCount = 0;
+ ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
+ updateLayerCache(ctx, list, frame);
+ updateYUV(ctx, list, false /*secure only*/, frame);
+ // There are only updating YUV layers or there is single RGB
+ // Layer(Youtube)
+ if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
+ (frame.layerCount == 1)) {
+ support = true;
+ }
+ return support;
+}
+
void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
//For primary display, set the dynamic refreshrate
if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
ctx->mUseMetaDataRefreshRate) {
- FrameInfo frame;
- frame.reset(mCurrentFrame.layerCount);
- memset(&frame.drop, 0, sizeof(frame.drop));
- frame.dropCount = 0;
- ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
- __FUNCTION__);
- updateLayerCache(ctx, list, frame);
- updateYUV(ctx, list, false /*secure only*/, frame);
uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
MDPVersion& mdpHw = MDPVersion::getInstance();
if(sIdleFallBack) {
//Set minimum panel refresh rate during idle timeout
refreshRate = mdpHw.getMinFpsSupported();
- } else if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
- (frame.layerCount == 1)) {
+ } else if(onlyVideosUpdating(ctx, list)) {
//Set the new fresh rate, if there is only one updating YUV layer
//or there is one single RGB layer with this request
refreshRate = ctx->listStats[mDpy].refreshRateRequest;
@@ -2031,6 +2070,7 @@
#ifdef DYNAMIC_FPS
setDynRefreshRate(ctx, list);
#endif
+ setPerfHint(ctx, list);
mCachedFrame.cacheAll(list);
mCachedFrame.updateCounts(mCurrentFrame);
@@ -2817,5 +2857,66 @@
sIsPartialUpdateActive = enable;
return 0;
}
+
+bool MDPComp::loadPerfLib() {
+ char perfLibPath[PROPERTY_VALUE_MAX] = {0};
+ bool success = false;
+ if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
+ ALOGE("vendor library not set in ro.vendor.extension_library");
+ return false;
+ }
+
+ sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
+ if(sLibPerfHint) {
+ *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
+ *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
+ if (!sPerfLockAcquire || !sPerfLockRelease) {
+ ALOGE("Failed to load symbols for perfLock");
+ dlclose(sLibPerfHint);
+ sLibPerfHint = NULL;
+ return false;
+ }
+ success = true;
+ ALOGI("Successfully Loaded perf hint API's");
+ } else {
+ ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
+ }
+ return success;
+}
+
+void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
+ if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
+ return;
+ }
+ static int count = sPerfHintWindow;
+ static int perflockFlag = 0;
+
+ /* Send hint to mpctl when single layer is updated
+ * for a successful number of windows. Hint release
+ * happens immediately upon multiple layer update.
+ */
+ if (onlyVideosUpdating(ctx, list)) {
+ if(count) {
+ count--;
+ }
+ } else {
+ if (perflockFlag) {
+ perflockFlag = 0;
+ sPerfLockRelease(sPerfLockHandle);
+ }
+ count = sPerfHintWindow;
+ }
+ if (count == 0 && !perflockFlag) {
+ int perfHint = 0x4501; // 45-display layer hint, 01-Enable
+ sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
+ &perfHint, sizeof(perfHint)/sizeof(int));
+ if(sPerfLockHandle < 0) {
+ ALOGE("Perf Lock Acquire Failed");
+ } else {
+ perflockFlag = 1;
+ }
+ }
+}
+
}; //namespace
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 4978182..302b047 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -247,6 +247,10 @@
hwc_display_contents_1_t* list);
/* checks for conditions to enable partial udpate */
bool canPartialUpdate(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+ // Checks if only videocontent is updating
+ bool onlyVideosUpdating(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+ static bool loadPerfLib();
+ void setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list);
int mDpy;
static bool sEnabled;
@@ -269,6 +273,12 @@
bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index);
//Enable Partial Update for MDP3 targets
static bool enablePartialUpdateForMDP3;
+ static void *sLibPerfHint;
+ static int sPerfLockHandle;
+ static int (*sPerfLockAcquire)(int, int, int*, int);
+ static int (*sPerfLockRelease)(int value);
+ static int sPerfHintWindow;
+
};
class MDPCompNonSplit : public MDPComp {
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index b772a6e..dd030ef 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -280,10 +280,11 @@
if(src_w > (int) mdpHw.getMaxPipeWidth()) {
//If the client sends us something > what a layer mixer supports
//then it means it doesn't want to use split-pipe but wants us to
- //decimate. A minimum decimation of 2 will ensure that the width is
+ //decimate. A minimum decimation of 1 will ensure that the width is
//always within layer mixer limits.
- if(horzDeci < 2)
- horzDeci = 2;
+ const uint8_t minDeci = 1;
+ if(horzDeci < minDeci)
+ horzDeci = minDeci;
}
}