summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/phone-hdpi-2048-dalvik-heap.mk25
-rw-r--r--build/phone-xhdpi-1024-dalvik-heap.mk2
-rw-r--r--build/phone-xxhdpi-2048-dalvik-heap.mk26
-rw-r--r--build/phone-xxhdpi-2048-hwui-memory.mk30
-rw-r--r--build/phone-xxxhdpi-3072-dalvik-heap.mk25
-rw-r--r--build/phone-xxxhdpi-3072-hwui-memory.mk30
-rw-r--r--cmds/installd/commands.cpp214
-rw-r--r--cmds/installd/installd.cpp16
-rw-r--r--cmds/installd/installd.h7
-rw-r--r--include/android/input.h2
-rw-r--r--include/batteryservice/BatteryService.h11
-rw-r--r--include/batteryservice/IBatteryPropertiesRegistrar.h3
-rw-r--r--include/binder/AppOpsManager.h14
-rw-r--r--include/binder/IMemory.h7
-rw-r--r--include/binder/MemoryHeapIon.h68
-rw-r--r--include/gui/ISurfaceComposer.h8
-rw-r--r--include/input/InputEventLabels.h1
-rw-r--r--include/ui/GraphicBufferMapper.h4
-rw-r--r--libs/binder/Android.mk43
-rw-r--r--libs/binder/IMemory.cpp29
-rw-r--r--libs/binder/MemoryHeapIon.cpp191
-rw-r--r--libs/gui/ISurfaceComposer.cpp8
-rw-r--r--libs/gui/Surface.cpp23
-rw-r--r--libs/gui/SurfaceComposerClient.cpp11
-rw-r--r--libs/ui/GraphicBuffer.cpp1
-rw-r--r--libs/ui/GraphicBufferMapper.cpp13
-rw-r--r--opengl/libs/Android.mk6
-rw-r--r--opengl/libs/EGL/eglApi.cpp9
-rw-r--r--services/batteryservice/BatteryProperties.cpp34
-rw-r--r--services/batteryservice/IBatteryPropertiesRegistrar.cpp28
-rw-r--r--services/inputflinger/InputManager.cpp10
-rw-r--r--services/inputflinger/InputReader.cpp66
-rw-r--r--services/inputflinger/InputReader.h33
-rw-r--r--services/surfaceflinger/Android.mk15
-rw-r--r--services/surfaceflinger/DispSync.cpp2
-rw-r--r--services/surfaceflinger/DispSync.h7
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp11
-rw-r--r--services/surfaceflinger/DisplayDevice.h8
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp43
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h19
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp8
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h5
-rw-r--r--services/surfaceflinger/DisplayUtils.cpp173
-rw-r--r--services/surfaceflinger/DisplayUtils.h78
-rw-r--r--services/surfaceflinger/EventThread.cpp2
-rw-r--r--services/surfaceflinger/Layer.cpp6
-rw-r--r--services/surfaceflinger/Layer.h21
-rw-r--r--services/surfaceflinger/LayerDim.cpp9
-rw-r--r--services/surfaceflinger/LayerDim.h2
-rw-r--r--services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp63
-rw-r--r--services/surfaceflinger/RenderEngine/GLES11RenderEngine.h5
-rw-r--r--services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp41
-rw-r--r--services/surfaceflinger/RenderEngine/GLES20RenderEngine.h5
-rw-r--r--services/surfaceflinger/RenderEngine/RenderEngine.cpp9
-rw-r--r--services/surfaceflinger/RenderEngine/RenderEngine.h11
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp149
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h50
-rw-r--r--services/surfaceflinger/main_surfaceflinger.cpp3
58 files changed, 1583 insertions, 160 deletions
diff --git a/build/phone-hdpi-2048-dalvik-heap.mk b/build/phone-hdpi-2048-dalvik-heap.mk
new file mode 100644
index 0000000..2f0bbd2
--- /dev/null
+++ b/build/phone-hdpi-2048-dalvik-heap.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Provides overrides to configure the Dalvik heap for a 2G phone
+# 192m of RAM gives enough space for 5 8 megapixel camera bitmaps in RAM.
+
+PRODUCT_PROPERTY_OVERRIDES += \
+ dalvik.vm.heapstartsize=12m \
+ dalvik.vm.heapgrowthlimit=128m \
+ dalvik.vm.heapsize=256m \
+ dalvik.vm.heaptargetutilization=0.75 \
+ dalvik.vm.heapminfree=4m
diff --git a/build/phone-xhdpi-1024-dalvik-heap.mk b/build/phone-xhdpi-1024-dalvik-heap.mk
index 221227d..20f365f 100644
--- a/build/phone-xhdpi-1024-dalvik-heap.mk
+++ b/build/phone-xhdpi-1024-dalvik-heap.mk
@@ -21,5 +21,5 @@ PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapgrowthlimit=96m \
dalvik.vm.heapsize=256m \
dalvik.vm.heaptargetutilization=0.75 \
- dalvik.vm.heapminfree=512k \
+ dalvik.vm.heapminfree=2m \
dalvik.vm.heapmaxfree=8m
diff --git a/build/phone-xxhdpi-2048-dalvik-heap.mk b/build/phone-xxhdpi-2048-dalvik-heap.mk
new file mode 100644
index 0000000..9489593
--- /dev/null
+++ b/build/phone-xxhdpi-2048-dalvik-heap.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Provides overrides to configure the Dalvik heap for a 2G phone
+# 192m of RAM gives enough space for 5 8 megapixel camera bitmaps in RAM.
+
+PRODUCT_PROPERTY_OVERRIDES += \
+ dalvik.vm.heapstartsize=16m \
+ dalvik.vm.heapgrowthlimit=192m \
+ dalvik.vm.heapsize=512m \
+ dalvik.vm.heaptargetutilization=0.75 \
+ dalvik.vm.heapminfree=2m \
+ dalvik.vm.heapmaxfree=8m
diff --git a/build/phone-xxhdpi-2048-hwui-memory.mk b/build/phone-xxhdpi-2048-hwui-memory.mk
new file mode 100644
index 0000000..b4226bc
--- /dev/null
+++ b/build/phone-xxhdpi-2048-hwui-memory.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2013 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Provides overrides to configure the HWUI memory limits
+
+PRODUCT_PROPERTY_OVERRIDES += \
+ ro.hwui.texture_cache_size=72 \
+ ro.hwui.layer_cache_size=48 \
+ ro.hwui.r_buffer_cache_size=8 \
+ ro.hwui.path_cache_size=32 \
+ ro.hwui.gradient_cache_size=1 \
+ ro.hwui.drop_shadow_cache_size=6 \
+ ro.hwui.texture_cache_flushrate=0.4 \
+ ro.hwui.text_small_cache_width=1024 \
+ ro.hwui.text_small_cache_height=1024 \
+ ro.hwui.text_large_cache_width=2048 \
+ ro.hwui.text_large_cache_height=1024
diff --git a/build/phone-xxxhdpi-3072-dalvik-heap.mk b/build/phone-xxxhdpi-3072-dalvik-heap.mk
new file mode 100644
index 0000000..3bf65a7
--- /dev/null
+++ b/build/phone-xxxhdpi-3072-dalvik-heap.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2015 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Provides overrides to configure the Dalvik heap for a 3G phone
+
+PRODUCT_PROPERTY_OVERRIDES += \
+ dalvik.vm.heapstartsize=8m \
+ dalvik.vm.heapgrowthlimit=256m \
+ dalvik.vm.heapsize=512m \
+ dalvik.vm.heaptargetutilization=0.75 \
+ dalvik.vm.heapminfree=2m \
+ dalvik.vm.heapmaxfree=8m
diff --git a/build/phone-xxxhdpi-3072-hwui-memory.mk b/build/phone-xxxhdpi-3072-hwui-memory.mk
new file mode 100644
index 0000000..8123fa0
--- /dev/null
+++ b/build/phone-xxxhdpi-3072-hwui-memory.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2015 The CyanogenMod Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Provides overrides to configure the HWUI memory limits
+
+PRODUCT_PROPERTY_OVERRIDES += \
+ ro.hwui.texture_cache_size=88 \
+ ro.hwui.layer_cache_size=58 \
+ ro.hwui.path_cache_size=32 \
+ ro.hwui.shape_cache_size=4 \
+ ro.hwui.gradient_cache_size=2 \
+ ro.hwui.drop_shadow_cache_size=8 \
+ ro.hwui.r_buffer_cache_size=8 \
+ ro.hwui.text_small_cache_width=2048 \
+ ro.hwui.text_small_cache_height=2048 \
+ ro.hwui.text_large_cache_width=4096 \
+ ro.hwui.text_large_cache_height=4096
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index d4aa7d3..55cdabc 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -1623,62 +1623,46 @@ out:
return rc;
}
-static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd)
+static void run_idmap(const char *target_apk, const char *overlay_apk, const char *cache_path,
+ int idmap_fd, uint32_t target_hash, uint32_t overlay_hash)
{
static const char *IDMAP_BIN = "/system/bin/idmap";
static const size_t MAX_INT_LEN = 32;
char idmap_str[MAX_INT_LEN];
+ char target_hash_str[MAX_INT_LEN];
+ char overlay_hash_str[MAX_INT_LEN];
snprintf(idmap_str, sizeof(idmap_str), "%d", idmap_fd);
+ snprintf(target_hash_str, sizeof(target_hash_str), "%d", target_hash);
+ snprintf(overlay_hash_str, sizeof(overlay_hash_str), "%d", overlay_hash);
- execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, idmap_str, (char*)NULL);
+ execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, cache_path, idmap_str,
+ target_hash_str, overlay_hash_str, (char*)NULL);
ALOGE("execl(%s) failed: %s\n", IDMAP_BIN, strerror(errno));
}
-// Transform string /a/b/c.apk to (prefix)/a@b@c.apk@(suffix)
-// eg /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap
-static int flatten_path(const char *prefix, const char *suffix,
- const char *overlay_path, char *idmap_path, size_t N)
+static int get_idmap_path(const char *prefix, const char *suffix, char *idmap_path, size_t N)
{
- if (overlay_path == NULL || idmap_path == NULL) {
- return -1;
- }
- const size_t len_overlay_path = strlen(overlay_path);
- // will access overlay_path + 1 further below; requires absolute path
- if (len_overlay_path < 2 || *overlay_path != '/') {
- return -1;
- }
- const size_t len_idmap_root = strlen(prefix);
- const size_t len_suffix = strlen(suffix);
- if (SIZE_MAX - len_idmap_root < len_overlay_path ||
- SIZE_MAX - (len_idmap_root + len_overlay_path) < len_suffix) {
- // additions below would cause overflow
- return -1;
- }
- if (N < len_idmap_root + len_overlay_path + len_suffix) {
- return -1;
- }
+ if (idmap_path == NULL) return -1;
+
memset(idmap_path, 0, N);
- snprintf(idmap_path, N, "%s%s%s", prefix, overlay_path + 1, suffix);
- char *ch = idmap_path + len_idmap_root;
- while (*ch != '\0') {
- if (*ch == '/') {
- *ch = '@';
- }
- ++ch;
+ int len = snprintf(idmap_path, N, "%s/%s", prefix, suffix);
+ if (len < 0 || (size_t)len >= N) {
+ return -1; // error or truncated
}
return 0;
}
-int idmap(const char *target_apk, const char *overlay_apk, uid_t uid)
+int idmap(const char *target_apk, const char *overlay_apk, const char *cache_path,
+ uid_t uid, uint32_t target_hash, uint32_t overlay_hash)
{
- ALOGV("idmap target_apk=%s overlay_apk=%s uid=%d\n", target_apk, overlay_apk, uid);
+ ALOGD("idmap target_apk=%s overlay_apk=%s cache_path=%s uid=%d\n", target_apk, overlay_apk,
+ cache_path, uid);
int idmap_fd = -1;
char idmap_path[PATH_MAX];
- if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk,
- idmap_path, sizeof(idmap_path)) == -1) {
+ if (get_idmap_path(cache_path, IDMAP_SUFFIX, idmap_path, sizeof(idmap_path)) == -1) {
ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk);
goto fail;
}
@@ -1715,7 +1699,7 @@ int idmap(const char *target_apk, const char *overlay_apk, uid_t uid)
exit(1);
}
- run_idmap(target_apk, overlay_apk, idmap_fd);
+ run_idmap(target_apk, overlay_apk, cache_path, idmap_fd, target_hash, overlay_hash);
exit(1); /* only if exec call to idmap failed */
} else {
int status = wait_child(pid);
@@ -1735,6 +1719,164 @@ fail:
return -1;
}
+static void run_aapt(const char *source_apk, const char *internal_path,
+ int resapk_fd, int pkgId, int min_sdk_version, const char *common_res_path)
+{
+ static const char *AAPT_BIN = "/system/bin/aapt";
+ static const char *MANIFEST = "/data/app/AndroidManifest.xml";
+ static const char *FRAMEWORK_RES = "/system/framework/framework-res.apk";
+
+ static const size_t MAX_INT_LEN = 32;
+ char resapk_str[MAX_INT_LEN];
+ char pkgId_str[MAX_INT_LEN];
+ char minSdkVersion_str[MAX_INT_LEN];
+
+ snprintf(resapk_str, sizeof(resapk_str), "%d", resapk_fd);
+ snprintf(pkgId_str, sizeof(pkgId_str), "%d", pkgId);
+ snprintf(minSdkVersion_str, sizeof(minSdkVersion_str), "%d", min_sdk_version);
+ bool hasCommonResources = (common_res_path != NULL && common_res_path[0] != '\0');
+
+ if (hasCommonResources) {
+ execl(AAPT_BIN, AAPT_BIN, "package",
+ "--min-sdk-version", minSdkVersion_str,
+ "-M", MANIFEST,
+ "-S", source_apk,
+ "-X", internal_path,
+ "-I", FRAMEWORK_RES,
+ "-I", common_res_path,
+ "-r", resapk_str,
+ "-x", pkgId_str,
+ "-f",
+ (char*)NULL);
+ } else {
+ execl(AAPT_BIN, AAPT_BIN, "package",
+ "--min-sdk-version", minSdkVersion_str,
+ "-M", MANIFEST,
+ "-S", source_apk,
+ "-X", internal_path,
+ "-I", FRAMEWORK_RES,
+ "-r", resapk_str,
+ "-x", pkgId_str,
+ "-f",
+ (char*)NULL);
+ }
+ ALOGE("execl(%s) failed: %s\n", AAPT_BIN, strerror(errno));
+}
+
+int aapt(const char *source_apk, const char *internal_path, const char *out_restable, uid_t uid,
+ int pkgId, int min_sdk_version, const char *common_res_path)
+{
+ ALOGD("aapt source_apk=%s internal_path=%s out_restable=%s uid=%d, pkgId=%d,min_sdk_version=%d, common_res_path=%s",
+ source_apk, internal_path, out_restable, uid, pkgId, min_sdk_version, common_res_path);
+ static const int PARENT_READ_PIPE = 0;
+ static const int CHILD_WRITE_PIPE = 1;
+
+ int resapk_fd = -1;
+ char restable_path[PATH_MAX];
+ char resapk_path[PATH_MAX];
+
+ // create pipes for redirecting STDERR to a buffer that can be displayed in logcat
+ int pipefd[2];
+ if (pipe(pipefd) != 0) {
+ pipefd[0] = pipefd[1] = -1;
+ }
+
+ pid_t pid = fork();
+
+ if (pid == 0) {
+ // get file descriptor for resources.arsc
+ snprintf(restable_path, PATH_MAX, "%s/resources.arsc", out_restable);
+ unlink(restable_path);
+
+ // get file descriptor for resources.apk
+ snprintf(resapk_path, PATH_MAX, "%s/resources.apk", out_restable);
+ unlink(resapk_path);
+ resapk_fd = open(resapk_path, O_RDWR | O_CREAT | O_EXCL, 0644);
+ if (resapk_fd < 0) {
+ ALOGE("aapt cannot open '%s' for output: %s\n", resapk_path, strerror(errno));
+ goto fail;
+ }
+ if (fchown(resapk_fd, AID_SYSTEM, uid) < 0) {
+ ALOGE("aapt cannot chown '%s'\n", resapk_path);
+ goto fail;
+ }
+ if (fchmod(resapk_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
+ ALOGE("aapt cannot chmod '%s'\n", resapk_path);
+ goto fail;
+ }
+
+ /* child -- drop privileges before continuing */
+ if (setgid(uid) != 0) {
+ ALOGE("setgid(%d) failed during aapt\n", uid);
+ exit(1);
+ }
+ if (setuid(uid) != 0) {
+ ALOGE("setuid(%d) failed during aapt\n", uid);
+ exit(1);
+ }
+
+ if (flock(resapk_fd, LOCK_EX | LOCK_NB) != 0) {
+ ALOGE("flock(%s) failed during aapt: %s\n", out_restable, strerror(errno));
+ exit(1);
+ }
+
+ if (pipefd[PARENT_READ_PIPE] > 0 && pipefd[CHILD_WRITE_PIPE] > 0) {
+ close(pipefd[PARENT_READ_PIPE]); // close unused read end
+ if (dup2(pipefd[CHILD_WRITE_PIPE], STDERR_FILENO) != STDERR_FILENO) {
+ pipefd[CHILD_WRITE_PIPE] = -1;
+ }
+ }
+
+ run_aapt(source_apk, internal_path, resapk_fd, pkgId, min_sdk_version, common_res_path);
+
+ close(resapk_fd);
+ if (pipefd[CHILD_WRITE_PIPE] > 0) {
+ close(pipefd[CHILD_WRITE_PIPE]);
+ }
+ exit(1); /* only if exec call to idmap failed */
+ } else {
+ int status, i;
+ char buffer[1024];
+ ssize_t readlen;
+
+ if (pipefd[CHILD_WRITE_PIPE] > 0) {
+ close(pipefd[CHILD_WRITE_PIPE]); // close unused write end
+ }
+
+ if (pipefd[PARENT_READ_PIPE] > 0) {
+ while ((readlen = read(pipefd[PARENT_READ_PIPE], buffer, sizeof(buffer) - 1)) > 0) {
+ // in case buffer has more than one string in it, replace '\0' with '\n'
+ for (i = 0; i < readlen; i++) {
+ if (buffer[i] == '\0') buffer[i] = '\n';
+ }
+ // null terminate buffer at readlen
+ buffer[readlen] = '\0';
+ ALOG(LOG_ERROR, "InstallTheme", "%s", buffer);
+ }
+ waitpid(pid, &status, 0);
+
+ if (pipefd[PARENT_READ_PIPE] > 0) {
+ close(pipefd[PARENT_READ_PIPE]);
+ }
+ } else {
+ status = wait_child(pid);
+ }
+
+ if (status != 0) {
+ ALOGE("aapt failed, status=0x%04x\n", status);
+ goto fail;
+ }
+ }
+
+ return 0;
+fail:
+ if (resapk_fd >= 0) {
+ close(resapk_fd);
+ unlink(resapk_path);
+ }
+ return -1;
+}
+
int restorecon_data(const char* uuid, const char* pkgName,
const char* seinfo, uid_t uid)
{
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index f67e838..d0e1747 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -158,7 +158,17 @@ static int do_linklib(char **arg, char reply[REPLY_MAX] __unused)
static int do_idmap(char **arg, char reply[REPLY_MAX] __unused)
{
- return idmap(arg[0], arg[1], atoi(arg[2]));
+ return idmap(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]));
+}
+
+static int do_aapt(char **arg, char reply[REPLY_MAX] __unused)
+{
+ return aapt(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]), "");
+}
+
+static int do_aapt_with_common(char **arg, char reply[REPLY_MAX] __unused)
+{
+ return aapt(arg[0], arg[1], arg[2], atoi(arg[3]), atoi(arg[4]), atoi(arg[5]), arg[6]);
}
static int do_restorecon_data(char **arg, char reply[REPLY_MAX] __attribute__((unused)))
@@ -212,7 +222,9 @@ struct cmdinfo cmds[] = {
{ "mkuserdata", 5, do_mk_user_data },
{ "mkuserconfig", 1, do_mk_user_config },
{ "rmuser", 2, do_rm_user },
- { "idmap", 3, do_idmap },
+ { "idmap", 6, do_idmap },
+ { "aapt", 6, do_aapt },
+ { "aapt_with_common", 7, do_aapt_with_common },
{ "restorecondata", 4, do_restorecon_data },
{ "createoatdir", 2, do_create_oat_dir },
{ "rmpackagedir", 1, do_rm_package_dir },
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 24b9084..2745ba0 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -80,7 +80,7 @@
#define UPDATE_COMMANDS_DIR_PREFIX "/system/etc/updatecmds/"
#define IDMAP_PREFIX "/data/resource-cache/"
-#define IDMAP_SUFFIX "@idmap"
+#define IDMAP_SUFFIX "idmap"
#define PKG_NAME_MAX 128 /* largest allowed package name */
#define PKG_PATH_MAX 256 /* max size of any path we use */
@@ -247,7 +247,10 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName,
int mark_boot_complete(const char *instruction_set);
int movefiles();
int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId);
-int idmap(const char *target_path, const char *overlay_path, uid_t uid);
+int idmap(const char *target_path, const char *overlay_path, const char *cache_path, uid_t uid,
+ uint32_t target_hash, uint32_t overlay_hash);
+int aapt(const char *source_apk, const char *internal_path, const char *out_restable, uid_t uid,
+ int pkgId, int min_sdk_version, const char *common_res_path);
int restorecon_data(const char *uuid, const char* pkgName, const char* seinfo, uid_t uid);
int create_oat_dir(const char* oat_dir, const char *instruction_set);
int rm_package_dir(const char* apk_path);
diff --git a/include/android/input.h b/include/android/input.h
index 5ab4e29..46cf89c 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -815,6 +815,8 @@ enum {
AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
/** navigation */
AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE,
+ /** gesture sensor (?) */
+ AINPUT_SOURCE_GESTURE_SENSOR = 0x00400000 | AINPUT_SOURCE_CLASS_NONE,
/** joystick */
AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
diff --git a/include/batteryservice/BatteryService.h b/include/batteryservice/BatteryService.h
index f0a2790..3e6bfb8 100644
--- a/include/batteryservice/BatteryService.h
+++ b/include/batteryservice/BatteryService.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -66,6 +67,16 @@ struct BatteryProperties {
int batteryTemperature;
String8 batteryTechnology;
+ bool dockBatterySupported;
+ bool chargerDockAcOnline;
+ int dockBatteryStatus;
+ int dockBatteryHealth;
+ bool dockBatteryPresent;
+ int dockBatteryLevel;
+ int dockBatteryVoltage;
+ int dockBatteryTemperature;
+ String8 dockBatteryTechnology;
+
status_t writeToParcel(Parcel* parcel) const;
status_t readFromParcel(Parcel* parcel);
};
diff --git a/include/batteryservice/IBatteryPropertiesRegistrar.h b/include/batteryservice/IBatteryPropertiesRegistrar.h
index eca075d..f6a7981 100644
--- a/include/batteryservice/IBatteryPropertiesRegistrar.h
+++ b/include/batteryservice/IBatteryPropertiesRegistrar.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +28,7 @@ enum {
REGISTER_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
UNREGISTER_LISTENER,
GET_PROPERTY,
+ GET_DOCK_PROPERTY,
};
class IBatteryPropertiesRegistrar : public IInterface {
@@ -36,6 +38,7 @@ public:
virtual void registerListener(const sp<IBatteryPropertiesListener>& listener) = 0;
virtual void unregisterListener(const sp<IBatteryPropertiesListener>& listener) = 0;
virtual status_t getProperty(int id, struct BatteryProperty *val) = 0;
+ virtual status_t getDockProperty(int id, struct BatteryProperty *val) = 0;
};
class BnBatteryPropertiesRegistrar : public BnInterface<IBatteryPropertiesRegistrar> {
diff --git a/include/binder/AppOpsManager.h b/include/binder/AppOpsManager.h
index 042927c..1d0e968 100644
--- a/include/binder/AppOpsManager.h
+++ b/include/binder/AppOpsManager.h
@@ -91,7 +91,19 @@ public:
OP_USE_SIP = 53,
OP_PROCESS_OUTGOING_CALLS = 54,
OP_USE_FINGERPRINT = 55,
- OP_BODY_SENSORS = 56
+ OP_BODY_SENSORS = 56,
+ OP_READ_CELL_BROADCASTS = 57,
+ OP_MOCK_LOCATION = 58,
+ OP_READ_EXTERNAL_STORAGE = 59,
+ OP_WRITE_EXTERNAL_STORAGE = 60,
+ OP_TURN_SCREEN_ON = 61,
+ OP_GET_ACCOUNTS = 62,
+ OP_WIFI_CHANGE = 63,
+ OP_BLUETOOTH_CHANGE = 64,
+ OP_BOOT_COMPLETED = 65,
+ OP_NFC_CHANGE = 66,
+ OP_DATA_CONNECT_CHANGE = 67,
+ OP_SU = 68
};
AppOpsManager();
diff --git a/include/binder/IMemory.h b/include/binder/IMemory.h
index 2d0db00..178ef85 100644
--- a/include/binder/IMemory.h
+++ b/include/binder/IMemory.h
@@ -36,7 +36,12 @@ public:
// flags returned by getFlags()
enum {
- READ_ONLY = 0x00000001
+ READ_ONLY = 0x00000001,
+#ifdef USE_MEMORY_HEAP_ION
+ USE_ION_FD = 0x00008000
+#else
+ USE_ION_FD = 0x00000008
+#endif
};
virtual int getHeapID() const = 0;
diff --git a/include/binder/MemoryHeapIon.h b/include/binder/MemoryHeapIon.h
new file mode 100644
index 0000000..7e059f4
--- /dev/null
+++ b/include/binder/MemoryHeapIon.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright 2011, Samsung Electronics Co. LTD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*!
+ * \file MemoryHeapIon.h
+ * \brief header file for MemoryHeapIon
+ * \author MinGu, Jeon(mingu85.jeon)
+ * \date 2011/11/20
+ *
+ * <b>Revision History: </b>
+ * - 2011/11/21 : MinGu, Jeon(mingu85.jeon)) \n
+ * Initial version
+ * - 2012/11/29 : MinGu, Jeon(mingu85.jeon)) \n
+ * Change name
+ */
+
+#ifndef ANDROID_MEMORY_HEAP_ION_H
+#define ANDROID_MEMORY_HEAP_ION_H
+
+#include <binder/IMemory.h>
+#include <binder/MemoryHeapBase.h>
+#include <stdlib.h>
+
+#define MHB_ION_HEAP_SYSTEM_CONTIG_MASK (1 << 1)
+#define MHB_ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4)
+#define MHB_ION_HEAP_EXYNOS_MASK (1 << 5)
+#define MHB_ION_HEAP_SYSTEM_MASK (1 << 6)
+
+#define MHB_ION_FLAG_CACHED (1 << 16)
+#define MHB_ION_FLAG_CACHED_NEEDS_SYNC (1 << 17)
+#define MHB_ION_FLAG_PRESERVE_KMAP (1 << 18)
+
+#define MHB_ION_EXYNOS_VIDEO_MASK (1 << 21)
+#define MHB_ION_EXYNOS_MFC_INPUT_MASK (1 << 25)
+#define MHB_ION_EXYNOS_MFC_OUTPUT_MASK (1 << 26)
+#define MHB_ION_EXYNOS_GSC_MASK (1 << 27)
+#define MHB_ION_EXYNOS_FIMD_VIDEO_MASK (1 << 28)
+
+namespace android {
+
+class MemoryHeapIon : public MemoryHeapBase
+{
+public:
+ enum {
+ USE_ION_FD = IMemoryHeap::USE_ION_FD
+ };
+ MemoryHeapIon(size_t size, uint32_t flags = 0, char const* name = NULL);
+ MemoryHeapIon(int fd, size_t size, uint32_t flags = 0, uint32_t offset = 0);
+ ~MemoryHeapIon();
+private:
+ int mIonClient;
+};
+
+};
+#endif
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 8c3d49e..84ddb27 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -58,8 +58,9 @@ public:
};
enum {
- eDisplayIdMain = 0,
- eDisplayIdHdmi = 1
+ eDisplayIdMain = 0,
+ eDisplayIdHdmi = 1,
+ eDisplayIdTertiary = 2
};
enum Rotation {
@@ -144,7 +145,8 @@ public:
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform,
- Rotation rotation = eRotateNone) = 0;
+ Rotation rotation = eRotateNone,
+ bool isCpuConsumer = false) = 0;
/* Clears the frame statistics for animations.
*
diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h
index 3962001..c2ed503 100644
--- a/include/input/InputEventLabels.h
+++ b/include/input/InputEventLabels.h
@@ -378,6 +378,7 @@ static const InputEventLabel LEDS[] = {
};
static const InputEventLabel FLAGS[] = {
+ DEFINE_FLAG(WAKE),
DEFINE_FLAG(VIRTUAL),
DEFINE_FLAG(FUNCTION),
DEFINE_FLAG(GESTURE),
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index 6099548..9900624 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -59,6 +59,10 @@ public:
status_t unlockAsync(buffer_handle_t handle, int *fenceFd);
+#ifdef EXYNOS4_ENHANCEMENTS
+ status_t getphys(buffer_handle_t handle, void** paddr);
+#endif
+
// dumps information about the mapping of this handle
void dump(buffer_handle_t handle);
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index d5860ef..b12eda8 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -38,11 +38,31 @@ sources := \
Static.cpp \
TextOutput.cpp \
+ifeq ($(BOARD_NEEDS_MEMORYHEAPION),true)
+sources += \
+ MemoryHeapIon.cpp
+endif
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+
+ifeq ($(BOARD_NEEDS_MEMORYHEAPION),true)
+LOCAL_SHARED_LIBRARIES += libion_exynos
+LOCAL_CFLAGS += -DUSE_MEMORY_HEAP_ION
+
+ifeq ($(TARGET_SLSI_VARIANT),cm)
+SLSI_DIR := samsung_slsi-cm
+PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)
+else
+SLSI_DIR := samsung_slsi
+PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)-$(TARGET_SLSI_VARIANT)
+endif
+LOCAL_C_INCLUDES += hardware/$(SLSI_DIR)/$(PLATFORM_DIR)/include
+endif
+
LOCAL_MODULE := libbinder
-LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
+LOCAL_SHARED_LIBRARIES += liblog libcutils libutils
LOCAL_SRC_FILES := $(sources)
ifneq ($(TARGET_USES_64_BIT_BINDER),true)
ifneq ($(TARGET_IS_64_BIT),true)
@@ -53,9 +73,30 @@ LOCAL_CFLAGS += -Werror
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
+
+ifeq ($(BOARD_NEEDS_MEMORYHEAPION),true)
+LOCAL_SHARED_LIBRARIES += libion_exynos
+LOCAL_CFLAGS += -DUSE_MEMORY_HEAP_ION
+
+ifeq ($(TARGET_SLSI_VARIANT),cm)
+SLSI_DIR := samsung_slsi-cm
+PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)
+else
+SLSI_DIR := samsung_slsi
+PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)-$(TARGET_SLSI_VARIANT)
+endif
+LOCAL_C_INCLUDES += hardware/$(SLSI_DIR)/$(PLATFORM_DIR)/include
+endif
+
LOCAL_MODULE := libbinder
LOCAL_STATIC_LIBRARIES += libutils
LOCAL_SRC_FILES := $(sources)
+ifeq ($(BOARD_NEEDS_MEMORYHEAPPMEM),true)
+LOCAL_C_INCLUDES += \
+ $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+ $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+endif
ifneq ($(TARGET_USES_64_BIT_BINDER),true)
ifneq ($(TARGET_IS_64_BIT),true)
LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index e9891a8..3f2198a 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -32,6 +32,10 @@
#include <binder/Parcel.h>
#include <utils/CallStack.h>
+#ifdef USE_MEMORY_HEAP_ION
+#include "ion.h"
+#endif
+
#define VERBOSE 0
namespace android {
@@ -300,6 +304,14 @@ void BpMemoryHeap::assertReallyMapped() const
IInterface::asBinder(this).get(),
parcel_fd, size, err, strerror(-err));
+#ifdef USE_MEMORY_HEAP_ION
+ ion_client ion_client_num = -1;
+ if (flags & USE_ION_FD) {
+ ion_client_num = ion_client_create();
+ ALOGE_IF(ion_client_num < 0, "BpMemoryHeap : ion client creation error");
+ }
+#endif
+
int fd = dup( parcel_fd );
ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, err=%d (%s)",
parcel_fd, size, err, strerror(errno));
@@ -312,7 +324,16 @@ void BpMemoryHeap::assertReallyMapped() const
Mutex::Autolock _l(mLock);
if (mHeapId == -1) {
mRealHeap = true;
- mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
+
+#ifdef USE_MEMORY_HEAP_ION
+ if (flags & USE_ION_FD) {
+ if (ion_client_num < 0)
+ mBase = MAP_FAILED;
+ else
+ mBase = ion_map(fd, size, offset);
+ } else
+#endif
+ mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
if (mBase == MAP_FAILED) {
ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)",
IInterface::asBinder(this).get(), size, fd, strerror(errno));
@@ -324,6 +345,12 @@ void BpMemoryHeap::assertReallyMapped() const
android_atomic_write(fd, &mHeapId);
}
}
+#ifdef USE_MEMORY_HEAP_ION
+ if (ion_client_num < 0)
+ ion_client_num = -1;
+ else
+ ion_client_destroy(ion_client_num);
+#endif
}
}
diff --git a/libs/binder/MemoryHeapIon.cpp b/libs/binder/MemoryHeapIon.cpp
new file mode 100644
index 0000000..c547395
--- /dev/null
+++ b/libs/binder/MemoryHeapIon.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright Samsung Electronics Co.,LTD.
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*!
+ * \file MemoryHeapIon.cpp
+ * \brief source file for MemoryHeapIon
+ * \author MinGu, Jeon(mingu85.jeon)
+ * \date 2011/11/20
+ *
+ * <b>Revision History: </b>
+ * - 2011/11/20 : MinGu, Jeon(mingu85.jeon)) \n
+ * Initial version
+ * - 2012/11/29 : MinGu, Jeon(mingu85.jeon)) \n
+ * Change name
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+#include <binder/MemoryHeapBase.h>
+#include <binder/IMemory.h>
+#include <binder/MemoryHeapIon.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include "ion.h"
+
+#define HEAP_MASK_FILTER ((1 << 16) - (2))
+#define FLAG_MASK_FILTER (~(HEAP_MASK_FILTER) - (1))
+
+namespace android {
+
+uint32_t ion_HeapMask_valid_check(uint32_t flags)
+{
+ uint32_t heap_mask, result;
+ result = 0;
+
+ heap_mask = flags & HEAP_MASK_FILTER;
+
+ switch(heap_mask) {
+ case MHB_ION_HEAP_SYSTEM_MASK:
+ return ION_HEAP_SYSTEM_MASK;
+ case MHB_ION_HEAP_SYSTEM_CONTIG_MASK:
+ return ION_HEAP_SYSTEM_CONTIG_MASK;
+ case MHB_ION_HEAP_EXYNOS_CONTIG_MASK:
+ return ION_HEAP_EXYNOS_CONTIG_MASK;
+ case MHB_ION_HEAP_EXYNOS_MASK:
+ return ION_HEAP_EXYNOS_MASK;
+ default:
+ ALOGE("MemoryHeapIon : Heap Mask flag is default (flags:%x)", flags);
+ return 0;
+ break;
+ }
+ ALOGE("MemoryHeapIon : Heap Mask flag is wrong (flags:%x)", flags);
+ return 0;
+}
+
+uint32_t ion_FlagMask_valid_check(uint32_t flags)
+{
+ uint32_t flag_mask, result;
+ result = 0;
+
+ flag_mask = flags & FLAG_MASK_FILTER;
+
+ if (flag_mask & MHB_ION_FLAG_CACHED)
+ result |= ION_FLAG_CACHED;
+ if (flag_mask & MHB_ION_FLAG_CACHED_NEEDS_SYNC)
+ result |= ION_FLAG_CACHED_NEEDS_SYNC;
+ if (flag_mask & MHB_ION_FLAG_PRESERVE_KMAP)
+ result |= ION_FLAG_PRESERVE_KMAP;
+ if (flag_mask & MHB_ION_EXYNOS_VIDEO_MASK)
+ result |= ION_EXYNOS_VIDEO_MASK;
+ if (flag_mask & MHB_ION_EXYNOS_MFC_INPUT_MASK)
+ result |= ION_EXYNOS_MFC_INPUT_MASK;
+ if (flag_mask & MHB_ION_EXYNOS_MFC_OUTPUT_MASK)
+ result |= ION_EXYNOS_MFC_OUTPUT_MASK;
+ if (flag_mask & MHB_ION_EXYNOS_GSC_MASK)
+ result |= ION_EXYNOS_GSC_MASK;
+ if (flag_mask & MHB_ION_EXYNOS_FIMD_VIDEO_MASK)
+ result |= ION_EXYNOS_FIMD_VIDEO_MASK;
+
+ return result;
+}
+
+MemoryHeapIon::MemoryHeapIon(size_t size, uint32_t flags,
+ __attribute__((unused))char const *name):MemoryHeapBase()
+{
+ void* base = NULL;
+ int fd = -1;
+ uint32_t isReadOnly, heapMask, flagMask;
+
+ mIonClient = ion_client_create();
+
+ if (mIonClient < 0) {
+ ALOGE("MemoryHeapIon : ION client creation failed : %s", strerror(errno));
+ mIonClient = -1;
+ } else {
+ isReadOnly = flags & (IMemoryHeap::READ_ONLY);
+ heapMask = ion_HeapMask_valid_check(flags);
+ flagMask = ion_FlagMask_valid_check(flags);
+
+ if (heapMask) {
+ ALOGD("MemoryHeapIon : Allocated with size:%d, heap:0x%X , flag:0x%X", size, heapMask, flagMask);
+ fd = ion_alloc(mIonClient, size, 0, heapMask, flagMask);
+ if (fd < 0) {
+ ALOGE("MemoryHeapIon : ION Reserve memory allocation failed(size[%u]) : %s", size, strerror(errno));
+ if (errno == ENOMEM) { // Out of reserve memory. So re-try allocating in system heap
+ ALOGD("MemoryHeapIon : Re-try Allocating in default heap - SYSTEM heap");
+ fd = ion_alloc(mIonClient, size, 0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC | ION_FLAG_PRESERVE_KMAP);
+ }
+ }
+ } else {
+ fd = ion_alloc(mIonClient, size, 0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC | ION_FLAG_PRESERVE_KMAP);
+ ALOGD("MemoryHeapIon : Allocated with default heap - SYSTEM heap");
+ }
+
+ flags = isReadOnly | heapMask | flagMask;
+
+ if (fd < 0) {
+ ALOGE("MemoryHeapIon : ION memory allocation failed(size[%u]) : %s", size, strerror(errno));
+ } else {
+ flags |= USE_ION_FD;
+ base = ion_map(fd, size, 0);
+ if (base != MAP_FAILED) {
+ init(fd, base, size, flags, NULL);
+ } else {
+ ALOGE("MemoryHeapIon : ION mmap failed(size[%u], fd[%d]) : %s", size, fd, strerror(errno));
+ ion_free(fd);
+ }
+ }
+ }
+}
+
+MemoryHeapIon::MemoryHeapIon(int fd, size_t size, uint32_t flags,
+ __attribute__((unused))uint32_t offset):MemoryHeapBase()
+{
+ void* base = NULL;
+ int dup_fd = -1;
+
+ mIonClient = ion_client_create();
+
+ if (mIonClient < 0) {
+ ALOGE("MemoryHeapIon : ION client creation failed : %s", strerror(errno));
+ mIonClient = -1;
+ } else {
+ if (fd >= 0) {
+ dup_fd = dup(fd);
+ if (dup_fd == -1) {
+ ALOGE("MemoryHeapIon : cannot dup fd (size[%u], fd[%d]) : %s", size, fd, strerror(errno));
+ } else {
+ flags |= USE_ION_FD;
+ base = ion_map(dup_fd, size, 0);
+ if (base != MAP_FAILED) {
+ init(dup_fd, base, size, flags, NULL);
+ } else {
+ ALOGE("MemoryHeapIon : ION mmap failed(size[%u], fd[%d]): %s", size, fd, strerror(errno));
+ ion_free(dup_fd);
+ }
+ }
+ } else {
+ ALOGE("MemoryHeapIon : fd parameter error(fd : %d)", fd);
+ }
+ }
+}
+
+MemoryHeapIon::~MemoryHeapIon()
+{
+ if (mIonClient != -1) {
+ ion_unmap(getBase(), getSize());
+ ion_client_destroy(mIonClient);
+ mIonClient = -1;
+ }
+}
+
+};
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 78886d5..0ad6339 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -103,7 +103,8 @@ public:
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform,
- ISurfaceComposer::Rotation rotation)
+ ISurfaceComposer::Rotation rotation,
+ bool isCpuConsumer)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -116,6 +117,7 @@ public:
data.writeUint32(maxLayerZ);
data.writeInt32(static_cast<int32_t>(useIdentityTransform));
data.writeInt32(static_cast<int32_t>(rotation));
+ data.writeInt32(isCpuConsumer);
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
return reply.readInt32();
}
@@ -361,11 +363,13 @@ status_t BnSurfaceComposer::onTransact(
uint32_t maxLayerZ = data.readUint32();
bool useIdentityTransform = static_cast<bool>(data.readInt32());
int32_t rotation = data.readInt32();
+ bool isCpuConsumer = data.readInt32();
status_t res = captureScreen(display, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
useIdentityTransform,
- static_cast<ISurfaceComposer::Rotation>(rotation));
+ static_cast<ISurfaceComposer::Rotation>(rotation),
+ isCpuConsumer);
reply->writeInt32(res);
return NO_ERROR;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 4b76f98..1abb6c3 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1023,6 +1023,7 @@ status_t Surface::lock(
}
// figure out if we can copy the frontbuffer back
+ int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
const bool canCopyBack = (frontBuffer != 0 &&
backBuffer->width == frontBuffer->width &&
@@ -1030,15 +1031,23 @@ status_t Surface::lock(
backBuffer->format == frontBuffer->format);
if (canCopyBack) {
- // copy the area that is invalid and not repainted this round
- const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
+ Mutex::Autolock lock(mMutex);
+ Region oldDirtyRegion;
+ if(mSlots[backBufferSlot].dirtyRegion.isEmpty()) {
+ oldDirtyRegion.set(bounds);
+ } else {
+ for(int i = 0 ; i < NUM_BUFFER_SLOTS; i++ ) {
+ if(i != backBufferSlot && !mSlots[i].dirtyRegion.isEmpty())
+ oldDirtyRegion.orSelf(mSlots[i].dirtyRegion);
+ }
+ }
+ const Region copyback(oldDirtyRegion.subtract(newDirtyRegion));
if (!copyback.isEmpty())
copyBlt(backBuffer, frontBuffer, copyback);
} else {
// if we can't copy-back anything, modify the user's dirty
// region to make sure they redraw the whole buffer
newDirtyRegion.set(bounds);
- mDirtyRegion.clear();
Mutex::Autolock lock(mMutex);
for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
mSlots[i].dirtyRegion.clear();
@@ -1048,15 +1057,9 @@ status_t Surface::lock(
{ // scope for the lock
Mutex::Autolock lock(mMutex);
- int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
- if (backBufferSlot >= 0) {
- Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
- mDirtyRegion.subtract(dirtyRegion);
- dirtyRegion = newDirtyRegion;
- }
+ mSlots[backBufferSlot].dirtyRegion = newDirtyRegion;
}
- mDirtyRegion.orSelf(newDirtyRegion);
if (inOutDirtyBounds) {
*inOutDirtyBounds = newDirtyRegion.getBounds();
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6ad47d8..9955faf 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -683,6 +683,12 @@ status_t SurfaceComposerClient::getAnimationFrameStats(FrameStats* outStats) {
// ----------------------------------------------------------------------------
+#ifndef FORCE_SCREENSHOT_CPU_PATH
+#define SS_CPU_CONSUMER false
+#else
+#define SS_CPU_CONSUMER true
+#endif
+
status_t ScreenshotClient::capture(
const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
@@ -691,7 +697,8 @@ status_t ScreenshotClient::capture(
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT;
return s->captureScreen(display, producer, sourceCrop,
- reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
+ reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
+ ISurfaceComposer::eRotateNone, SS_CPU_CONSUMER);
}
ScreenshotClient::ScreenshotClient()
@@ -729,7 +736,7 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
status_t err = s->captureScreen(display, mProducer, sourceCrop,
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
- static_cast<ISurfaceComposer::Rotation>(rotation));
+ static_cast<ISurfaceComposer::Rotation>(rotation), true);
if (err == NO_ERROR) {
err = mCpuConsumer->lockNextBuffer(&mBuffer);
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index e55db30..0d77727 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -112,6 +112,7 @@ void GraphicBuffer::free_handle()
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
}
+ handle = NULL;
mWrappedBuffer = 0;
}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 90a1c11..0580e16 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -190,5 +190,18 @@ status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
return err;
}
+#ifdef EXYNOS4_ENHANCEMENTS
+status_t GraphicBufferMapper::getphys(buffer_handle_t handle, void** paddr)
+{
+ status_t err;
+
+ err = mAllocMod->getphys(mAllocMod, handle, paddr);
+
+ ALOGW_IF(err, "getphys(%p) fail %d(%s)", handle, err, strerror(-err));
+ return err;
+}
+#endif
+
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 18ad300..e952a38 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -47,6 +47,12 @@ LOCAL_CFLAGS += -DEGL_TRACE=1
ifeq ($(BOARD_ALLOW_EGL_HIBERNATION),true)
LOCAL_CFLAGS += -DBOARD_ALLOW_EGL_HIBERNATION
endif
+ifeq ($(TARGET_BOARD_PLATFORM), omap4)
+ LOCAL_CFLAGS += -DWORKAROUND_BUG_10194508=1
+endif
+ifeq ($(BOARD_EGL_WORKAROUND_BUG_10194508),true)
+ LOCAL_CFLAGS += -DWORKAROUND_BUG_10194508=1
+endif
ifneq ($(MAX_EGL_CACHE_ENTRY_SIZE),)
LOCAL_CFLAGS += -DMAX_EGL_CACHE_ENTRY_SIZE=$(MAX_EGL_CACHE_ENTRY_SIZE)
endif
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 8378907..0bc81b1 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -466,6 +466,14 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
EGLint format = HAL_PIXEL_FORMAT_RGBA_8888;
android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
+#if WORKAROUND_BUG_10194508
+ if (!cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_NATIVE_VISUAL_ID,
+ &format)) {
+ ALOGE("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed: %#x",
+ eglGetError());
+ format = 0;
+ }
+#else
EGLint a = 0;
cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a);
if (a > 0) {
@@ -484,6 +492,7 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
format = HAL_PIXEL_FORMAT_RGBX_8888;
}
}
+#endif
// now select a corresponding sRGB format if needed
if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
diff --git a/services/batteryservice/BatteryProperties.cpp b/services/batteryservice/BatteryProperties.cpp
index f13d6e8..55c7813 100644
--- a/services/batteryservice/BatteryProperties.cpp
+++ b/services/batteryservice/BatteryProperties.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2015 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +42,27 @@ status_t BatteryProperties::readFromParcel(Parcel* p) {
batteryVoltage = p->readInt32();
batteryTemperature = p->readInt32();
batteryTechnology = String8((p->readString16()).string());
+
+ dockBatterySupported = p->readInt32() == 1 ? true : false;
+ if (dockBatterySupported) {
+ chargerDockAcOnline = p->readInt32() == 1 ? true : false;
+ dockBatteryStatus = p->readInt32();
+ dockBatteryHealth = p->readInt32();
+ dockBatteryPresent = p->readInt32() == 1 ? true : false;
+ dockBatteryLevel = p->readInt32();
+ dockBatteryVoltage = p->readInt32();
+ dockBatteryTemperature = p->readInt32();
+ dockBatteryTechnology = String8((p->readString16()).string());
+ } else {
+ chargerDockAcOnline = false;
+ dockBatteryStatus = BATTERY_STATUS_UNKNOWN;
+ dockBatteryHealth = BATTERY_HEALTH_UNKNOWN;
+ dockBatteryPresent = false;
+ dockBatteryLevel = 0;
+ dockBatteryVoltage = 0;
+ dockBatteryTemperature = 0;
+ dockBatteryTechnology = String8(String8::kEmptyString);
+ }
return OK;
}
@@ -56,6 +78,18 @@ status_t BatteryProperties::writeToParcel(Parcel* p) const {
p->writeInt32(batteryVoltage);
p->writeInt32(batteryTemperature);
p->writeString16(String16(batteryTechnology));
+
+ p->writeInt32(dockBatterySupported ? 1 : 0);
+ if (dockBatterySupported) {
+ p->writeInt32(chargerDockAcOnline ? 1 : 0);
+ p->writeInt32(dockBatteryStatus);
+ p->writeInt32(dockBatteryHealth);
+ p->writeInt32(dockBatteryPresent ? 1 : 0);
+ p->writeInt32(dockBatteryLevel);
+ p->writeInt32(dockBatteryVoltage);
+ p->writeInt32(dockBatteryTemperature);
+ p->writeString16(String16(dockBatteryTechnology));
+ }
return OK;
}
diff --git a/services/batteryservice/IBatteryPropertiesRegistrar.cpp b/services/batteryservice/IBatteryPropertiesRegistrar.cpp
index 46934e0..e18e39c 100644
--- a/services/batteryservice/IBatteryPropertiesRegistrar.cpp
+++ b/services/batteryservice/IBatteryPropertiesRegistrar.cpp
@@ -60,6 +60,22 @@ public:
val->readFromParcel(&reply);
return ret;
}
+
+ status_t getDockProperty(int id, struct BatteryProperty *val) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IBatteryPropertiesRegistrar::getInterfaceDescriptor());
+ data.writeInt32(id);
+ remote()->transact(GET_DOCK_PROPERTY, data, &reply);
+ int32_t ret = reply.readExceptionCode();
+ if (ret != 0) {
+ return ret;
+ }
+ ret = reply.readInt32();
+ int parcelpresent = reply.readInt32();
+ if (parcelpresent)
+ val->readFromParcel(&reply);
+ return ret;
+ }
};
IMPLEMENT_META_INTERFACE(BatteryPropertiesRegistrar, "android.os.IBatteryPropertiesRegistrar");
@@ -97,6 +113,18 @@ status_t BnBatteryPropertiesRegistrar::onTransact(uint32_t code,
val.writeToParcel(reply);
return OK;
}
+
+ case GET_DOCK_PROPERTY: {
+ CHECK_INTERFACE(IBatteryPropertiesRegistrar, data, reply);
+ int id = data.readInt32();
+ struct BatteryProperty val;
+ status_t result = getDockProperty(id, &val);
+ reply->writeNoException();
+ reply->writeInt32(result);
+ reply->writeInt32(1);
+ val.writeToParcel(reply);
+ return OK;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
};
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 6a6547b..4f28840 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -21,6 +21,7 @@
#include "InputManager.h"
#include <cutils/log.h>
+#include <cutils/iosched_policy.h>
namespace android {
@@ -51,13 +52,15 @@ void InputManager::initialize() {
}
status_t InputManager::start() {
- status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
+ status_t result = mDispatcherThread->run("InputDispatcher",
+ PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
if (result) {
ALOGE("Could not start InputDispatcher thread due to error %d.", result);
return result;
}
- result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
+ result = mReaderThread->run("InputReader",
+ PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
if (result) {
ALOGE("Could not start InputReader thread due to error %d.", result);
@@ -65,6 +68,9 @@ status_t InputManager::start() {
return result;
}
+ android_set_rt_ioprio(mDispatcherThread->getTid(), 1);
+ android_set_rt_ioprio(mReaderThread->getTid(), 1);
+
return OK;
}
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 36095bf..3813d9b 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -116,9 +116,9 @@ static inline const char* toString(bool value) {
}
static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
- const int32_t map[][4], size_t mapSize) {
+ const int32_t map[][4], size_t mapSize, int32_t rotationMapOffset) {
if (orientation != DISPLAY_ORIENTATION_0) {
- for (size_t i = 0; i < mapSize; i++) {
+ for (size_t i = rotationMapOffset; i < mapSize; i++) {
if (value == map[i][0]) {
return map[i][orientation];
}
@@ -130,6 +130,16 @@ static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
static const int32_t keyCodeRotationMap[][4] = {
// key codes enumerated counter-clockwise with the original (unrotated) key first
// no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation
+
+ // volume keys - tablet
+ { AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_DOWN },
+ { AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_UP },
+
+ // volume keys - phone or hybrid
+ { AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_UP },
+ { AKEYCODE_VOLUME_DOWN, AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_UP, AKEYCODE_VOLUME_DOWN },
+
+ // dpad keys - common
{ AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT },
{ AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN },
{ AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT },
@@ -138,9 +148,9 @@ static const int32_t keyCodeRotationMap[][4] = {
static const size_t keyCodeRotationMapSize =
sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
-static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
+static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation, int32_t rotationMapOffset) {
return rotateValueUsingRotationMap(keyCode, orientation,
- keyCodeRotationMap, keyCodeRotationMapSize);
+ keyCodeRotationMap, keyCodeRotationMapSize, rotationMapOffset);
}
static void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) {
@@ -2131,10 +2141,16 @@ void KeyboardInputMapper::configure(nsecs_t when,
mOrientation = DISPLAY_ORIENTATION_0;
}
}
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_VOLUME_KEYS_ROTATION)) {
+ // mode 0 (disabled) ~ offset 4
+ // mode 1 (phone) ~ offset 2
+ // mode 2 (tablet) ~ offset 0
+ mRotationMapOffset = 4 - 2 * config->volumeKeysRotationMode;
+ }
}
void KeyboardInputMapper::configureParameters() {
- mParameters.orientationAware = false;
+ mParameters.orientationAware = !getDevice()->isExternal();
getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
mParameters.orientationAware);
@@ -2214,7 +2230,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
if (down) {
// Rotate key codes according to orientation if needed.
if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
- keyCode = rotateKeyCode(keyCode, mOrientation);
+ keyCode = rotateKeyCode(keyCode, mOrientation, mRotationMapOffset);
}
// Add key down.
@@ -2924,7 +2940,8 @@ void TouchInputMapper::configure(nsecs_t when,
if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
| InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
| InputReaderConfiguration::CHANGE_SHOW_TOUCHES
- | InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE))) {
+ | InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE
+ | InputReaderConfiguration::CHANGE_STYLUS_ICON_ENABLED))) {
// Configure device sources, surface dimensions, orientation and
// scaling factors.
configureSurface(when, &resetNeeded);
@@ -2996,6 +3013,8 @@ void TouchInputMapper::configureParameters() {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
} else if (deviceTypeString == "pointer") {
mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
+ } else if (deviceTypeString == "gesture") {
+ mParameters.deviceType = Parameters::DEVICE_TYPE_GESTURE_SENSOR;
} else if (deviceTypeString != "default") {
ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
}
@@ -3051,6 +3070,9 @@ void TouchInputMapper::dumpParameters(String8& dump) {
case Parameters::DEVICE_TYPE_POINTER:
dump.append(INDENT4 "DeviceType: pointer\n");
break;
+ case Parameters::DEVICE_TYPE_GESTURE_SENSOR:
+ dump.append(INDENT4 "DeviceType: gesture\n");
+ break;
default:
ALOG_ASSERT(false);
}
@@ -3113,6 +3135,9 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
} else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
mDeviceMode = DEVICE_MODE_NAVIGATION;
+ } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_GESTURE_SENSOR) {
+ mSource = AINPUT_SOURCE_GESTURE_SENSOR;
+ mDeviceMode = DEVICE_MODE_UNSCALED;
} else {
mSource = AINPUT_SOURCE_TOUCHPAD;
mDeviceMode = DEVICE_MODE_UNSCALED;
@@ -4846,7 +4871,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
&& (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
|| mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
// Remind the user of where the pointer is after finishing a gesture with spots.
- mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
+ unfadePointer(PointerControllerInterface::TRANSITION_GRADUAL);
}
break;
case PointerGesture::TAP:
@@ -5835,6 +5860,7 @@ void TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags)
mPointerSimple.currentProperties.id = 0;
mPointerSimple.currentProperties.toolType =
mCurrentCookedState.cookedPointerData.pointerProperties[index].toolType;
+ mLastStylusTime = when;
} else {
down = false;
hovering = false;
@@ -5911,11 +5937,16 @@ void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
mPointerController->clearSpots();
mPointerController->setButtonState(mCurrentRawState.buttonState);
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ unfadePointer(PointerControllerInterface::TRANSITION_IMMEDIATE);
} else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
}
}
+
+ if (rejectPalm(when)) { // stylus is currently active
+ mPointerSimple.reset();
+ return;
+ }
if (mPointerSimple.down && !down) {
mPointerSimple.down = false;
@@ -6037,6 +6068,9 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32
const PointerProperties* properties, const PointerCoords* coords,
const uint32_t* idToIndex, BitSet32 idBits, int32_t changedId,
float xPrecision, float yPrecision, nsecs_t downTime) {
+
+ if (rejectPalm(when)) return;
+
PointerCoords pointerCoords[MAX_POINTERS];
PointerProperties pointerProperties[MAX_POINTERS];
uint32_t pointerCount = 0;
@@ -6110,6 +6144,20 @@ void TouchInputMapper::fadePointer() {
}
}
+void TouchInputMapper::unfadePointer(PointerControllerInterface::Transition transition) {
+ if (mPointerController != NULL &&
+ !(mPointerUsage == POINTER_USAGE_STYLUS && !mConfig.stylusIconEnabled)) {
+ mPointerController->unfade(transition);
+ }
+}
+
+nsecs_t TouchInputMapper::mLastStylusTime = 0;
+
+bool TouchInputMapper::rejectPalm(nsecs_t when) {
+ return (when - mLastStylusTime < mConfig.stylusPalmRejectionTime) &&
+ mPointerSimple.currentProperties.toolType != AMOTION_EVENT_TOOL_TYPE_STYLUS;
+}
+
void TouchInputMapper::cancelTouch(nsecs_t when) {
abortPointerUsage(when, 0 /*policyFlags*/);
abortTouches(when, 0 /* policyFlags*/);
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 7cb4680..9a46fb8 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -144,6 +144,12 @@ struct InputReaderConfiguration {
// The presence of an external stylus has changed.
CHANGE_EXTERNAL_STYLUS_PRESENCE = 1 << 7,
+ // Volume keys rotation option changed.
+ CHANGE_VOLUME_KEYS_ROTATION = 1 << 8,
+
+ // Stylus icon option changed.
+ CHANGE_STYLUS_ICON_ENABLED = 1 << 9,
+
// All devices must be reopened.
CHANGE_MUST_REOPEN = 1 << 31,
};
@@ -231,6 +237,16 @@ struct InputReaderConfiguration {
// True to show the location of touches on the touch screen as spots.
bool showTouches;
+ // True to show the pointer icon when a stylus is used.
+ bool stylusIconEnabled;
+
+ // Ignore finger touches this long after the stylus has been used (including hover)
+ nsecs_t stylusPalmRejectionTime;
+
+ // Remap volume keys according to display rotation
+ // 0 - disabled, 1 - phone or hybrid rotation mode, 2 - tablet rotation mode
+ int volumeKeysRotationMode;
+
InputReaderConfiguration() :
virtualKeyQuietTime(0),
pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
@@ -247,7 +263,11 @@ struct InputReaderConfiguration {
pointerGestureSwipeMaxWidthRatio(0.25f),
pointerGestureMovementSpeedRatio(0.8f),
pointerGestureZoomSpeedRatio(0.3f),
- showTouches(false) { }
+ showTouches(false),
+ stylusIconEnabled(false),
+ stylusPalmRejectionTime(50 * 10000000LL), // 50 ms
+ volumeKeysRotationMode(0)
+ { }
bool getDisplayInfo(bool external, DisplayViewport* outViewport) const;
void setDisplayInfo(bool external, const DisplayViewport& viewport);
@@ -1126,7 +1146,8 @@ private:
uint32_t mSource;
int32_t mKeyboardType;
- int32_t mOrientation; // orientation for dpad keys
+ int32_t mRotationMapOffset; // determines if and how volume keys rotate
+ int32_t mOrientation; // orientation for dpad and volume keys
Vector<KeyDown> mKeyDowns; // keys that are down
int32_t mMetaState;
@@ -1296,6 +1317,7 @@ protected:
DEVICE_TYPE_TOUCH_SCREEN,
DEVICE_TYPE_TOUCH_PAD,
DEVICE_TYPE_TOUCH_NAVIGATION,
+ DEVICE_TYPE_GESTURE_SENSOR,
DEVICE_TYPE_POINTER,
};
@@ -1786,6 +1808,9 @@ private:
VelocityControl mPointerVelocityControl;
VelocityControl mWheelXVelocityControl;
VelocityControl mWheelYVelocityControl;
+
+ // The time the stylus event was processed by any TouchInputMapper
+ static nsecs_t mLastStylusTime;
void resetExternalStylus();
void clearStylusDataPendingFlags();
@@ -1852,6 +1877,10 @@ private:
const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
static void assignPointerIds(const RawState* last, RawState* current);
+
+ void unfadePointer(PointerControllerInterface::Transition transition);
+
+ bool rejectPalm(nsecs_t when);
};
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 1eb2361..276a242 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -34,8 +34,8 @@ LOCAL_SRC_FILES := \
RenderEngine/Texture.cpp \
RenderEngine/GLES10RenderEngine.cpp \
RenderEngine/GLES11RenderEngine.cpp \
- RenderEngine/GLES20RenderEngine.cpp
-
+ RenderEngine/GLES20RenderEngine.cpp \
+ DisplayUtils.cpp
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
@@ -106,6 +106,17 @@ LOCAL_SHARED_LIBRARIES := \
libgui \
libpowermanager
+
+ifeq ($(TARGET_USES_QCOM_BSP), true)
+ LOCAL_WHOLE_STATIC_LIBRARIES += libexsurfaceflinger
+ LOCAL_C_INCLUDES += vendor/qcom/opensource/display-frameworks/native/services/surfaceflinger
+ LOCAL_C_INCLUDES += vendor/qcom/opensource/display-frameworks/include
+ LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libgralloc
+ LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libqdutils
+ LOCAL_SHARED_LIBRARIES += libqdutils
+ LOCAL_CFLAGS += -DQTI_BSP
+endif
+
LOCAL_MODULE := libsurfaceflinger
LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index 3738a55..73b3897 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -21,6 +21,7 @@
#include <math.h>
+#include <cutils/iosched_policy.h>
#include <cutils/log.h>
#include <ui/Fence.h>
@@ -292,6 +293,7 @@ DispSync::DispSync() :
mThread(new DispSyncThread()) {
mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
+ android_set_rt_ioprio(mThread->getTid(), 1);
reset();
beginResync();
diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h
index 67142b6..ebe19a5 100644
--- a/services/surfaceflinger/DispSync.h
+++ b/services/surfaceflinger/DispSync.h
@@ -26,11 +26,8 @@
namespace android {
// Ignore present (retire) fences if the device doesn't have support for the
-// sync framework, or if all phase offsets are zero. The latter is useful
-// because it allows us to avoid resync bursts on devices that don't need
-// phase-offset VSYNC events.
-#if defined(RUNNING_WITHOUT_SYNC_FRAMEWORK) || \
- (VSYNC_EVENT_PHASE_OFFSET_NS == 0 && SF_VSYNC_EVENT_PHASE_OFFSET_NS == 0)
+// sync framework.
+#if defined(RUNNING_WITHOUT_SYNC_FRAMEWORK)
static const bool kIgnorePresentFences = true;
#else
static const bool kIgnorePresentFences = false;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 13d44f3..baff5ba 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -90,6 +90,7 @@ DisplayDevice::DisplayDevice(
{
mNativeWindow = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
+ char property[PROPERTY_VALUE_MAX];
/*
* Create our display's surface
@@ -140,6 +141,11 @@ DisplayDevice::DisplayDevice(
break;
}
+ mPanelInverseMounted = false;
+ // Check if panel is inverse mounted (contents show up HV flipped)
+ property_get("persist.panel.inversemounted", property, "0");
+ mPanelInverseMounted = !!atoi(property);
+
// initialize the display orientation transform.
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
}
@@ -402,6 +408,11 @@ status_t DisplayDevice::orientationToTransfrom(
default:
return BAD_VALUE;
}
+
+ if (DISPLAY_PRIMARY == mHwcDisplayId && isPanelInverseMounted()) {
+ flags = flags ^ Transform::ROT_180;
+ }
+
tr->set(flags, w, h);
return NO_ERROR;
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 8695a44..f492a42 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -126,6 +126,10 @@ public:
int32_t getHwcDisplayId() const { return mHwcDisplayId; }
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
+ bool isPanelInverseMounted() const {
+ return mPanelInverseMounted;
+ }
+
// We pass in mustRecompose so we can keep VirtualDisplaySurface's state
// machine happy without actually queueing a buffer if nothing has changed
status_t beginFrame(bool mustRecompose) const;
@@ -209,7 +213,7 @@ private:
/*
* Transaction state
*/
- static status_t orientationToTransfrom(int orientation,
+ status_t orientationToTransfrom(int orientation,
int w, int h, Transform* tr);
uint32_t mLayerStack;
@@ -226,6 +230,8 @@ private:
int mPowerMode;
// Current active config
int mActiveConfig;
+ // Panel is inverse mounted
+ int mPanelInverseMounted;
};
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 0859149..c57dd5f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -190,6 +190,11 @@ HWComposer::HWComposer(
// we don't have VSYNC support, we need to fake it
mVSyncThread = new VSyncThread(*this);
}
+
+ mDimComp = 0;
+ if (mHwc) {
+ mHwc->query(mHwc, HWC_BACKGROUND_LAYER_SUPPORTED, &mDimComp);
+ }
}
HWComposer::~HWComposer() {
@@ -368,7 +373,12 @@ status_t HWComposer::queryDisplayProperties(int disp) {
return err;
}
- mDisplayData[disp].currentConfig = 0;
+ int currentConfig = getActiveConfig(disp);
+ if (currentConfig < 0 || currentConfig > static_cast<int>((numConfigs-1))) {
+ ALOGE("%s: Invalid display config! %d", __FUNCTION__, currentConfig);
+ currentConfig = 0;
+ }
+ mDisplayData[disp].currentConfig = currentConfig;
for (size_t c = 0; c < numConfigs; ++c) {
err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
DISPLAY_ATTRIBUTES, values);
@@ -716,6 +726,9 @@ status_t HWComposer::prepare() {
if (l.compositionType == HWC_OVERLAY) {
disp.hasOvComp = true;
}
+ if (isCompositionTypeBlit(l.compositionType)) {
+ disp.hasFbComp = true;
+ }
if (l.compositionType == HWC_CURSOR_OVERLAY) {
disp.hasOvComp = true;
}
@@ -816,15 +829,31 @@ status_t HWComposer::setPowerMode(int disp, int mode) {
status_t HWComposer::setActiveConfig(int disp, int mode) {
LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
DisplayData& dd(mDisplayData[disp]);
- dd.currentConfig = mode;
if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
- return (status_t)mHwc->setActiveConfig(mHwc, disp, mode);
+ status_t status = static_cast<status_t>(
+ mHwc->setActiveConfig(mHwc, disp, mode));
+ if (status == NO_ERROR) {
+ dd.currentConfig = mode;
+ } else {
+ ALOGE("%s Failed to set new config (%d) for display (%d)",
+ __FUNCTION__, mode, disp);
+ }
+ return status;
} else {
LOG_FATAL_IF(mode != 0);
}
return NO_ERROR;
}
+int HWComposer::getActiveConfig(int disp) const {
+ LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
+ if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
+ return mHwc->getActiveConfig(mHwc, disp);
+ } else {
+ return 0;
+ }
+}
+
void HWComposer::disconnectDisplay(int disp) {
LOG_ALWAYS_FATAL_IF(disp < 0 || disp == HWC_DISPLAY_PRIMARY);
DisplayData& dd(mDisplayData[disp]);
@@ -998,6 +1027,10 @@ public:
getLayer()->flags &= ~HWC_SKIP_LAYER;
}
}
+ virtual void setDim() {
+ setSkip(false);
+ getLayer()->flags |= 0x80000000;
+ }
virtual void setIsCursorLayerHint(bool isCursor) {
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
if (isCursor) {
@@ -1233,7 +1266,7 @@ void HWComposer::dump(String8& result) const {
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
result.appendFormat(
" %9s | %08" PRIxPTR " | %04x | %04x | %02x | %04x | %-11s |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d | %s\n",
- compositionTypeName[type],
+ (isCompositionTypeBlit(l.compositionType)) ? "HWC_BLIT" : compositionTypeName[type],
intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, formatStr.string(),
l.sourceCropf.left, l.sourceCropf.top, l.sourceCropf.right, l.sourceCropf.bottom,
l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
@@ -1241,7 +1274,7 @@ void HWComposer::dump(String8& result) const {
} else {
result.appendFormat(
" %9s | %08" PRIxPTR " | %04x | %04x | %02x | %04x | %-11s |%7d,%7d,%7d,%7d |%5d,%5d,%5d,%5d | %s\n",
- compositionTypeName[type],
+ (isCompositionTypeBlit(l.compositionType)) ? "HWC_BLIT" : compositionTypeName[type],
intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, formatStr.string(),
l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 5e0b3d8..862288f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -74,7 +74,7 @@ public:
const sp<SurfaceFlinger>& flinger,
EventHandler& handler);
- ~HWComposer();
+ virtual ~HWComposer();
status_t initCheck() const;
@@ -103,6 +103,9 @@ public:
// set active config
status_t setActiveConfig(int disp, int mode);
+ // get active config
+ int getActiveConfig(int disp) const;
+
// reset state when an external, non-virtual display is disconnected
void disconnectDisplay(int disp);
@@ -117,6 +120,9 @@ public:
// does this display have layers handled by GLES
bool hasGlesComposition(int32_t id) const;
+ // does this display support dim layer composition
+ bool hasDimComposition() const { return (mDimComp == 1); }
+
// get the releaseFence file descriptor for a display's framebuffer layer.
// the release fence is only valid after commit()
sp<Fence> getAndResetReleaseFence(int32_t id);
@@ -162,6 +168,7 @@ public:
virtual sp<Fence> getAndResetReleaseFence() = 0;
virtual void setDefaultState() = 0;
virtual void setSkip(bool skip) = 0;
+ virtual void setDim() = 0;
virtual void setIsCursorLayerHint(bool isCursor = true) = 0;
virtual void setBlending(uint32_t blending) = 0;
virtual void setTransform(uint32_t transform) = 0;
@@ -302,6 +309,14 @@ public:
// for debugging ----------------------------------------------------------
void dump(String8& out) const;
+ /* ------------------------------------------------------------------------
+ * Extensions
+ */
+ virtual inline bool isVDSEnabled() const { return true; };
+ virtual inline bool isCompositionTypeBlit(const int32_t /*compType*/) const {
+ return false;
+ };
+
private:
void loadHwcModule();
int loadFbHalModule();
@@ -372,6 +387,8 @@ private:
// thread-safe
mutable Mutex mEventControlLock;
+
+ int mDimComp;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index ba4c198..1e4f907 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -152,7 +152,7 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
// format/usage and get a new buffer when the GLES driver calls
// dequeueBuffer().
mOutputFormat = mDefaultOutputFormat;
- mOutputUsage = GRALLOC_USAGE_HW_COMPOSER;
+ setOutputUsage(GRALLOC_USAGE_HW_COMPOSER);
refreshOutputBuffer();
}
@@ -377,7 +377,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool
mSinkBufferWidth, mSinkBufferHeight,
buf->getPixelFormat(), buf->getUsage());
mOutputFormat = format;
- mOutputUsage = usage;
+ setOutputUsage(usage);
result = refreshOutputBuffer();
if (result < 0)
return result;
@@ -616,6 +616,10 @@ const char* VirtualDisplaySurface::dbgSourceStr(Source s) {
}
}
+void VirtualDisplaySurface::setOutputUsage(uint32_t usage) {
+ mOutputUsage = usage;
+}
+
// ---------------------------------------------------------------------------
} // namespace android
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 6298751..3d0e412 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -72,6 +72,10 @@ class VirtualDisplaySurface : public DisplaySurface,
public BnGraphicBufferProducer,
private ConsumerBase {
public:
+#ifdef QTI_BSP
+ friend class ExVirtualDisplaySurface;
+#endif
+
VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
@@ -118,6 +122,7 @@ private:
virtual status_t allowAllocation(bool allow);
virtual status_t setGenerationNumber(uint32_t generationNumber);
virtual String8 getConsumerName() const override;
+ virtual void setOutputUsage(uint32_t flag);
//
// Utility methods
diff --git a/services/surfaceflinger/DisplayUtils.cpp b/services/surfaceflinger/DisplayUtils.cpp
new file mode 100644
index 0000000..1f4c21c
--- /dev/null
+++ b/services/surfaceflinger/DisplayUtils.cpp
@@ -0,0 +1,173 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <gui/Surface.h>
+#include <ui/GraphicBuffer.h>
+
+#include "RenderEngine/RenderEngine.h"
+#include "DisplayHardware/FramebufferSurface.h"
+#include "DisplayUtils.h"
+#ifdef QTI_BSP
+#include <ExSurfaceFlinger.h>
+#include <ExLayer.h>
+#include <DisplayHardware/ExHWComposer.h>
+#include <DisplayHardware/ExVirtualDisplaySurface.h>
+#endif
+#include <dlfcn.h>
+#include <cutils/properties.h>
+
+namespace android {
+
+DisplayUtils* DisplayUtils::sDisplayUtils = NULL;
+bool DisplayUtils::sUseExtendedImpls = false;
+
+DisplayUtils::DisplayUtils() {
+#ifdef QTI_BSP
+ sUseExtendedImpls = true;
+#endif
+}
+
+DisplayUtils* DisplayUtils::getInstance() {
+ if(sDisplayUtils == NULL) {
+ sDisplayUtils = new DisplayUtils();
+ }
+ return sDisplayUtils;
+}
+
+SurfaceFlinger* DisplayUtils::getSFInstance() {
+#ifdef QTI_BSP
+ if(sUseExtendedImpls) {
+ return new ExSurfaceFlinger();
+ }
+#endif
+ return new SurfaceFlinger();
+}
+
+Layer* DisplayUtils::getLayerInstance(SurfaceFlinger* flinger,
+ const sp<Client>& client, const String8& name,
+ uint32_t w, uint32_t h, uint32_t flags) {
+#ifdef QTI_BSP
+ if(sUseExtendedImpls) {
+ return new ExLayer(flinger, client, name, w, h, flags);
+ }
+#endif
+ return new Layer(flinger, client, name, w, h, flags);
+}
+
+HWComposer* DisplayUtils::getHWCInstance(
+ const sp<SurfaceFlinger>& flinger,
+ HWComposer::EventHandler& handler) {
+#ifdef QTI_BSP
+ if(sUseExtendedImpls) {
+ return new ExHWComposer(flinger, handler);
+ }
+#endif
+ return new HWComposer(flinger,handler);
+}
+
+void DisplayUtils::initVDSInstance(HWComposer* hwc, int32_t hwcDisplayId,
+ sp<IGraphicBufferProducer> currentStateSurface, sp<DisplaySurface> &dispSurface,
+ sp<IGraphicBufferProducer> &producer, sp<IGraphicBufferProducer> bqProducer,
+ sp<IGraphicBufferConsumer> bqConsumer, String8 currentStateDisplayName,
+ bool currentStateIsSecure, int currentStateType)
+{
+#ifdef QTI_BSP
+ if(sUseExtendedImpls) {
+ if(hwc->isVDSEnabled()) {
+ VirtualDisplaySurface* vds = new ExVirtualDisplaySurface(*hwc, hwcDisplayId,
+ currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName,
+ currentStateIsSecure);
+ dispSurface = vds;
+ producer = vds;
+ } else if(!createV4L2BasedVirtualDisplay(hwc, hwcDisplayId, dispSurface, producer,
+ currentStateSurface, bqProducer, bqConsumer, currentStateType)) {
+ VirtualDisplaySurface* vds = new VirtualDisplaySurface(*hwc, hwcDisplayId,
+ currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName);
+ dispSurface = vds;
+ producer = vds;
+ }
+ } else {
+#endif
+ (void)currentStateIsSecure;
+ (void)currentStateType;
+ VirtualDisplaySurface* vds = new VirtualDisplaySurface(*hwc, hwcDisplayId,
+ currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName);
+ dispSurface = vds;
+ producer = vds;
+#ifdef QTI_BSP
+ }
+#endif
+}
+
+bool DisplayUtils::createV4L2BasedVirtualDisplay(HWComposer* hwc, int32_t &hwcDisplayId,
+ sp<DisplaySurface> &dispSurface, sp<IGraphicBufferProducer> &producer,
+ sp<IGraphicBufferProducer> currentStateSurface,
+ sp<IGraphicBufferProducer> bqProducer, sp<IGraphicBufferConsumer> bqConsumer,
+ int currentStateType) {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("persist.sys.wfd.virtual", value, "0");
+ int wfdVirtual = atoi(value);
+ if(wfdVirtual && hwcDisplayId > 0) {
+ //Read virtual display properties and create a
+ //rendering surface for it inorder to be handled
+ //by hwc.
+
+ sp<ANativeWindow> mNativeWindow = new Surface(currentStateSurface);
+ ANativeWindow* const window = mNativeWindow.get();
+
+ int format;
+ window->query(window, NATIVE_WINDOW_FORMAT, &format);
+ EGLSurface surface;
+ EGLint w, h;
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ // In M AOSP getEGLConfig() always returns EGL_NO_CONFIG as
+ // EGL_ANDROIDX_no_config_context active now.
+ EGLConfig config = RenderEngine::chooseEglConfig(display, format);
+
+ surface = eglCreateWindowSurface(display, config, window, NULL);
+ eglQuerySurface(display, surface, EGL_WIDTH, &w);
+ eglQuerySurface(display, surface, EGL_HEIGHT, &h);
+ if(hwc->setVirtualDisplayProperties(hwcDisplayId, w, h, format) != NO_ERROR)
+ return false;
+
+ dispSurface = new FramebufferSurface(*hwc, currentStateType, bqConsumer);
+ producer = bqProducer;
+ return true;
+ }
+ return false;
+}
+
+}; // namespace android
+
diff --git a/services/surfaceflinger/DisplayUtils.h b/services/surfaceflinger/DisplayUtils.h
new file mode 100644
index 0000000..cdf2b67
--- /dev/null
+++ b/services/surfaceflinger/DisplayUtils.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ANDROID_DISPLAY_UTILS_H
+#define ANDROID_DISPLAY_UTILS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "Layer.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/HWComposer.h"
+#include "DisplayHardware/VirtualDisplaySurface.h"
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class IGraphicBufferProducer;
+class IGraphicBufferConsumer;
+class DisplaySurface;
+
+/* Factory Classes */
+
+class DisplayUtils {
+ public:
+ static DisplayUtils* getInstance() ANDROID_API;
+ SurfaceFlinger* getSFInstance() ANDROID_API;
+ Layer* getLayerInstance(SurfaceFlinger*, const sp<Client>&,
+ const String8&, uint32_t,
+ uint32_t, uint32_t);
+ HWComposer* getHWCInstance(const sp<SurfaceFlinger>& flinger,
+ HWComposer::EventHandler& handler);
+ void initVDSInstance(HWComposer* hwc, int32_t hwcDisplayId,
+ sp<IGraphicBufferProducer> currentStateSurface, sp<DisplaySurface> &dispSurface,
+ sp<IGraphicBufferProducer> &producer, sp<IGraphicBufferProducer> bqProducer,
+ sp<IGraphicBufferConsumer> bqConsumer, String8 currentStateDisplayName,
+ bool currentStateIsSecure, int currentStateType);
+ DisplayUtils();
+ private:
+ static DisplayUtils* sDisplayUtils;
+ static bool sUseExtendedImpls;
+
+ bool createV4L2BasedVirtualDisplay(HWComposer* hwc, int32_t &hwcDisplayId,
+ sp<DisplaySurface> &dispSurface, sp<IGraphicBufferProducer> &producer,
+ sp<IGraphicBufferProducer> currentStateSurface,
+ sp<IGraphicBufferProducer> bqProducer,
+ sp<IGraphicBufferConsumer> bqConsumer, int currentStateType);
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_UTILS_H
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index f760200..973a8bc 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <cutils/compiler.h>
+#include <cutils/iosched_policy.h>
#include <gui/BitTube.h>
#include <gui/IDisplayEventConnection.h>
@@ -91,6 +92,7 @@ void EventThread::sendVsyncHintOnLocked() {
void EventThread::onFirstRef() {
run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
+ android_set_rt_ioprio(getTid(), 1);
}
sp<EventThread::Connection> EventThread::createEventConnection() const {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5ff79a9..bcd5915 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -320,7 +320,7 @@ Rect Layer::getContentCrop() const {
return crop;
}
-static Rect reduce(const Rect& win, const Region& exclude) {
+Rect Layer::reduce(const Rect& win, const Region& exclude) const{
if (CC_LIKELY(exclude.isEmpty())) {
return win;
}
@@ -494,6 +494,7 @@ void Layer::setGeometry(
frame.intersect(hw->getViewport(), &frame);
const Transform& tr(hw->getTransform());
layer.setFrame(tr.transform(frame));
+ setPosition(hw, layer, s);
layer.setCrop(computeCrop(hw));
layer.setPlaneAlpha(s.alpha);
@@ -578,6 +579,7 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
}
}
}
+ setAcquiredFenceIfBlit(fenceFd, layer);
layer.setAcquireFenceFd(fenceFd);
}
@@ -664,7 +666,7 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
RenderEngine& engine(mFlinger->getRenderEngine());
- if (!blackOutLayer) {
+ if (!blackOutLayer || canAllowGPUForProtected()) {
// TODO: we could be more subtle with isFixedSize()
const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c1e5e9f..c0c8bf5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -71,6 +71,9 @@ class Layer : public SurfaceFlingerConsumer::ContentsChangedListener {
static int32_t sSequence;
public:
+#ifdef QTI_BSP
+ friend class ExLayer;
+#endif
mutable bool contentDirty;
// regions below are in window-manager space
Region visibleRegion;
@@ -204,7 +207,7 @@ public:
void setGeometry(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer);
- void setPerFrameData(const sp<const DisplayDevice>& hw,
+ virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer);
void setAcquireFence(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer);
@@ -285,6 +288,21 @@ public:
// the current orientation of the display device.
void updateTransformHint(const sp<const DisplayDevice>& hw) const;
+ /* ------------------------------------------------------------------------
+ * Extensions
+ */
+ virtual bool isExtOnly() const { return false; }
+ virtual bool isIntOnly() const { return false; }
+ virtual bool isSecureDisplay() const { return false; }
+ virtual bool isYuvLayer() const { return false; }
+ virtual void setPosition(const sp<const DisplayDevice>& /*hw*/,
+ HWComposer::HWCLayerInterface& /*layer*/,
+ const State& /*state*/) { }
+ virtual void setAcquiredFenceIfBlit(int& /*fenceFd */,
+ HWComposer::HWCLayerInterface& /*layer */) { }
+ virtual bool canAllowGPUForProtected() const { return false; }
+
+
/*
* returns the rectangle that crops the content of the layer and scales it
* to the layer's size.
@@ -336,6 +354,7 @@ protected:
LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer);
};
+ Rect reduce(const Rect& win, const Region& exclude) const;
private:
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 14aa328..b8d549a 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -58,6 +58,15 @@ bool LayerDim::isVisible() const {
return !(s.flags & layer_state_t::eLayerHidden) && s.alpha;
}
+void LayerDim::setPerFrameData(const sp<const DisplayDevice>& hw,
+ HWComposer::HWCLayerInterface& layer) {
+ HWComposer& hwc = mFlinger->getHwComposer();
+
+ Layer::setPerFrameData(hw, layer);
+ if (hwc.hasDimComposition()) {
+ layer.setDim();
+ }
+}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index a0cfca9..b66591b 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -40,6 +40,8 @@ public:
virtual bool isSecure() const { return false; }
virtual bool isFixedSize() const { return true; }
virtual bool isVisible() const;
+ virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
+ HWComposer::HWCLayerInterface& layer);
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
index 1a9f59b..853a4eb 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
@@ -92,14 +92,29 @@ void GLES11RenderEngine::setViewportAndProjection(
case Transform::ROT_0:
break;
case Transform::ROT_90:
- glRotatef(90, 0, 0, 1);
+ {
+ float x1 = (l+r)/2;
+ float y1 = (t+b)/2;
+ glTranslatef(x1-y1, x1+y1, 0);
+ glRotatef(270, 0, 0, 1);
break;
+ }
case Transform::ROT_180:
+ {
+ float x1 = (l+r)/2;
+ float y1 = (t+b)/2;
+ glTranslatef(x1*2, y1*2, 0);
glRotatef(180, 0, 0, 1);
break;
+ }
case Transform::ROT_270:
- glRotatef(270, 0, 0, 1);
+ {
+ float x1 = (l+r)/2;
+ float y1 = (t+b)/2;
+ glTranslatef(x1+y1, y1-x1, 0);
+ glRotatef(90, 0, 0, 1);
break;
+ }
default:
break;
}
@@ -210,28 +225,46 @@ void GLES11RenderEngine::disableBlending() {
}
void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status) {
+ uint32_t* texName, uint32_t* fbName, uint32_t* status,
+ bool useReadPixels, int reqWidth, int reqHeight) {
GLuint tname, name;
- // turn our EGLImage into a texture
- glGenTextures(1, &tname);
- glBindTexture(GL_TEXTURE_2D, tname);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
-
- // create a Framebuffer Object to render into
- glGenFramebuffersOES(1, &name);
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
- glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
- GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
+ if (!useReadPixels) {
+ // turn our EGLImage into a texture
+ glGenTextures(1, &tname);
+ glBindTexture(GL_TEXTURE_2D, tname);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+
+ // create a Framebuffer Object to render into
+ glGenFramebuffersOES(1, &name);
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+ glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
+ GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
+ } else {
+ // since we're going to use glReadPixels() anyways,
+ // use an intermediate renderbuffer instead
+ glGenRenderbuffersOES(1, &tname);
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
+ glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, reqWidth, reqHeight);
+ // create a FBO to render into
+ glGenFramebuffersOES(1, &name);
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
+ GL_RENDERBUFFER_OES, tname);
+ }
*status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
*texName = tname;
*fbName = name;
}
-void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
+void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName,
+ bool useReadPixels) {
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
glDeleteFramebuffersOES(1, &fbName);
- glDeleteTextures(1, &texName);
+ if (!useReadPixels)
+ glDeleteTextures(1, &texName);
+ else
+ glDeleteRenderbuffersOES(1, &texName);
}
void GLES11RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
index 08de646..77824ce 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
@@ -40,8 +40,9 @@ class GLES11RenderEngine : public RenderEngine {
GLint mMaxTextureSize;
virtual void bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status);
- virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
+ uint32_t* texName, uint32_t* fbName, uint32_t* status, bool useReadPixels,
+ int reqWidth, int reqHeight);
+ virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, bool useReadPixels);
public:
GLES11RenderEngine();
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 1fabaf5..a35aa78 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -185,27 +185,44 @@ void GLES20RenderEngine::disableBlending() {
void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status) {
+ uint32_t* texName, uint32_t* fbName, uint32_t* status,
+ bool useReadPixels, int reqWidth, int reqHeight) {
GLuint tname, name;
- // turn our EGLImage into a texture
- glGenTextures(1, &tname);
- glBindTexture(GL_TEXTURE_2D, tname);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
-
- // create a Framebuffer Object to render into
- glGenFramebuffers(1, &name);
- glBindFramebuffer(GL_FRAMEBUFFER, name);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
+ if (!useReadPixels) {
+ // turn our EGLImage into a texture
+ glGenTextures(1, &tname);
+ glBindTexture(GL_TEXTURE_2D, tname);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+
+ // create a Framebuffer Object to render into
+ glGenFramebuffers(1, &name);
+ glBindFramebuffer(GL_FRAMEBUFFER, name);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
+ } else {
+ // since we're going to use glReadPixels() anyways,
+ // use an intermediate renderbuffer instead
+ glGenRenderbuffers(1, &tname);
+ glBindRenderbuffer(GL_RENDERBUFFER, tname);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, reqWidth, reqHeight);
+ // create a FBO to render into
+ glGenFramebuffers(1, &name);
+ glBindFramebuffer(GL_FRAMEBUFFER, name);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, tname);
+ }
*status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
*texName = tname;
*fbName = name;
}
-void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
+void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName,
+ bool useReadPixels) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbName);
- glDeleteTextures(1, &texName);
+ if (!useReadPixels)
+ glDeleteTextures(1, &texName);
+ else
+ glDeleteRenderbuffers(1, &texName);
}
void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 819356a..6074a3d 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -55,8 +55,9 @@ class GLES20RenderEngine : public RenderEngine {
Vector<Group> mGroupStack;
virtual void bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status);
- virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
+ uint32_t* texName, uint32_t* fbName, uint32_t* status,
+ bool useReadPixels, int reqWidth, int reqHeight);
+ virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, bool useReadPixels);
public:
GLES20RenderEngine();
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 7cd42e4..cb1d14c 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -83,7 +83,6 @@ RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) {
EGL_CONTEXT_CLIENT_VERSION, contextClientVersion, // MUST be first
#ifdef EGL_IMG_context_priority
#ifdef HAS_CONTEXT_PRIORITY
-#warning "using EGL_IMG_context_priority"
EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
#endif
#endif
@@ -262,9 +261,11 @@ void RenderEngine::dump(String8& result) {
// ---------------------------------------------------------------------------
RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
- RenderEngine& engine, EGLImageKHR image) : mEngine(engine)
+ RenderEngine& engine, EGLImageKHR image, bool useReadPixels,
+ int reqWidth, int reqHeight) : mEngine(engine), mUseReadPixels(useReadPixels)
{
- mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus);
+ mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus,
+ useReadPixels, reqWidth, reqHeight);
ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES,
"glCheckFramebufferStatusOES error %d", mStatus);
@@ -272,7 +273,7 @@ RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() {
// back to main framebuffer
- mEngine.unbindFramebuffer(mTexName, mFbName);
+ mEngine.unbindFramebuffer(mTexName, mFbName, mUseReadPixels);
}
status_t RenderEngine::BindImageAsFramebuffer::getStatus() const {
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 31a961e..c9a043a 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -51,8 +51,11 @@ class RenderEngine {
EGLContext mEGLContext;
void setEGLHandles(EGLConfig config, EGLContext ctxt);
- virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, uint32_t* status) = 0;
- virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0;
+ virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName,
+ uint32_t* fbName, uint32_t* status, bool useReadPixels, int reqWidth,
+ int reqHeight) = 0;
+ virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName,
+ bool useReadPixels) = 0;
protected:
RenderEngine();
@@ -83,8 +86,10 @@ public:
RenderEngine& mEngine;
uint32_t mTexName, mFbName;
uint32_t mStatus;
+ bool mUseReadPixels;
public:
- BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image);
+ BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image,
+ bool useReadPixels, int reqWidth, int reqHeight);
~BindImageAsFramebuffer();
int getStatus() const;
};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fdc3650..fc99fa0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -27,6 +27,7 @@
#include <EGL/egl.h>
#include <cutils/log.h>
+#include <cutils/iosched_policy.h>
#include <cutils/properties.h>
#include <binder/IPCThreadState.h>
@@ -77,6 +78,7 @@
#include "RenderEngine/RenderEngine.h"
#include <cutils/compiler.h>
+#include "DisplayUtils.h"
#define DISPLAY_COUNT 1
@@ -122,6 +124,8 @@ const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"
const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
const String16 sDump("android.permission.DUMP");
+static sp<Layer> lastSurfaceViewLayer;
+
// ---------------------------------------------------------------------------
SurfaceFlinger::SurfaceFlinger()
@@ -456,7 +460,7 @@ void SurfaceFlinger::init() {
// Initialize the H/W composer object. There may or may not be an
// actual hardware composer underneath.
- mHwc = new HWComposer(this,
+ mHwc = DisplayUtils::getInstance()->getHWCInstance(this,
*static_cast<HWComposer::EventHandler *>(this));
// get a RenderEngine for the given display / config (can't fail)
@@ -497,6 +501,13 @@ void SurfaceFlinger::init() {
ALOGD("marking display %zu as acquired/unblanked", i);
hw->setPowerMode(HWC_POWER_MODE_NORMAL);
}
+ // When a non-virtual display device is added at boot time,
+ // update the active config by querying HWC otherwise the
+ // default config (config 0) will be used.
+ int activeConfig = mHwc->getActiveConfig(hwcId);
+ if (activeConfig >= 0) {
+ hw->setActiveConfig(activeConfig);
+ }
mDisplays.add(token, hw);
}
}
@@ -507,6 +518,7 @@ void SurfaceFlinger::init() {
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
+ android_set_rt_ioprio(mEventControlThread->getTid(), 1);
// set a fake vsync period if there is no HWComposer
if (mHwc->initCheck() != NO_ERROR) {
@@ -695,8 +707,10 @@ void SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mo
return;
}
- hw->setActiveConfig(mode);
- getHwComposer().setActiveConfig(type, mode);
+ status_t status = getHwComposer().setActiveConfig(type, mode);
+ if (status == NO_ERROR) {
+ hw->setActiveConfig(mode);
+ }
}
status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
@@ -869,6 +883,7 @@ void SurfaceFlinger::onHotplugReceived(int type, bool connected) {
} else {
mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
mBuiltinDisplays[type].clear();
+ updateVisibleRegionsDirty();
}
setTransactionFlags(eDisplayTransactionNeeded);
@@ -1067,6 +1082,7 @@ void SurfaceFlinger::postComposition()
}
void SurfaceFlinger::rebuildLayerStacks() {
+ updateExtendedMode();
// rebuild the visible layer list per screen
if (CC_UNLIKELY(mVisibleRegionsDirty)) {
ATRACE_CALL();
@@ -1082,14 +1098,13 @@ void SurfaceFlinger::rebuildLayerStacks() {
const Transform& tr(hw->getTransform());
const Rect bounds(hw->getBounds());
if (hw->isDisplayOn()) {
- SurfaceFlinger::computeVisibleRegions(layers,
+ computeVisibleRegions(hw->getHwcDisplayId(), layers,
hw->getLayerStack(), dirtyRegion, opaqueRegion);
const size_t count = layers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(layers[i]);
- const Layer::State& s(layer->getDrawingState());
- if (s.layerStack == hw->getLayerStack()) {
+ {
Region drawRegion(tr.transform(
layer->visibleNonTransparentRegion));
drawRegion.andSelf(bounds);
@@ -1169,6 +1184,8 @@ void SurfaceFlinger::setUpHWComposer() {
sp<const DisplayDevice> hw(mDisplays[dpy]);
const int32_t id = hw->getHwcDisplayId();
if (id >= 0) {
+ bool freezeSurfacePresent = false;
+ isfreezeSurfacePresent(freezeSurfacePresent, hw, id);
const Vector< sp<Layer> >& currentLayers(
hw->getVisibleLayersSortedByZ());
const size_t count = currentLayers.size();
@@ -1181,6 +1198,11 @@ void SurfaceFlinger::setUpHWComposer() {
*/
const sp<Layer>& layer(currentLayers[i]);
layer->setPerFrameData(hw, *cur);
+ setOrientationEventControl(freezeSurfacePresent,id);
+ if(!strncmp(layer->getName(), "SurfaceView",
+ 11)) {
+ lastSurfaceViewLayer = layer;
+ }
}
}
}
@@ -1454,12 +1476,10 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
hwcDisplayId = allocateHwcDisplayId(state.type);
}
- sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
- *mHwc, hwcDisplayId, state.surface,
- bqProducer, bqConsumer, state.displayName);
+ DisplayUtils::getInstance()->initVDSInstance(mHwc, hwcDisplayId,
+ state.surface, dispSurface, producer, bqProducer, bqConsumer,
+ state.displayName, state.isSecure, state.type);
- dispSurface = vds;
- producer = vds;
}
} else {
ALOGE_IF(state.surface!=NULL,
@@ -1475,7 +1495,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
}
const wp<IBinder>& display(curr.keyAt(i));
- if (dispSurface != NULL) {
+ if (dispSurface != NULL && producer != NULL) {
sp<DisplayDevice> hw = new DisplayDevice(this,
state.type, hwcDisplayId,
mHwc->getFormat(hwcDisplayId), state.isSecure,
@@ -1485,6 +1505,16 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
hw->setProjection(state.orientation,
state.viewport, state.frame);
hw->setDisplayName(state.displayName);
+ // When a new display device is added update the active
+ // config by querying HWC otherwise the default config
+ // (config 0) will be used.
+ if (hwcDisplayId >= DisplayDevice::DISPLAY_PRIMARY &&
+ hwcDisplayId < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
+ int activeConfig = mHwc->getActiveConfig(hwcDisplayId);
+ if (activeConfig >= 0) {
+ hw->setActiveConfig(activeConfig);
+ }
+ }
mDisplays.add(display, hw);
if (state.isVirtualDisplay()) {
if (hwcDisplayId >= 0) {
@@ -1643,7 +1673,7 @@ void SurfaceFlinger::commitTransaction()
mTransactionCV.broadcast();
}
-void SurfaceFlinger::computeVisibleRegions(
+void SurfaceFlinger::computeVisibleRegions(size_t dpy,
const LayerVector& currentLayers, uint32_t layerStack,
Region& outDirtyRegion, Region& outOpaqueRegion)
{
@@ -1654,6 +1684,9 @@ void SurfaceFlinger::computeVisibleRegions(
Region dirty;
outDirtyRegion.clear();
+ bool bIgnoreLayers = false;
+ int indexLOI = -1;
+ getIndexLOI(dpy, currentLayers, bIgnoreLayers, indexLOI);
size_t i = currentLayers.size();
while (i--) {
@@ -1662,8 +1695,9 @@ void SurfaceFlinger::computeVisibleRegions(
// start with the whole surface at its current location
const Layer::State& s(layer->getDrawingState());
- // only consider the layers on the given layer stack
- if (s.layerStack != layerStack)
+ if(updateLayerVisibleNonTransparentRegion(dpy, layer,
+ bIgnoreLayers, indexLOI,
+ layerStack, i))
continue;
/*
@@ -1954,7 +1988,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
// screen is already cleared here
if (!region.isEmpty()) {
// can happen with SurfaceView
- drawWormhole(hw, region);
+ drawWormHoleIfRequired(cur, end, hw, region);
}
}
@@ -2096,6 +2130,8 @@ void SurfaceFlinger::setTransactionState(
uint32_t flags)
{
ATRACE_CALL();
+
+ delayDPTransactionIfNeeded(displays);
Mutex::Autolock _l(mStateLock);
uint32_t transactionFlags = 0;
@@ -2342,7 +2378,7 @@ status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
break;
}
- *outLayer = new Layer(this, client, name, w, h, flags);
+ *outLayer = DisplayUtils::getInstance()->getLayerInstance(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w, h, format, flags);
if (err == NO_ERROR) {
*handle = (*outLayer)->getHandle();
@@ -2605,14 +2641,19 @@ void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index
if (name.isEmpty()) {
mAnimFrameTracker.dumpStats(result);
} else {
+ bool found = false;
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(currentLayers[i]);
if (name == layer->getName()) {
+ found = true;
layer->dumpFrameStats(result);
}
}
+ if (!found && !strncmp(name.string(), "SurfaceView", 11)) {
+ lastSurfaceViewLayer->dumpFrameStats(result);
+ }
}
}
@@ -3155,7 +3196,8 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
+ bool useIdentityTransform, ISurfaceComposer::Rotation rotation,
+ bool useReadPixels) {
if (CC_UNLIKELY(display == 0))
return BAD_VALUE;
@@ -3205,6 +3247,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
uint32_t minLayerZ,maxLayerZ;
bool useIdentityTransform;
Transform::orientation_flags rotation;
+ bool useReadPixels;
status_t result;
public:
MessageCaptureScreen(SurfaceFlinger* flinger,
@@ -3212,12 +3255,14 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation)
+ bool useIdentityTransform, Transform::orientation_flags rotation,
+ bool useReadPixels)
: flinger(flinger), display(display), producer(producer),
sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
useIdentityTransform(useIdentityTransform),
rotation(rotation),
+ useReadPixels(useReadPixels),
result(PERMISSION_DENIED)
{
}
@@ -3227,9 +3272,10 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
virtual bool handler() {
Mutex::Autolock _l(flinger->mStateLock);
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
+ bool useReadPixels = this->useReadPixels && !flinger->mGpuToCpuSupported;
result = flinger->captureScreenImplLocked(hw, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform, rotation);
+ useIdentityTransform, rotation, useReadPixels);
static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
return true;
}
@@ -3252,7 +3298,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
sp<MessageBase> msg = new MessageCaptureScreen(this,
display, IGraphicBufferProducer::asInterface( wrapper ),
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform, rotationFlags);
+ useIdentityTransform, rotationFlags, useReadPixels);
status_t res = postMessageAsync(msg);
if (res == NO_ERROR) {
@@ -3301,6 +3347,12 @@ void SurfaceFlinger::renderScreenImplLocked(
// make sure to clear all GL error flags
engine.checkErrors();
+ if (DisplayDevice::DISPLAY_PRIMARY == hw->getDisplayType() &&
+ hw->isPanelInverseMounted()) {
+ rotation = (Transform::orientation_flags)
+ (rotation ^ Transform::ROT_180);
+ }
+
// set-up our viewport
engine.setViewportAndProjection(
reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
@@ -3316,7 +3368,7 @@ void SurfaceFlinger::renderScreenImplLocked(
const Layer::State& state(layer->getDrawingState());
if (state.layerStack == hw->getLayerStack()) {
if (state.z >= minLayerZ && state.z <= maxLayerZ) {
- if (layer->isVisible()) {
+ if (canDrawLayerinScreenShot(hw,layer)) {
if (filtering) layer->setFiltering(true);
layer->draw(hw, useIdentityTransform);
if (filtering) layer->setFiltering(false);
@@ -3336,7 +3388,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation)
+ bool useIdentityTransform, Transform::orientation_flags rotation,
+ bool useReadPixels)
{
ATRACE_CALL();
@@ -3388,7 +3441,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(
if (image != EGL_NO_IMAGE_KHR) {
// this binds the given EGLImage as a framebuffer for the
// duration of this scope.
- RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
+ RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image,
+ useReadPixels, reqWidth, reqHeight);
if (imageBond.getStatus() == NO_ERROR) {
// this will in fact render into our dequeued buffer
// via an FBO, which means we didn't have to create
@@ -3435,6 +3489,15 @@ status_t SurfaceFlinger::captureScreenImplLocked(
ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
}
}
+ if (useReadPixels) {
+ sp<GraphicBuffer> buf = static_cast<GraphicBuffer*>(buffer);
+ void* vaddr;
+ if (buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, &vaddr) == NO_ERROR) {
+ getRenderEngine().readPixels(0, 0, buffer->stride, reqHeight,
+ (uint32_t *)vaddr);
+ buf->unlock();
+ }
+ }
if (DEBUG_SCREENSHOTS) {
uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
@@ -3492,6 +3555,44 @@ void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* v
}
}
+/* ------------------------------------------------------------------------
+ * Extensions
+ */
+
+bool SurfaceFlinger::updateLayerVisibleNonTransparentRegion(const int& /*dpy*/,
+ const sp<Layer>& layer, bool& /*bIgnoreLayers*/, int& /*indexLOI*/,
+ uint32_t layerStack, const int& /*i*/) {
+
+ const Layer::State& s(layer->getDrawingState());
+
+ // only consider the layers on the given layer stack
+ if (s.layerStack != layerStack) {
+ /* set the visible region as empty since we have removed the
+ * layerstack check in rebuildLayerStack() function
+ */
+ Region visibleNonTransRegion;
+ visibleNonTransRegion.set(Rect(0,0));
+ layer->setVisibleNonTransparentRegion(visibleNonTransRegion);
+
+ return true;
+ }
+
+ return false;
+}
+
+bool SurfaceFlinger::canDrawLayerinScreenShot(
+ const sp<const DisplayDevice>& /*hw*/,
+ const sp<Layer>& layer) {
+ return layer->isVisible();
+}
+
+void SurfaceFlinger::drawWormHoleIfRequired(HWComposer::LayerListIterator& /*cur*/,
+ const HWComposer::LayerListIterator& /*end*/,
+ const sp<const DisplayDevice>& hw,
+ const Region& region) {
+ drawWormhole(hw, region);
+}
+
// ---------------------------------------------------------------------------
SurfaceFlinger::LayerVector::LayerVector() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b3baadd..4bbb1f4 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -84,6 +84,10 @@ class SurfaceFlinger : public BnSurfaceComposer,
private HWComposer::EventHandler
{
public:
+#ifdef QTI_BSP
+ friend class ExSurfaceFlinger;
+#endif
+
static char const* getServiceName() ANDROID_API {
return "SurfaceFlinger";
}
@@ -138,6 +142,7 @@ private:
friend class Client;
friend class DisplayEventConnection;
friend class Layer;
+ friend class LayerDim;
friend class MonitoredProducer;
// This value is specified in number of frames. Log frame stats at most
@@ -207,7 +212,8 @@ private:
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, ISurfaceComposer::Rotation rotation);
+ bool useIdentityTransform, ISurfaceComposer::Rotation rotation,
+ bool isCpuConsumer);
virtual status_t getDisplayStats(const sp<IBinder>& display,
DisplayStatInfo* stats);
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
@@ -235,6 +241,43 @@ private:
virtual void onHotplugReceived(int disp, bool connected);
/* ------------------------------------------------------------------------
+ * Extensions
+ */
+ virtual void updateExtendedMode() { }
+
+ virtual void getIndexLOI(size_t /*dpy*/,
+ const LayerVector& /*currentLayers*/,
+ bool& /*bIgnoreLayers*/,
+ int& /*indexLOI*/) { }
+
+ virtual bool updateLayerVisibleNonTransparentRegion(
+ const int& dpy, const sp<Layer>& layer,
+ bool& bIgnoreLayers, int& indexLOI,
+ uint32_t layerStack, const int& i);
+
+ virtual void delayDPTransactionIfNeeded(
+ const Vector<DisplayState>& /*displays*/) { }
+
+ virtual bool canDrawLayerinScreenShot(
+ const sp<const DisplayDevice>& hw,
+ const sp<Layer>& layer);
+
+ virtual void isfreezeSurfacePresent(
+ bool& freezeSurfacePresent,
+ const sp<const DisplayDevice>& /*hw*/,
+ const int32_t& /*id*/) { freezeSurfacePresent = false; }
+
+ virtual void setOrientationEventControl(
+ bool& /*freezeSurfacePresent*/,
+ const int32_t& /*id*/) { }
+
+ virtual void updateVisibleRegionsDirty() { }
+
+ virtual void drawWormHoleIfRequired(HWComposer::LayerListIterator &cur,
+ const HWComposer::LayerListIterator &end,
+ const sp<const DisplayDevice>& hw,
+ const Region& region);
+ /* ------------------------------------------------------------------------
* Message handling
*/
void waitForEvent();
@@ -329,7 +372,8 @@ private:
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation);
+ bool useIdentityTransform, Transform::orientation_flags rotation,
+ bool useReadPixels);
/* ------------------------------------------------------------------------
* EGL
@@ -373,7 +417,7 @@ private:
* Compositing
*/
void invalidateHwcGeometry();
- static void computeVisibleRegions(
+ void computeVisibleRegions(size_t dpy,
const LayerVector& currentLayers, uint32_t layerStack,
Region& dirtyRegion, Region& opaqueRegion);
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index a74bc4c..6127cf6 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -22,6 +22,7 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include "SurfaceFlinger.h"
+#include "DisplayUtils.h"
using namespace android;
@@ -35,7 +36,7 @@ int main(int, char**) {
ps->startThreadPool();
// instantiate surfaceflinger
- sp<SurfaceFlinger> flinger = new SurfaceFlinger();
+ sp<SurfaceFlinger> flinger = DisplayUtils::getInstance()->getSFInstance();
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);