author | jeff.yang <jeff.yang@amlogic.com> | 2013-05-06 06:57:45 (GMT) |
---|---|---|
committer | timyao <tim.yao@amlogic.com> | 2013-05-06 18:16:14 (GMT) |
commit | 16b34cc1a7362b1a947f70140e31b1e5d7f15c02 (patch) | |
tree | 5b30deea2549387d47f12af6427e03d1a18af58d | |
parent | 2778044563406a8972da2145fa4fbe899dc12c3c (diff) | |
download | hwcomposer-16b34cc1a7362b1a947f70140e31b1e5d7f15c02.zip hwcomposer-16b34cc1a7362b1a947f70140e31b1e5d7f15c02.tar.gz hwcomposer-16b34cc1a7362b1a947f70140e31b1e5d7f15c02.tar.bz2 |
PD #72549: modify the high cpu loading problem when using gl-draw, the problem shows spin_lock in surfaceflinger consume much loading
-rw-r--r-- | Android.mk | 2 | ||||
-rwxr-xr-x | hwcomposer.cpp | 97 |
2 files changed, 90 insertions, 9 deletions
@@ -8,7 +8,7 @@ LOCAL_PATH := $(call my-dir) # /system/lib/hw/hwcomposer.amlogic.so include $(CLEAR_VARS) LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw -LOCAL_SHARED_LIBRARIES := liblog libEGL libamavutils +LOCAL_SHARED_LIBRARIES := liblog libEGL libutils libamavutils LOCAL_SRC_FILES := hwcomposer.cpp AMPLAYER_APK_DIR=$(TOP)/packages/amlogic/LibPlayer/ diff --git a/hwcomposer.cpp b/hwcomposer.cpp index 3b875f4..f94b5d7 100755 --- a/hwcomposer.cpp +++ b/hwcomposer.cpp @@ -19,15 +19,33 @@ #include <hardware/hardware.h> #include <fcntl.h> +#include <math.h> +#include <poll.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/time.h> +#include <sys/types.h> #include <errno.h> +#include <sys/resource.h> +#include <EGL/egl.h> + +#define HWC_REMOVE_DEPRECATED_VERSIONS 1 + +#include <cutils/compiler.h> #include <cutils/log.h> #include <cutils/atomic.h> +#include <utils/String8.h> #include <hardware/hwcomposer.h> #include <EGL/egl.h> - +#include <utils/Vector.h> +#include <utils/Timers.h> // for private_handle_t #include "../../libhardware/modules/gralloc/gralloc_priv.h" @@ -37,17 +55,23 @@ #define LOGD ALOGD #endif +extern "C" int clock_nanosleep(clockid_t clock_id, int flags, + const struct timespec *request, + struct timespec *remain); /*****************************************************************************/ + struct hwc_context_1_t { hwc_composer_device_1_t device; /* our private state goes below here */ - hwc_layer_1_t const* saved_layer; + hwc_layer_1_t const* saved_layer; unsigned saved_transform; int saved_left; int saved_top; int saved_right; int saved_bottom; + const hwc_procs_t *procs; + pthread_t vsync_thread; }; static int hwc_device_open(const struct hw_module_t* module, const char* name, @@ -122,7 +146,7 @@ static void hwc_overlay_compose(hwc_composer_device_1_t *dev, hwc_layer_1_t cons ctx->saved_bottom = l->displayFrame.bottom; } -static void dump_layer(hwc_layer_t const* l) { +/*static void dump_layer(hwc_layer_t const* l) { LOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}", l->compositionType, l->flags, l->handle, l->transform, l->blending, l->sourceCrop.left, @@ -133,7 +157,7 @@ static void dump_layer(hwc_layer_t const* l) { l->displayFrame.top, l->displayFrame.right, l->displayFrame.bottom); -} +}*/ static int hwc_blank(struct hwc_composer_device_1* dev, int disp, @@ -179,25 +203,75 @@ static int hwc_set(struct hwc_composer_device_1 *dev, } } -//TODO: revert this after ARM has official Mali driver release for Android 4.2 -#if 0 + EGLBoolean success = eglSwapBuffers(displays[0]->dpy, displays[0]->sur); if (!success) { return HWC_EGL_ERROR; } -#endif return 0; } static int hwc_device_close(struct hw_device_t *dev) { - struct hwc_context_t* ctx = (struct hwc_context_t*)dev; + struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)dev; if (ctx) { free(ctx); } return 0; } +static void *hwc_vsync_thread(void *data) +{ + struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)data; + nsecs_t nextFakeVSync = 0; + + setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY-1); + + //vsync events unsupported for now and debug.sf.no_hw_vsync is broken + //so simulate them + + while (true) { + const nsecs_t period = 20000000; //50Hz + const nsecs_t now = systemTime(CLOCK_MONOTONIC); + nsecs_t next_vsync = nextFakeVSync; + nsecs_t sleep = next_vsync - now; + if (sleep < 0) { + // we missed, find where the next vsync should be + sleep = (period - ((now - next_vsync) % period)); + next_vsync = now + sleep; + } + nextFakeVSync = next_vsync + period; + + struct timespec spec; + spec.tv_sec = next_vsync / 1000000000; + spec.tv_nsec = next_vsync % 1000000000; + + int err; + do { + err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); + } while (err<0 && errno == EINTR); + + if (err == 0) { + if (ctx->procs) { + ctx->procs->vsync(ctx->procs, 0, next_vsync); + } + } + } + + return NULL; +} + + + +static void hwc_registerProcs(hwc_composer_device_1_t *dev, + hwc_procs_t const* procs) +{ + struct hwc_context_1_t* ctx = (struct hwc_context_1_t*)dev; + if (ctx) { + ctx->procs = procs; + } +} + /*****************************************************************************/ static int hwc_device_open(const struct hw_module_t* module, const char* name, @@ -219,11 +293,18 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name, dev->device.blank = hwc_blank; dev->device.eventControl = hwc_eventControl; + dev->device.registerProcs = hwc_registerProcs; dev->device.prepare = hwc_prepare; dev->device.set = hwc_set; *device = &dev->device.common; status = 0; + + + status = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev); + if (status) { + ALOGE("failed to start vsync thread: %s", strerror(status)); + } } return status; } |