hwc: Set GPU performance hint.
1. Set the GPU hint flag to high for MIXED/GPU composition only for
first frame after MDP to GPU/MIXED mode transition.
2. Set the GPU hint to default if the current composition type is GPU
due to idle fallback or MDP composition.
Change-Id: I208a778017435a5a4620142da9d9fb3c50e09155
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 893fee0..bfcfa78 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -212,6 +212,7 @@
if(ctx->mCopyBit[dpy])
ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
}
+ setGPUHint(ctx, list);
}
return 0;
}
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 22b8baf..2d65755 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -53,6 +53,7 @@
static bool init(hwc_context_t *ctx);
static void resetIdleFallBack() { sIdleFallBack = false; }
static void reset() { sHandleTimeout = false; };
+ static bool isIdleFallback() { return sIdleFallBack; }
protected:
enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 751aef3..d9e75dc 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -52,6 +52,26 @@
using namespace overlay::utils;
namespace ovutils = overlay::utils;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EGLAPI EGLBoolean eglGpuPerfHintQCOM(EGLDisplay dpy, EGLContext ctx,
+ EGLint *attrib_list);
+#define EGL_GPU_HINT_1 0x32D0
+#define EGL_GPU_HINT_2 0x32D1
+
+#define EGL_GPU_LEVEL_0 0x0
+#define EGL_GPU_LEVEL_1 0x1
+#define EGL_GPU_LEVEL_2 0x2
+#define EGL_GPU_LEVEL_3 0x3
+#define EGL_GPU_LEVEL_4 0x4
+#define EGL_GPU_LEVEL_5 0x5
+
+#ifdef __cplusplus
+}
+#endif
+
namespace qhwc {
bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
@@ -245,6 +265,15 @@
ctx->mMDPDownscaleEnabled = true;
}
+ // Initialize gpu perfomance hint related parameters
+ property_get("sys.hwc.gpu_perf_mode", value, "0");
+ ctx->mGPUHintInfo.mGpuPerfModeEnable = atoi(value)? true : false;
+
+ ctx->mGPUHintInfo.mEGLDisplay = NULL;
+ ctx->mGPUHintInfo.mEGLContext = NULL;
+ ctx->mGPUHintInfo.mPrevCompositionGLES = false;
+ ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
+
ALOGI("Initializing Qualcomm Hardware Composer");
ALOGI("MDP version: %d", ctx->mMDP.version);
}
@@ -1981,6 +2010,78 @@
return true;
}
+bool isGLESComp(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list) {
+ int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
+ for(int index = 0; index < numAppLayers; index++) {
+ hwc_layer_1_t* layer = &(list->hwLayers[index]);
+ if(layer->compositionType == HWC_FRAMEBUFFER)
+ return true;
+ }
+ return false;
+}
+
+void setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
+ struct gpu_hint_info *gpuHint = &ctx->mGPUHintInfo;
+ if(!gpuHint->mGpuPerfModeEnable)
+ return;
+ /* Set the GPU hint flag to high for MIXED/GPU composition only for
+ first frame after MDP -> GPU/MIXED mode transition. Set the GPU
+ hint to default if the previous composition is GPU or current GPU
+ composition is due to idle fallback */
+ if(!gpuHint->mEGLDisplay || !gpuHint->mEGLContext) {
+ gpuHint->mEGLDisplay = eglGetCurrentDisplay();
+ if(!gpuHint->mEGLDisplay) {
+ ALOGW("%s Warning: EGL current display is NULL", __FUNCTION__);
+ return;
+ }
+ gpuHint->mEGLContext = eglGetCurrentContext();
+ if(!gpuHint->mEGLContext) {
+ ALOGW("%s Warning: EGL current context is NULL", __FUNCTION__);
+ return;
+ }
+ }
+ if(isGLESComp(ctx, list)) {
+ if(!gpuHint->mPrevCompositionGLES && !MDPComp::isIdleFallback()) {
+ EGLint attr_list[] = {EGL_GPU_HINT_1,
+ EGL_GPU_LEVEL_3,
+ EGL_NONE };
+ if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_3) &&
+ !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
+ gpuHint->mEGLContext, attr_list)) {
+ ALOGW("eglGpuPerfHintQCOM failed for Built in display");
+ } else {
+ gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_3;
+ gpuHint->mPrevCompositionGLES = true;
+ }
+ } else {
+ EGLint attr_list[] = {EGL_GPU_HINT_1,
+ EGL_GPU_LEVEL_0,
+ EGL_NONE };
+ if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
+ !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
+ gpuHint->mEGLContext, attr_list)) {
+ ALOGW("eglGpuPerfHintQCOM failed for Built in display");
+ } else {
+ gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
+ }
+ }
+ } else {
+ /* set the GPU hint flag to default for MDP composition */
+ EGLint attr_list[] = {EGL_GPU_HINT_1,
+ EGL_GPU_LEVEL_0,
+ EGL_NONE };
+ if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
+ !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
+ gpuHint->mEGLContext, attr_list)) {
+ ALOGW("eglGpuPerfHintQCOM failed for Built in display");
+ } else {
+ gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
+ }
+ gpuHint->mPrevCompositionGLES = false;
+ }
+}
+
void BwcPM::setBwc(const hwc_rect_t& crop,
const hwc_rect_t& dst, const int& transform,
ovutils::eMdpFlags& mdpFlags) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index b4b5232..ad023ad 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -30,6 +30,8 @@
#include <utils/String8.h>
#include "qdMetaData.h"
#include <overlayUtils.h>
+#include <EGL/egl.h>
+
#define ALIGN_TO(x, align) (((x) + ((align)-1)) & ~((align)-1))
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
@@ -341,6 +343,12 @@
bool isDisplaySplit(hwc_context_t* ctx, int dpy);
+// Set the GPU hint flag to high for MIXED/GPU composition only for
+// first frame after MDP to GPU/MIXED mode transition.
+// Set the GPU hint to default if the current composition type is GPU
+// due to idle fallback or MDP composition.
+void setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+
// Inline utility functions
static inline bool isSkipLayer(const hwc_layer_1_t* l) {
return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
@@ -439,6 +447,20 @@
ANIMATION_STARTED,
};
+// Structure holds the information about the GPU hint.
+struct gpu_hint_info {
+ // system level flag to enable gpu_perf_mode
+ bool mGpuPerfModeEnable;
+ // Stores the current GPU performance mode DEFAULT/HIGH
+ bool mCurrGPUPerfMode;
+ // true if previous composition used GPU
+ bool mPrevCompositionGLES;
+ // Stores the EGLContext of current process
+ EGLContext mEGLContext;
+ // Stores the EGLDisplay of current process
+ EGLDisplay mEGLDisplay;
+};
+
// -----------------------------------------------------------------------------
// HWC context
// This structure contains overall state
@@ -502,6 +524,7 @@
// Downscale feature switch, set via system the property
// sys.hwc.mdp_downscale_enabled
bool mMDPDownscaleEnabled;
+ struct gpu_hint_info mGPUHintInfo;
};
namespace qhwc {