Merge branch 'cm-13.0' of https://github.com/CyanogenMod/android_frameworks_native into replicant-6.0
This commit is contained in:
commit
d3ad4f1e64
25
build/phone-xxhdpi-3072-dalvik-heap.mk
Normal file
25
build/phone-xxhdpi-3072-dalvik-heap.mk
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2016 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=288m \
|
||||||
|
dalvik.vm.heapsize=768m \
|
||||||
|
dalvik.vm.heaptargetutilization=0.75 \
|
||||||
|
dalvik.vm.heapminfree=512k \
|
||||||
|
dalvik.vm.heapmaxfree=8m
|
30
build/phone-xxhdpi-3072-hwui-memory.mk
Normal file
30
build/phone-xxhdpi-3072-hwui-memory.mk
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2016 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.path_cache_size=32 \
|
||||||
|
ro.hwui.gradient_cache_size=1 \
|
||||||
|
ro.hwui.drop_shadow_cache_size=6 \
|
||||||
|
ro.hwui.r_buffer_cache_size=8 \
|
||||||
|
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
|
@ -18,8 +18,8 @@
|
|||||||
|
|
||||||
PRODUCT_PROPERTY_OVERRIDES += \
|
PRODUCT_PROPERTY_OVERRIDES += \
|
||||||
dalvik.vm.heapstartsize=8m \
|
dalvik.vm.heapstartsize=8m \
|
||||||
dalvik.vm.heapgrowthlimit=256m \
|
dalvik.vm.heapgrowthlimit=288m \
|
||||||
dalvik.vm.heapsize=512m \
|
dalvik.vm.heapsize=768m \
|
||||||
dalvik.vm.heaptargetutilization=0.75 \
|
dalvik.vm.heaptargetutilization=0.75 \
|
||||||
dalvik.vm.heapminfree=2m \
|
dalvik.vm.heapminfree=2m \
|
||||||
dalvik.vm.heapmaxfree=8m
|
dalvik.vm.heapmaxfree=8m
|
||||||
|
25
build/phone-xxxhdpi-4096-dalvik-heap.mk
Normal file
25
build/phone-xxxhdpi-4096-dalvik-heap.mk
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2016 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 4G phone
|
||||||
|
|
||||||
|
PRODUCT_PROPERTY_OVERRIDES += \
|
||||||
|
dalvik.vm.heapstartsize=8m \
|
||||||
|
dalvik.vm.heapgrowthlimit=384m \
|
||||||
|
dalvik.vm.heapsize=1024m \
|
||||||
|
dalvik.vm.heaptargetutilization=0.75 \
|
||||||
|
dalvik.vm.heapminfree=4m \
|
||||||
|
dalvik.vm.heapmaxfree=16m
|
30
build/phone-xxxhdpi-4096-hwui-memory.mk
Normal file
30
build/phone-xxxhdpi-4096-hwui-memory.mk
Normal file
@ -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=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
|
@ -272,7 +272,9 @@ static void dumpstate() {
|
|||||||
char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
|
char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
|
||||||
char network[PROPERTY_VALUE_MAX], date[80];
|
char network[PROPERTY_VALUE_MAX], date[80];
|
||||||
char build_type[PROPERTY_VALUE_MAX];
|
char build_type[PROPERTY_VALUE_MAX];
|
||||||
|
char cm_version[PROPERTY_VALUE_MAX];
|
||||||
|
|
||||||
|
property_get("ro.cm.version", cm_version, "(unknown)");
|
||||||
property_get("ro.build.display.id", build, "(unknown)");
|
property_get("ro.build.display.id", build, "(unknown)");
|
||||||
property_get("ro.build.fingerprint", fingerprint, "(unknown)");
|
property_get("ro.build.fingerprint", fingerprint, "(unknown)");
|
||||||
property_get("ro.build.type", build_type, "(unknown)");
|
property_get("ro.build.type", build_type, "(unknown)");
|
||||||
@ -286,6 +288,7 @@ static void dumpstate() {
|
|||||||
printf("========================================================\n");
|
printf("========================================================\n");
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
printf("CM Version: %s\n", cm_version);
|
||||||
printf("Build: %s\n", build);
|
printf("Build: %s\n", build);
|
||||||
printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */
|
printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */
|
||||||
printf("Bootloader: %s\n", bootloader);
|
printf("Bootloader: %s\n", bootloader);
|
||||||
@ -302,7 +305,7 @@ static void dumpstate() {
|
|||||||
dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
|
dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
|
||||||
dump_file("MEMORY INFO", "/proc/meminfo");
|
dump_file("MEMORY INFO", "/proc/meminfo");
|
||||||
run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
|
run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
|
||||||
run_command("PROCRANK", 20, "procrank", NULL);
|
run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL);
|
||||||
dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
|
dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
|
||||||
dump_file("VMALLOC INFO", "/proc/vmallocinfo");
|
dump_file("VMALLOC INFO", "/proc/vmallocinfo");
|
||||||
dump_file("SLAB INFO", "/proc/slabinfo");
|
dump_file("SLAB INFO", "/proc/slabinfo");
|
||||||
|
@ -18,7 +18,7 @@ LOCAL_MODULE_TAGS := optional
|
|||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_SHARED_LIBRARIES := liblog libselinux
|
LOCAL_SHARED_LIBRARIES := liblog libcutils libselinux
|
||||||
LOCAL_SRC_FILES := service_manager.c binder.c
|
LOCAL_SRC_FILES := service_manager.c binder.c
|
||||||
LOCAL_CFLAGS += $(svc_c_flags)
|
LOCAL_CFLAGS += $(svc_c_flags)
|
||||||
LOCAL_MODULE := servicemanager
|
LOCAL_MODULE := servicemanager
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cutils/multiuser.h>
|
||||||
|
|
||||||
#include <private/android_filesystem_config.h>
|
#include <private/android_filesystem_config.h>
|
||||||
|
|
||||||
#include <selinux/android.h>
|
#include <selinux/android.h>
|
||||||
@ -107,9 +109,14 @@ static bool check_mac_perms_from_lookup(pid_t spid, const char *perm, const char
|
|||||||
return allowed;
|
return allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid)
|
static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
|
||||||
{
|
{
|
||||||
const char *perm = "add";
|
const char *perm = "add";
|
||||||
|
|
||||||
|
if (multiuser_get_app_id(uid) >= AID_APP) {
|
||||||
|
return 0; /* Don't allow apps to register services */
|
||||||
|
}
|
||||||
|
|
||||||
return check_mac_perms_from_lookup(spid, perm, str8(name, name_len)) ? 1 : 0;
|
return check_mac_perms_from_lookup(spid, perm, str8(name, name_len)) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +211,7 @@ int do_add_service(struct binder_state *bs,
|
|||||||
if (!handle || (len == 0) || (len > 127))
|
if (!handle || (len == 0) || (len > 127))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!svc_can_register(s, len, spid)) {
|
if (!svc_can_register(s, len, spid, uid)) {
|
||||||
ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
|
ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
|
||||||
str8(s, len), handle, uid);
|
str8(s, len), handle, uid);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -45,6 +45,19 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This flag indicates that the window that received this motion event is partly
|
||||||
|
* or wholly obscured by another visible window above it. This flag is set to true
|
||||||
|
* even if the event did not directly pass through the obscured area.
|
||||||
|
* A security sensitive application can check this flag to identify situations in which
|
||||||
|
* a malicious application may have covered up part of its content for the purpose
|
||||||
|
* of misleading the user or hijacking touches. An appropriate response might be
|
||||||
|
* to drop the suspect touches or to take additional precautions to confirm the user's
|
||||||
|
* actual intent.
|
||||||
|
*/
|
||||||
|
AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 0x2,
|
||||||
|
|
||||||
/* Motion event is inconsistent with previously sent motion events. */
|
/* Motion event is inconsistent with previously sent motion events. */
|
||||||
AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
|
AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
|
||||||
};
|
};
|
||||||
|
@ -25,6 +25,7 @@ namespace android {
|
|||||||
|
|
||||||
class FrameStats : public LightFlattenable<FrameStats> {
|
class FrameStats : public LightFlattenable<FrameStats> {
|
||||||
public:
|
public:
|
||||||
|
FrameStats() : refreshPeriodNano(0) {};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Approximate refresh time, in nanoseconds.
|
* Approximate refresh time, in nanoseconds.
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include <binder/IMemory.h>
|
#include <binder/IMemory.h>
|
||||||
|
#include <cutils/log.h>
|
||||||
#include <utils/KeyedVector.h>
|
#include <utils/KeyedVector.h>
|
||||||
#include <utils/threads.h>
|
#include <utils/threads.h>
|
||||||
#include <utils/Atomic.h>
|
#include <utils/Atomic.h>
|
||||||
@ -191,15 +192,26 @@ sp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const
|
|||||||
if (heap != 0) {
|
if (heap != 0) {
|
||||||
mHeap = interface_cast<IMemoryHeap>(heap);
|
mHeap = interface_cast<IMemoryHeap>(heap);
|
||||||
if (mHeap != 0) {
|
if (mHeap != 0) {
|
||||||
mOffset = o;
|
size_t heapSize = mHeap->getSize();
|
||||||
mSize = s;
|
if (s <= heapSize
|
||||||
|
&& o >= 0
|
||||||
|
&& (static_cast<size_t>(o) <= heapSize - s)) {
|
||||||
|
mOffset = o;
|
||||||
|
mSize = s;
|
||||||
|
} else {
|
||||||
|
// Hm.
|
||||||
|
android_errorWriteWithInfoLog(0x534e4554,
|
||||||
|
"26877992", -1, NULL, 0);
|
||||||
|
mOffset = 0;
|
||||||
|
mSize = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (offset) *offset = mOffset;
|
if (offset) *offset = mOffset;
|
||||||
if (size) *size = mSize;
|
if (size) *size = mSize;
|
||||||
return mHeap;
|
return (mSize > 0) ? mHeap : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -1083,8 +1083,16 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
|
|||||||
<< reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
|
<< reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
|
||||||
}
|
}
|
||||||
if (tr.target.ptr) {
|
if (tr.target.ptr) {
|
||||||
sp<BBinder> b((BBinder*)tr.cookie);
|
// We only have a weak reference on the target object, so we must first try to
|
||||||
error = b->transact(tr.code, buffer, &reply, tr.flags);
|
// safely acquire a strong reference before doing anything else with it.
|
||||||
|
if (reinterpret_cast<RefBase::weakref_type*>(
|
||||||
|
tr.target.ptr)->attemptIncStrong(this)) {
|
||||||
|
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
|
||||||
|
&reply, tr.flags);
|
||||||
|
reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
|
||||||
|
} else {
|
||||||
|
error = UNKNOWN_TRANSACTION;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
|
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
//#define LOG_NDEBUG 0
|
//#define LOG_NDEBUG 0
|
||||||
|
|
||||||
#include <binder/Parcel.h>
|
#include <binder/Parcel.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <binder/IPCThreadState.h>
|
#include <binder/IPCThreadState.h>
|
||||||
#include <binder/Binder.h>
|
#include <binder/Binder.h>
|
||||||
@ -42,6 +44,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifndef INT32_MAX
|
#ifndef INT32_MAX
|
||||||
#define INT32_MAX ((int32_t)(2147483647))
|
#define INT32_MAX ((int32_t)(2147483647))
|
||||||
@ -95,6 +100,32 @@ enum {
|
|||||||
BLOB_ASHMEM_MUTABLE = 2,
|
BLOB_ASHMEM_MUTABLE = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static dev_t ashmem_rdev()
|
||||||
|
{
|
||||||
|
static dev_t __ashmem_rdev;
|
||||||
|
static pthread_mutex_t __ashmem_rdev_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&__ashmem_rdev_lock);
|
||||||
|
|
||||||
|
dev_t rdev = __ashmem_rdev;
|
||||||
|
if (!rdev) {
|
||||||
|
int fd = TEMP_FAILURE_RETRY(open("/dev/ashmem", O_RDONLY));
|
||||||
|
if (fd >= 0) {
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
int ret = TEMP_FAILURE_RETRY(fstat(fd, &st));
|
||||||
|
close(fd);
|
||||||
|
if ((ret >= 0) && S_ISCHR(st.st_mode)) {
|
||||||
|
rdev = __ashmem_rdev = st.st_rdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&__ashmem_rdev_lock);
|
||||||
|
|
||||||
|
return rdev;
|
||||||
|
}
|
||||||
|
|
||||||
void acquire_object(const sp<ProcessState>& proc,
|
void acquire_object(const sp<ProcessState>& proc,
|
||||||
const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
|
const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
|
||||||
{
|
{
|
||||||
@ -123,8 +154,10 @@ void acquire_object(const sp<ProcessState>& proc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case BINDER_TYPE_FD: {
|
case BINDER_TYPE_FD: {
|
||||||
if (obj.cookie != 0) {
|
if ((obj.cookie != 0) && (outAshmemSize != NULL)) {
|
||||||
if (outAshmemSize != NULL) {
|
struct stat st;
|
||||||
|
int ret = fstat(obj.handle, &st);
|
||||||
|
if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
|
||||||
// If we own an ashmem fd, keep track of how much memory it refers to.
|
// If we own an ashmem fd, keep track of how much memory it refers to.
|
||||||
int size = ashmem_get_size_region(obj.handle);
|
int size = ashmem_get_size_region(obj.handle);
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
@ -173,15 +206,18 @@ static void release_object(const sp<ProcessState>& proc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case BINDER_TYPE_FD: {
|
case BINDER_TYPE_FD: {
|
||||||
if (outAshmemSize != NULL) {
|
if (obj.cookie != 0) { // owned
|
||||||
if (obj.cookie != 0) {
|
if (outAshmemSize != NULL) {
|
||||||
int size = ashmem_get_size_region(obj.handle);
|
struct stat st;
|
||||||
if (size > 0) {
|
int ret = fstat(obj.handle, &st);
|
||||||
*outAshmemSize -= size;
|
if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
|
||||||
|
int size = ashmem_get_size_region(obj.handle);
|
||||||
|
if (size > 0) {
|
||||||
|
*outAshmemSize -= size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close(obj.handle);
|
|
||||||
}
|
}
|
||||||
|
close(obj.handle);
|
||||||
#ifdef DISABLE_ASHMEM_TRACKING
|
#ifdef DISABLE_ASHMEM_TRACKING
|
||||||
} else if (obj.cookie != 0) {
|
} else if (obj.cookie != 0) {
|
||||||
close(obj.handle);
|
close(obj.handle);
|
||||||
@ -1389,7 +1425,13 @@ native_handle* Parcel::readNativeHandle() const
|
|||||||
|
|
||||||
for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
|
for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
|
||||||
h->data[i] = dup(readFileDescriptor());
|
h->data[i] = dup(readFileDescriptor());
|
||||||
if (h->data[i] < 0) err = BAD_VALUE;
|
if (h->data[i] < 0) {
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
close(h->data[j]);
|
||||||
|
}
|
||||||
|
native_handle_delete(h);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
err = read(h->data + numFds, sizeof(int)*numInts);
|
err = read(h->data + numFds, sizeof(int)*numInts);
|
||||||
if (err != NO_ERROR) {
|
if (err != NO_ERROR) {
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
#include <gui/IConsumerListener.h>
|
#include <gui/IConsumerListener.h>
|
||||||
#include <gui/IProducerListener.h>
|
#include <gui/IProducerListener.h>
|
||||||
|
|
||||||
|
#include <binder/IPCThreadState.h>
|
||||||
|
#include <binder/PermissionCache.h>
|
||||||
|
#include <private/android_filesystem_config.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
|
BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
|
||||||
@ -572,7 +576,18 @@ sp<NativeHandle> BufferQueueConsumer::getSidebandStream() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
|
void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
|
||||||
mCore->dump(result, prefix);
|
const IPCThreadState* ipc = IPCThreadState::self();
|
||||||
|
const pid_t pid = ipc->getCallingPid();
|
||||||
|
const uid_t uid = ipc->getCallingUid();
|
||||||
|
if ((uid != AID_SHELL)
|
||||||
|
&& !PermissionCache::checkPermission(String16(
|
||||||
|
"android.permission.DUMP"), pid, uid)) {
|
||||||
|
result.appendFormat("Permission Denial: can't dump BufferQueueConsumer "
|
||||||
|
"from pid=%d, uid=%d\n", pid, uid);
|
||||||
|
android_errorWriteWithInfoLog(0x534e4554, "27046057", uid, NULL, 0);
|
||||||
|
} else {
|
||||||
|
mCore->dump(result, prefix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
@ -349,7 +349,7 @@ status_t BnGraphicBufferConsumer::onTransact(
|
|||||||
}
|
}
|
||||||
case GET_RELEASED_BUFFERS: {
|
case GET_RELEASED_BUFFERS: {
|
||||||
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
|
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
|
||||||
uint64_t slotMask;
|
uint64_t slotMask = 0;
|
||||||
status_t result = getReleasedBuffers(&slotMask);
|
status_t result = getReleasedBuffers(&slotMask);
|
||||||
reply->writeInt64(static_cast<int64_t>(slotMask));
|
reply->writeInt64(static_cast<int64_t>(slotMask));
|
||||||
reply->writeInt32(result);
|
reply->writeInt32(result);
|
||||||
|
@ -435,6 +435,7 @@ status_t BnGraphicBufferProducer::onTransact(
|
|||||||
QueueBufferOutput* const output =
|
QueueBufferOutput* const output =
|
||||||
reinterpret_cast<QueueBufferOutput *>(
|
reinterpret_cast<QueueBufferOutput *>(
|
||||||
reply->writeInplace(sizeof(QueueBufferOutput)));
|
reply->writeInplace(sizeof(QueueBufferOutput)));
|
||||||
|
memset(output, 0, sizeof(QueueBufferOutput));
|
||||||
status_t res = connect(listener, api, producerControlledByApp, output);
|
status_t res = connect(listener, api, producerControlledByApp, output);
|
||||||
reply->writeInt32(res);
|
reply->writeInt32(res);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
|
@ -795,6 +795,11 @@ status_t Region::unflatten(void const* buffer, size_t size) {
|
|||||||
return NO_MEMORY;
|
return NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (numRects > (UINT32_MAX / sizeof(Rect))) {
|
||||||
|
android_errorWriteWithInfoLog(0x534e4554, "29983260", -1, NULL, 0);
|
||||||
|
return NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
Region result;
|
Region result;
|
||||||
result.mStorage.clear();
|
result.mStorage.clear();
|
||||||
for (size_t r = 0; r < numRects; ++r) {
|
for (size_t r = 0; r < numRects; ++r) {
|
||||||
|
@ -65,6 +65,10 @@ ifneq ($(MAX_EGL_CACHE_SIZE),)
|
|||||||
LOCAL_CFLAGS += -DMAX_EGL_CACHE_SIZE=$(MAX_EGL_CACHE_SIZE)
|
LOCAL_CFLAGS += -DMAX_EGL_CACHE_SIZE=$(MAX_EGL_CACHE_SIZE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(BOARD_USE_BGRA_8888), true)
|
||||||
|
LOCAL_CFLAGS += -DUSE_BGRA_8888
|
||||||
|
endif
|
||||||
|
|
||||||
LOCAL_REQUIRED_MODULES := $(egl.cfg_config_module)
|
LOCAL_REQUIRED_MODULES := $(egl.cfg_config_module)
|
||||||
egl.cfg_config_module :=
|
egl.cfg_config_module :=
|
||||||
|
|
||||||
|
@ -1225,6 +1225,8 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
|
|||||||
int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
|
int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
|
||||||
if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
|
if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
|
||||||
outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
|
outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
|
||||||
|
} else if (isWindowObscuredLocked(windowHandle)) {
|
||||||
|
outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTempTouchState.addOrUpdateWindow(
|
mTempTouchState.addOrUpdateWindow(
|
||||||
@ -1262,6 +1264,8 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
|
|||||||
}
|
}
|
||||||
if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
|
if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
|
||||||
targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
|
targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
|
||||||
|
} else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
|
||||||
|
targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update hover state.
|
// Update hover state.
|
||||||
@ -1437,6 +1441,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
|
|||||||
== InputWindowInfo::TYPE_WALLPAPER) {
|
== InputWindowInfo::TYPE_WALLPAPER) {
|
||||||
mTempTouchState.addOrUpdateWindow(windowHandle,
|
mTempTouchState.addOrUpdateWindow(windowHandle,
|
||||||
InputTarget::FLAG_WINDOW_IS_OBSCURED
|
InputTarget::FLAG_WINDOW_IS_OBSCURED
|
||||||
|
| InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED
|
||||||
| InputTarget::FLAG_DISPATCH_AS_IS,
|
| InputTarget::FLAG_DISPATCH_AS_IS,
|
||||||
BitSet32(0));
|
BitSet32(0));
|
||||||
}
|
}
|
||||||
@ -1631,6 +1636,27 @@ bool InputDispatcher::isWindowObscuredAtPointLocked(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
|
||||||
|
int32_t displayId = windowHandle->getInfo()->displayId;
|
||||||
|
const InputWindowInfo* windowInfo = windowHandle->getInfo();
|
||||||
|
size_t numWindows = mWindowHandles.size();
|
||||||
|
for (size_t i = 0; i < numWindows; i++) {
|
||||||
|
sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
|
||||||
|
if (otherHandle == windowHandle) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InputWindowInfo* otherInfo = otherHandle->getInfo();
|
||||||
|
if (otherInfo->displayId == displayId
|
||||||
|
&& otherInfo->visible && !otherInfo->isTrustedOverlay()
|
||||||
|
&& otherInfo->overlaps(windowInfo)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
String8 InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
|
String8 InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime,
|
||||||
const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
|
const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry,
|
||||||
const char* targetType) {
|
const char* targetType) {
|
||||||
@ -1905,6 +1931,9 @@ void InputDispatcher::enqueueDispatchEntryLocked(
|
|||||||
if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
|
if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
|
||||||
dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
|
dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
|
||||||
}
|
}
|
||||||
|
if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
|
||||||
|
dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
|
||||||
|
}
|
||||||
|
|
||||||
if (!connection->inputState.trackMotion(motionEntry,
|
if (!connection->inputState.trackMotion(motionEntry,
|
||||||
dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
|
dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
|
||||||
|
@ -89,7 +89,7 @@ struct InputTarget {
|
|||||||
/* This flag indicates that the event is being delivered to a foreground application. */
|
/* This flag indicates that the event is being delivered to a foreground application. */
|
||||||
FLAG_FOREGROUND = 1 << 0,
|
FLAG_FOREGROUND = 1 << 0,
|
||||||
|
|
||||||
/* This flag indicates that the target of a MotionEvent is partly or wholly
|
/* This flag indicates that the MotionEvent falls within the area of the target
|
||||||
* obscured by another visible window above it. The motion event should be
|
* obscured by another visible window above it. The motion event should be
|
||||||
* delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */
|
* delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */
|
||||||
FLAG_WINDOW_IS_OBSCURED = 1 << 1,
|
FLAG_WINDOW_IS_OBSCURED = 1 << 1,
|
||||||
@ -139,6 +139,12 @@ struct InputTarget {
|
|||||||
| FLAG_DISPATCH_AS_HOVER_EXIT
|
| FLAG_DISPATCH_AS_HOVER_EXIT
|
||||||
| FLAG_DISPATCH_AS_SLIPPERY_EXIT
|
| FLAG_DISPATCH_AS_SLIPPERY_EXIT
|
||||||
| FLAG_DISPATCH_AS_SLIPPERY_ENTER,
|
| FLAG_DISPATCH_AS_SLIPPERY_ENTER,
|
||||||
|
|
||||||
|
/* This flag indicates that the target of a MotionEvent is partly or wholly
|
||||||
|
* obscured by another visible window above it. The motion event should be
|
||||||
|
* delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED. */
|
||||||
|
FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 1 << 14,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The input channel to be targeted.
|
// The input channel to be targeted.
|
||||||
@ -1048,6 +1054,7 @@ private:
|
|||||||
const InjectionState* injectionState);
|
const InjectionState* injectionState);
|
||||||
bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
|
bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
|
||||||
int32_t x, int32_t y) const;
|
int32_t x, int32_t y) const;
|
||||||
|
bool isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const;
|
||||||
String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
|
String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
|
||||||
const sp<InputWindowHandle>& windowHandle);
|
const sp<InputWindowHandle>& windowHandle);
|
||||||
|
|
||||||
|
@ -6167,7 +6167,8 @@ nsecs_t TouchInputMapper::mLastStylusTime = 0;
|
|||||||
|
|
||||||
bool TouchInputMapper::rejectPalm(nsecs_t when) {
|
bool TouchInputMapper::rejectPalm(nsecs_t when) {
|
||||||
return (when - mLastStylusTime < mConfig.stylusPalmRejectionTime) &&
|
return (when - mLastStylusTime < mConfig.stylusPalmRejectionTime) &&
|
||||||
mPointerSimple.currentProperties.toolType != AMOTION_EVENT_TOOL_TYPE_STYLUS;
|
mPointerSimple.currentProperties.toolType != AMOTION_EVENT_TOOL_TYPE_STYLUS &&
|
||||||
|
mPointerSimple.currentProperties.toolType != AMOTION_EVENT_TOOL_TYPE_ERASER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchInputMapper::cancelTouch(nsecs_t when) {
|
void TouchInputMapper::cancelTouch(nsecs_t when) {
|
||||||
|
@ -36,14 +36,16 @@ bool InputWindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
|
bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
|
||||||
return x >= frameLeft && x <= frameRight
|
return x >= frameLeft && x < frameRight
|
||||||
&& y >= frameTop && y <= frameBottom;
|
&& y >= frameTop && y < frameBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputWindowInfo::isTrustedOverlay() const {
|
bool InputWindowInfo::isTrustedOverlay() const {
|
||||||
return layoutParamsType == TYPE_INPUT_METHOD
|
return layoutParamsType == TYPE_INPUT_METHOD
|
||||||
|| layoutParamsType == TYPE_INPUT_METHOD_DIALOG
|
|| layoutParamsType == TYPE_INPUT_METHOD_DIALOG
|
||||||
|| layoutParamsType == TYPE_MAGNIFICATION_OVERLAY
|
|| layoutParamsType == TYPE_MAGNIFICATION_OVERLAY
|
||||||
|
|| layoutParamsType == TYPE_STATUS_BAR
|
||||||
|
|| layoutParamsType == TYPE_NAVIGATION_BAR
|
||||||
|| layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
|
|| layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +53,11 @@ bool InputWindowInfo::supportsSplitTouch() const {
|
|||||||
return layoutParamsFlags & FLAG_SPLIT_TOUCH;
|
return layoutParamsFlags & FLAG_SPLIT_TOUCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InputWindowInfo::overlaps(const InputWindowInfo* other) const {
|
||||||
|
return frameLeft < other->frameRight && frameRight > other->frameLeft
|
||||||
|
&& frameTop < other->frameBottom && frameBottom > other->frameTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- InputWindowHandle ---
|
// --- InputWindowHandle ---
|
||||||
|
|
||||||
|
@ -146,6 +146,8 @@ struct InputWindowInfo {
|
|||||||
bool isTrustedOverlay() const;
|
bool isTrustedOverlay() const;
|
||||||
|
|
||||||
bool supportsSplitTouch() const;
|
bool supportsSplitTouch() const;
|
||||||
|
|
||||||
|
bool overlaps(const InputWindowInfo* other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,6 +359,8 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
|
|||||||
result.appendFormat("non-wakeUp | ");
|
result.appendFormat("non-wakeUp | ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.appendFormat("%.4f mA | ", s.getPowerUsage());
|
||||||
|
|
||||||
int bufIndex = mLastEventSeen.indexOfKey(s.getHandle());
|
int bufIndex = mLastEventSeen.indexOfKey(s.getHandle());
|
||||||
if (bufIndex >= 0) {
|
if (bufIndex >= 0) {
|
||||||
const CircularBuffer* buf = mLastEventSeen.valueAt(bufIndex);
|
const CircularBuffer* buf = mLastEventSeen.valueAt(bufIndex);
|
||||||
@ -1118,7 +1120,7 @@ bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,
|
|||||||
AppOpsManager appOps;
|
AppOpsManager appOps;
|
||||||
if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName)
|
if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName)
|
||||||
!= AppOpsManager::MODE_ALLOWED) {
|
!= AppOpsManager::MODE_ALLOWED) {
|
||||||
ALOGE("%s a sensor (%s) without enabled required app op: %D",
|
ALOGE("%s a sensor (%s) without enabled required app op: %d",
|
||||||
operation, sensor.getName().string(), opCode);
|
operation, sensor.getName().string(), opCode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,10 @@ else
|
|||||||
LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=0
|
LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(BOARD_USE_BGRA_8888),true)
|
||||||
|
LOCAL_CFLAGS += -DUSE_BGRA_8888
|
||||||
|
endif
|
||||||
|
|
||||||
LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
|
LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
|
||||||
LOCAL_CFLAGS += -std=c++11
|
LOCAL_CFLAGS += -std=c++11
|
||||||
|
|
||||||
@ -116,7 +120,11 @@ ifeq ($(TARGET_USES_QCOM_BSP), true)
|
|||||||
LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libgralloc
|
LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libgralloc
|
||||||
LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libqdutils
|
LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libqdutils
|
||||||
LOCAL_SHARED_LIBRARIES += libqdutils
|
LOCAL_SHARED_LIBRARIES += libqdutils
|
||||||
|
LOCAL_SHARED_LIBRARIES += libqdMetaData
|
||||||
LOCAL_CFLAGS += -DQTI_BSP
|
LOCAL_CFLAGS += -DQTI_BSP
|
||||||
|
ifeq ($(call is-board-platform-in-list,msm8996),true)
|
||||||
|
LOCAL_CFLAGS += -DSDM_TARGET
|
||||||
|
endif
|
||||||
LOCAL_SRC_FILES += \
|
LOCAL_SRC_FILES += \
|
||||||
ExSurfaceFlinger/ExLayer.cpp \
|
ExSurfaceFlinger/ExLayer.cpp \
|
||||||
ExSurfaceFlinger/ExSurfaceFlinger.cpp \
|
ExSurfaceFlinger/ExSurfaceFlinger.cpp \
|
||||||
@ -124,10 +132,22 @@ ifeq ($(TARGET_USES_QCOM_BSP), true)
|
|||||||
ExSurfaceFlinger/ExHWComposer.cpp
|
ExSurfaceFlinger/ExHWComposer.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(TARGET_HAVE_UI_BLUR),true)
|
ifeq ($(BOARD_USES_HWC_SERVICES), true)
|
||||||
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/ui
|
LOCAL_CFLAGS += -DUSES_HWC_SERVICES
|
||||||
LOCAL_SHARED_LIBRARIES += libuiblur
|
LOCAL_SHARED_LIBRARIES += libExynosHWCService
|
||||||
LOCAL_CFLAGS += -DUI_BLUR
|
LOCAL_C_INCLUDES += \
|
||||||
|
$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
|
||||||
|
$(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/$(TARGET_BOARD_PLATFORM)/libhwcService \
|
||||||
|
$(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/$(TARGET_BOARD_PLATFORM)/include \
|
||||||
|
$(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/$(TARGET_SOC)/include \
|
||||||
|
$(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/$(TARGET_SOC)/libhwcmodule \
|
||||||
|
$(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/exynos/libhwc \
|
||||||
|
$(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/exynos/include \
|
||||||
|
$(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/exynos/libexynosutils \
|
||||||
|
$(TOP)/system/core/libsync/include
|
||||||
|
|
||||||
|
LOCAL_ADDITIONAL_DEPENDENCIES := \
|
||||||
|
$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LOCAL_MODULE := libsurfaceflinger
|
LOCAL_MODULE := libsurfaceflinger
|
||||||
|
51
services/surfaceflinger/CleanSpec.mk
Normal file
51
services/surfaceflinger/CleanSpec.mk
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Copyright (C) 2016 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# If you don't need to do a full clean build but would like to touch
|
||||||
|
# a file or delete some intermediate files, add a clean step to the end
|
||||||
|
# of the list. These steps will only be run once, if they haven't been
|
||||||
|
# run before.
|
||||||
|
#
|
||||||
|
# E.g.:
|
||||||
|
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
|
||||||
|
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
|
||||||
|
#
|
||||||
|
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
|
||||||
|
# files that are missing or have been moved.
|
||||||
|
#
|
||||||
|
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
|
||||||
|
# Use $(OUT_DIR) to refer to the "out" directory.
|
||||||
|
#
|
||||||
|
# If you need to re-do something that's already mentioned, just copy
|
||||||
|
# the command and add it to the bottom of the list. E.g., if a change
|
||||||
|
# that you made last week required touching a file and a change you
|
||||||
|
# made today requires touching the same file, just copy the old
|
||||||
|
# touch step and add it to the end of the list.
|
||||||
|
#
|
||||||
|
# ************************************************
|
||||||
|
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||||
|
# ************************************************
|
||||||
|
|
||||||
|
# For example:
|
||||||
|
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
|
||||||
|
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
|
||||||
|
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
|
||||||
|
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
|
||||||
|
|
||||||
|
# ************************************************
|
||||||
|
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||||
|
# ************************************************
|
||||||
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libsurfaceflinger_intermediates)
|
||||||
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libsurfaceflinger_ddmconnection_intermediates)
|
@ -57,15 +57,17 @@ public:
|
|||||||
mStop(false),
|
mStop(false),
|
||||||
mPeriod(0),
|
mPeriod(0),
|
||||||
mPhase(0),
|
mPhase(0),
|
||||||
|
mReferenceTime(0),
|
||||||
mWakeupLatency(0) {
|
mWakeupLatency(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DispSyncThread() {}
|
virtual ~DispSyncThread() {}
|
||||||
|
|
||||||
void updateModel(nsecs_t period, nsecs_t phase) {
|
void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) {
|
||||||
Mutex::Autolock lock(mMutex);
|
Mutex::Autolock lock(mMutex);
|
||||||
mPeriod = period;
|
mPeriod = period;
|
||||||
mPhase = phase;
|
mPhase = phase;
|
||||||
|
mReferenceTime = referenceTime;
|
||||||
mCond.signal();
|
mCond.signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +249,7 @@ private:
|
|||||||
ref = lastEventTime;
|
ref = lastEventTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsecs_t phase = mPhase + listener.mPhase;
|
nsecs_t phase = mReferenceTime + mPhase + listener.mPhase;
|
||||||
nsecs_t t = (((ref - phase) / mPeriod) + 1) * mPeriod + phase;
|
nsecs_t t = (((ref - phase) / mPeriod) + 1) * mPeriod + phase;
|
||||||
|
|
||||||
if (t - listener.mLastEventTime < mPeriod / 2) {
|
if (t - listener.mLastEventTime < mPeriod / 2) {
|
||||||
@ -267,6 +269,7 @@ private:
|
|||||||
|
|
||||||
nsecs_t mPeriod;
|
nsecs_t mPeriod;
|
||||||
nsecs_t mPhase;
|
nsecs_t mPhase;
|
||||||
|
nsecs_t mReferenceTime;
|
||||||
nsecs_t mWakeupLatency;
|
nsecs_t mWakeupLatency;
|
||||||
|
|
||||||
Vector<EventListener> mEventListeners;
|
Vector<EventListener> mEventListeners;
|
||||||
@ -315,6 +318,9 @@ DispSync::~DispSync() {}
|
|||||||
void DispSync::reset() {
|
void DispSync::reset() {
|
||||||
Mutex::Autolock lock(mMutex);
|
Mutex::Autolock lock(mMutex);
|
||||||
|
|
||||||
|
mPhase = 0;
|
||||||
|
mReferenceTime = 0;
|
||||||
|
mModelUpdated = false;
|
||||||
mNumResyncSamples = 0;
|
mNumResyncSamples = 0;
|
||||||
mFirstResyncSample = 0;
|
mFirstResyncSample = 0;
|
||||||
mNumResyncSamplesSincePresent = 0;
|
mNumResyncSamplesSincePresent = 0;
|
||||||
@ -342,12 +348,13 @@ bool DispSync::addPresentFence(const sp<Fence>& fence) {
|
|||||||
|
|
||||||
updateErrorLocked();
|
updateErrorLocked();
|
||||||
|
|
||||||
return mPeriod == 0 || mError > kErrorThreshold;
|
return !mModelUpdated || mError > kErrorThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispSync::beginResync() {
|
void DispSync::beginResync() {
|
||||||
Mutex::Autolock lock(mMutex);
|
Mutex::Autolock lock(mMutex);
|
||||||
|
|
||||||
|
mModelUpdated = false;
|
||||||
mNumResyncSamples = 0;
|
mNumResyncSamples = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,6 +363,10 @@ bool DispSync::addResyncSample(nsecs_t timestamp) {
|
|||||||
|
|
||||||
size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
|
size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
|
||||||
mResyncSamples[idx] = timestamp;
|
mResyncSamples[idx] = timestamp;
|
||||||
|
if (mNumResyncSamples == 0) {
|
||||||
|
mPhase = 0;
|
||||||
|
mReferenceTime = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
|
if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
|
||||||
mNumResyncSamples++;
|
mNumResyncSamples++;
|
||||||
@ -378,7 +389,7 @@ bool DispSync::addResyncSample(nsecs_t timestamp) {
|
|||||||
return mThread->hasAnyEventListeners();
|
return mThread->hasAnyEventListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mPeriod == 0 || mError > kErrorThreshold;
|
return !mModelUpdated || mError > kErrorThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispSync::endResync() {
|
void DispSync::endResync() {
|
||||||
@ -407,7 +418,8 @@ void DispSync::setPeriod(nsecs_t period) {
|
|||||||
Mutex::Autolock lock(mMutex);
|
Mutex::Autolock lock(mMutex);
|
||||||
mPeriod = period;
|
mPeriod = period;
|
||||||
mPhase = 0;
|
mPhase = 0;
|
||||||
mThread->updateModel(mPeriod, mPhase);
|
mReferenceTime = 0;
|
||||||
|
mThread->updateModel(mPeriod, mPhase, mReferenceTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsecs_t DispSync::getPeriod() {
|
nsecs_t DispSync::getPeriod() {
|
||||||
@ -432,7 +444,7 @@ void DispSync::updateModelLocked() {
|
|||||||
double scale = 2.0 * M_PI / double(mPeriod);
|
double scale = 2.0 * M_PI / double(mPeriod);
|
||||||
for (size_t i = 0; i < mNumResyncSamples; i++) {
|
for (size_t i = 0; i < mNumResyncSamples; i++) {
|
||||||
size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
|
size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
|
||||||
nsecs_t sample = mResyncSamples[idx];
|
nsecs_t sample = mResyncSamples[idx] - mReferenceTime;
|
||||||
double samplePhase = double(sample % mPeriod) * scale;
|
double samplePhase = double(sample % mPeriod) * scale;
|
||||||
sampleAvgX += cos(samplePhase);
|
sampleAvgX += cos(samplePhase);
|
||||||
sampleAvgY += sin(samplePhase);
|
sampleAvgY += sin(samplePhase);
|
||||||
@ -455,12 +467,13 @@ void DispSync::updateModelLocked() {
|
|||||||
// Artificially inflate the period if requested.
|
// Artificially inflate the period if requested.
|
||||||
mPeriod += mPeriod * mRefreshSkipCount;
|
mPeriod += mPeriod * mRefreshSkipCount;
|
||||||
|
|
||||||
mThread->updateModel(mPeriod, mPhase);
|
mThread->updateModel(mPeriod, mPhase, mReferenceTime);
|
||||||
|
mModelUpdated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispSync::updateErrorLocked() {
|
void DispSync::updateErrorLocked() {
|
||||||
if (mPeriod == 0) {
|
if (!mModelUpdated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,7 +485,7 @@ void DispSync::updateErrorLocked() {
|
|||||||
nsecs_t sqErrSum = 0;
|
nsecs_t sqErrSum = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
|
for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
|
||||||
nsecs_t sample = mPresentTimes[i];
|
nsecs_t sample = mPresentTimes[i] - mReferenceTime;
|
||||||
if (sample > mPhase) {
|
if (sample > mPhase) {
|
||||||
nsecs_t sampleErr = (sample - mPhase) % period;
|
nsecs_t sampleErr = (sample - mPhase) % period;
|
||||||
if (sampleErr > period / 2) {
|
if (sampleErr > period / 2) {
|
||||||
@ -506,7 +519,8 @@ void DispSync::resetErrorLocked() {
|
|||||||
nsecs_t DispSync::computeNextRefresh(int periodOffset) const {
|
nsecs_t DispSync::computeNextRefresh(int periodOffset) const {
|
||||||
Mutex::Autolock lock(mMutex);
|
Mutex::Autolock lock(mMutex);
|
||||||
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
|
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||||
return (((now - mPhase) / mPeriod) + periodOffset + 1) * mPeriod + mPhase;
|
nsecs_t phase = mReferenceTime + mPhase;
|
||||||
|
return (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispSync::dump(String8& result) const {
|
void DispSync::dump(String8& result) const {
|
||||||
|
@ -146,11 +146,18 @@ private:
|
|||||||
// number of nanoseconds from time 0 to the first vsync event.
|
// number of nanoseconds from time 0 to the first vsync event.
|
||||||
nsecs_t mPhase;
|
nsecs_t mPhase;
|
||||||
|
|
||||||
|
// mReferenceTime is the reference time of the modeled vsync events.
|
||||||
|
// It is the nanosecond timestamp of the first vsync event after a resync.
|
||||||
|
nsecs_t mReferenceTime;
|
||||||
|
|
||||||
// mError is the computed model error. It is based on the difference
|
// mError is the computed model error. It is based on the difference
|
||||||
// between the estimated vsync event times and those observed in the
|
// between the estimated vsync event times and those observed in the
|
||||||
// mPresentTimes array.
|
// mPresentTimes array.
|
||||||
nsecs_t mError;
|
nsecs_t mError;
|
||||||
|
|
||||||
|
// Whether we have updated the vsync event model since the last resync.
|
||||||
|
bool mModelUpdated;
|
||||||
|
|
||||||
// These member variables are the state used during the resynchronization
|
// These member variables are the state used during the resynchronization
|
||||||
// process to store information about the hardware vsync event times used
|
// process to store information about the hardware vsync event times used
|
||||||
// to compute the model.
|
// to compute the model.
|
||||||
|
@ -142,10 +142,10 @@ DisplayDevice::DisplayDevice(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPanelInverseMounted = false;
|
mPanelMountFlip = 0;
|
||||||
// Check if panel is inverse mounted (contents show up HV flipped)
|
// 1: H-Flip, 2: V-Flip, 3: 180 (HV Flip)
|
||||||
property_get("persist.panel.inversemounted", property, "0");
|
property_get("persist.panel.mountflip", property, "0");
|
||||||
mPanelInverseMounted = !!atoi(property);
|
mPanelMountFlip = atoi(property);
|
||||||
|
|
||||||
// initialize the display orientation transform.
|
// initialize the display orientation transform.
|
||||||
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
|
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
|
||||||
@ -401,7 +401,7 @@ status_t DisplayDevice::orientationToTransfrom(
|
|||||||
property_get("ro.sf.hwrotation", value, "0");
|
property_get("ro.sf.hwrotation", value, "0");
|
||||||
int additionalRot = atoi(value);
|
int additionalRot = atoi(value);
|
||||||
|
|
||||||
if (additionalRot) {
|
if (additionalRot && mType == DISPLAY_PRIMARY) {
|
||||||
additionalRot /= 90;
|
additionalRot /= 90;
|
||||||
if (orientation == DisplayState::eOrientationUnchanged) {
|
if (orientation == DisplayState::eOrientationUnchanged) {
|
||||||
orientation = additionalRot;
|
orientation = additionalRot;
|
||||||
@ -428,8 +428,8 @@ status_t DisplayDevice::orientationToTransfrom(
|
|||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DISPLAY_PRIMARY == mHwcDisplayId && isPanelInverseMounted()) {
|
if (DISPLAY_PRIMARY == mHwcDisplayId) {
|
||||||
flags = flags ^ Transform::ROT_180;
|
flags = flags ^ getPanelMountFlip();
|
||||||
}
|
}
|
||||||
|
|
||||||
tr->set(flags, w, h);
|
tr->set(flags, w, h);
|
||||||
|
@ -126,8 +126,8 @@ public:
|
|||||||
int32_t getHwcDisplayId() const { return mHwcDisplayId; }
|
int32_t getHwcDisplayId() const { return mHwcDisplayId; }
|
||||||
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
|
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
|
||||||
|
|
||||||
bool isPanelInverseMounted() const {
|
uint32_t getPanelMountFlip() const {
|
||||||
return mPanelInverseMounted;
|
return mPanelMountFlip;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We pass in mustRecompose so we can keep VirtualDisplaySurface's state
|
// We pass in mustRecompose so we can keep VirtualDisplaySurface's state
|
||||||
@ -230,8 +230,8 @@ private:
|
|||||||
int mPowerMode;
|
int mPowerMode;
|
||||||
// Current active config
|
// Current active config
|
||||||
int mActiveConfig;
|
int mActiveConfig;
|
||||||
// Panel is inverse mounted
|
// Panel's mount flip, H, V or 180 (HV)
|
||||||
int mPanelInverseMounted;
|
uint32_t mPanelMountFlip;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
@ -435,7 +435,11 @@ status_t HWComposer::queryDisplayProperties(int disp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: what should we set the format to?
|
// FIXME: what should we set the format to?
|
||||||
|
#ifdef USE_BGRA_8888
|
||||||
|
mDisplayData[disp].format = HAL_PIXEL_FORMAT_BGRA_8888;
|
||||||
|
#else
|
||||||
mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;
|
mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;
|
||||||
|
#endif
|
||||||
mDisplayData[disp].connected = true;
|
mDisplayData[disp].connected = true;
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
@ -497,7 +501,11 @@ sp<Fence> HWComposer::getDisplayFence(int disp) const {
|
|||||||
|
|
||||||
uint32_t HWComposer::getFormat(int disp) const {
|
uint32_t HWComposer::getFormat(int disp) const {
|
||||||
if (static_cast<uint32_t>(disp) >= MAX_HWC_DISPLAYS || !mAllocatedDisplayIDs.hasBit(disp)) {
|
if (static_cast<uint32_t>(disp) >= MAX_HWC_DISPLAYS || !mAllocatedDisplayIDs.hasBit(disp)) {
|
||||||
|
#ifdef USE_BGRA_8888
|
||||||
|
return HAL_PIXEL_FORMAT_BGRA_8888;
|
||||||
|
#else
|
||||||
return HAL_PIXEL_FORMAT_RGBA_8888;
|
return HAL_PIXEL_FORMAT_RGBA_8888;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
return mDisplayData[disp].format;
|
return mDisplayData[disp].format;
|
||||||
}
|
}
|
||||||
@ -879,7 +887,11 @@ int HWComposer::getVisualID() const {
|
|||||||
// FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
|
// FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
|
||||||
// is supported by the implementation. we can only be in this case
|
// is supported by the implementation. we can only be in this case
|
||||||
// if we have HWC 1.1
|
// if we have HWC 1.1
|
||||||
|
#ifdef USE_BGRA_8888
|
||||||
|
return HAL_PIXEL_FORMAT_BGRA_8888;
|
||||||
|
#else
|
||||||
return HAL_PIXEL_FORMAT_RGBA_8888;
|
return HAL_PIXEL_FORMAT_RGBA_8888;
|
||||||
|
#endif
|
||||||
//return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
|
//return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
|
||||||
} else {
|
} else {
|
||||||
return mFbDev->format;
|
return mFbDev->format;
|
||||||
@ -1367,7 +1379,11 @@ bool HWComposer::VSyncThread::threadLoop() {
|
|||||||
HWComposer::DisplayData::DisplayData()
|
HWComposer::DisplayData::DisplayData()
|
||||||
: configs(),
|
: configs(),
|
||||||
currentConfig(0),
|
currentConfig(0),
|
||||||
|
#ifdef USE_BGRA_8888
|
||||||
|
format(HAL_PIXEL_FORMAT_BGRA_8888),
|
||||||
|
#else
|
||||||
format(HAL_PIXEL_FORMAT_RGBA_8888),
|
format(HAL_PIXEL_FORMAT_RGBA_8888),
|
||||||
|
#endif
|
||||||
connected(false),
|
connected(false),
|
||||||
hasFbComp(false), hasOvComp(false),
|
hasFbComp(false), hasOvComp(false),
|
||||||
capacity(0), list(NULL),
|
capacity(0), list(NULL),
|
||||||
|
@ -306,6 +306,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
friend class VSyncThread;
|
friend class VSyncThread;
|
||||||
|
friend class ExHWComposer;
|
||||||
|
|
||||||
// for debugging ----------------------------------------------------------
|
// for debugging ----------------------------------------------------------
|
||||||
void dump(String8& out) const;
|
void dump(String8& out) const;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -45,6 +45,10 @@
|
|||||||
#include <ExSurfaceFlinger/ExHWComposer.h>
|
#include <ExSurfaceFlinger/ExHWComposer.h>
|
||||||
#include <ExSurfaceFlinger/ExVirtualDisplaySurface.h>
|
#include <ExSurfaceFlinger/ExVirtualDisplaySurface.h>
|
||||||
#include <gralloc_priv.h>
|
#include <gralloc_priv.h>
|
||||||
|
#ifdef SDM_TARGET
|
||||||
|
#include <qd_utils.h>
|
||||||
|
#include <display_config.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <cutils/properties.h>
|
#include <cutils/properties.h>
|
||||||
@ -176,8 +180,25 @@ bool DisplayUtils::canAllocateHwcDisplayIdForVDS(int usage) {
|
|||||||
|
|
||||||
#ifdef QTI_BSP
|
#ifdef QTI_BSP
|
||||||
#ifdef FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS
|
#ifdef FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS
|
||||||
// Reserve hardware acceleration for WFD use-case
|
#ifdef SDM_TARGET
|
||||||
flag_mask = GRALLOC_USAGE_PRIVATE_WFD;
|
int hdmi_node = qdutils::getHDMINode();
|
||||||
|
if(hdmi_node == HWC_DISPLAY_PRIMARY) {
|
||||||
|
int active_config = qdutils::getActiveConfig(HWC_DISPLAY_PRIMARY);
|
||||||
|
if(active_config >= 0) {
|
||||||
|
qdutils::DisplayAttributes attr = qdutils::getDisplayAttributes(active_config,
|
||||||
|
HWC_DISPLAY_PRIMARY);
|
||||||
|
if(!attr.is_yuv) {
|
||||||
|
// Reserve hardware acceleration for WFD use-case
|
||||||
|
flag_mask = GRALLOC_USAGE_PRIVATE_WFD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
// Reserve hardware acceleration for WFD use-case
|
||||||
|
flag_mask = GRALLOC_USAGE_PRIVATE_WFD;
|
||||||
|
#ifdef SDM_TARGET
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
// Don't allocate HWC display unless we force HWC copy, otherwise
|
// Don't allocate HWC display unless we force HWC copy, otherwise
|
||||||
// incompatible buffers are sent to the media stack
|
// incompatible buffers are sent to the media stack
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include "ExHWComposer.h"
|
#include "ExHWComposer.h"
|
||||||
#ifdef QTI_BSP
|
#ifdef QTI_BSP
|
||||||
#include <hardware/display_defs.h>
|
#include <hardware/display_defs.h>
|
||||||
|
#include <gralloc_priv.h>
|
||||||
|
#include <qdMetaData.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
@ -74,4 +76,32 @@ bool ExHWComposer::isCompositionTypeBlit(const int32_t compType) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(QTI_BSP) && defined(SDM_TARGET)
|
||||||
|
uint32_t ExHWComposer::getS3DFlag(int disp) const {
|
||||||
|
if (disp < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mHwc || uint32_t(disp) >= MAX_HWC_DISPLAYS || !mAllocatedDisplayIDs.hasBit(disp))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const DisplayData& disp_data(mDisplayData[disp]);
|
||||||
|
|
||||||
|
for (size_t i=0 ; i<disp_data.list->numHwLayers-1; i++) {
|
||||||
|
const hwc_layer_1_t &l = disp_data.list->hwLayers[i];
|
||||||
|
private_handle_t *pvt_handle = static_cast<private_handle_t *>
|
||||||
|
(const_cast<native_handle_t*>(l.handle));
|
||||||
|
|
||||||
|
if (pvt_handle != NULL) {
|
||||||
|
struct S3DSFRender_t s3dRender;
|
||||||
|
getMetaData(pvt_handle, GET_S3D_RENDER, &s3dRender);
|
||||||
|
if (s3dRender.DisplayId == static_cast<uint32_t>(disp) && s3dRender.GpuRender) {
|
||||||
|
return s3dRender.GpuS3dFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
@ -43,6 +43,10 @@ public:
|
|||||||
|
|
||||||
virtual ~ExHWComposer();
|
virtual ~ExHWComposer();
|
||||||
|
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
uint32_t getS3DFlag(int disp) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool mVDSEnabled;
|
bool mVDSEnabled;
|
||||||
inline bool isVDSEnabled() const { return mVDSEnabled; };
|
inline bool isVDSEnabled() const { return mVDSEnabled; };
|
||||||
|
@ -36,10 +36,12 @@
|
|||||||
#include <ui/GraphicBuffer.h>
|
#include <ui/GraphicBuffer.h>
|
||||||
#ifdef QTI_BSP
|
#ifdef QTI_BSP
|
||||||
#include <gralloc_priv.h>
|
#include <gralloc_priv.h>
|
||||||
|
#include <qdMetaData.h>
|
||||||
#include <hardware/display_defs.h>
|
#include <hardware/display_defs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ExLayer.h"
|
#include "ExLayer.h"
|
||||||
|
#include "RenderEngine/RenderEngine.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
@ -70,12 +72,18 @@ static Rect getAspectRatio(const sp<const DisplayDevice>& hw,
|
|||||||
|
|
||||||
ExLayer::ExLayer(SurfaceFlinger* flinger, const sp<Client>& client,
|
ExLayer::ExLayer(SurfaceFlinger* flinger, const sp<Client>& client,
|
||||||
const String8& name, uint32_t w, uint32_t h, uint32_t flags)
|
const String8& name, uint32_t w, uint32_t h, uint32_t flags)
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
: Layer(flinger, client, name, w, h, flags),
|
||||||
|
mMeshLeftTop(Mesh::TRIANGLE_FAN, 4, 2, 2),
|
||||||
|
mMeshRightBottom(Mesh::TRIANGLE_FAN, 4, 2, 2) {
|
||||||
|
#else
|
||||||
: Layer(flinger, client, name, w, h, flags) {
|
: Layer(flinger, client, name, w, h, flags) {
|
||||||
|
#endif
|
||||||
char property[PROPERTY_VALUE_MAX] = {0};
|
char property[PROPERTY_VALUE_MAX] = {0};
|
||||||
|
|
||||||
mDebugLogs = false;
|
mDebugLogs = false;
|
||||||
mIsGPUAllowedForProtected = false;
|
mIsGPUAllowedForProtected = false;
|
||||||
|
mIsHDMIPrimary = false;
|
||||||
if((property_get("persist.debug.qdframework.logs", property, NULL) > 0) &&
|
if((property_get("persist.debug.qdframework.logs", property, NULL) > 0) &&
|
||||||
(!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
|
(!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
|
||||||
(!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
|
(!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
|
||||||
@ -88,6 +96,12 @@ ExLayer::ExLayer(SurfaceFlinger* flinger, const sp<Client>& client,
|
|||||||
(atoi(property) == 1)) {
|
(atoi(property) == 1)) {
|
||||||
mIsGPUAllowedForProtected = true;
|
mIsGPUAllowedForProtected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((property_get("persist.sys.is_hdmi_primary", property, NULL) > 0) &&
|
||||||
|
(atoi(property) == 1)) {
|
||||||
|
mIsHDMIPrimary = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExLayer::~ExLayer() {
|
ExLayer::~ExLayer() {
|
||||||
@ -204,4 +218,172 @@ bool ExLayer::canAllowGPUForProtected() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExLayer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
|
||||||
|
const Region& /* clip */, bool useIdentityTransform) const {
|
||||||
|
const State& s(getDrawingState());
|
||||||
|
#if defined(QTI_BSP) && defined(SDM_TARGET)
|
||||||
|
uint32_t s3d_fmt = 0;
|
||||||
|
private_handle_t *pvt_handle = static_cast<private_handle_t *>
|
||||||
|
(const_cast<native_handle_t*>(mActiveBuffer->handle));
|
||||||
|
if (pvt_handle != NULL) {
|
||||||
|
struct S3DSFRender_t s3dRender;
|
||||||
|
getMetaData(pvt_handle, GET_S3D_RENDER, &s3dRender);
|
||||||
|
|
||||||
|
if ((s3dRender.DisplayId == static_cast<uint32_t>(hw->getHwcDisplayId()) ||
|
||||||
|
mIsHDMIPrimary) && s3dRender.GpuRender) {
|
||||||
|
clearMetaData(pvt_handle, SET_S3D_RENDER);
|
||||||
|
s3d_fmt = s3dRender.GpuS3dFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
computeGeometry(hw, mMesh, useIdentityTransform);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: the way we compute the texture coordinates here produces
|
||||||
|
* different results than when we take the HWC path -- in the later case
|
||||||
|
* the "source crop" is rounded to texel boundaries.
|
||||||
|
* This can produce significantly different results when the texture
|
||||||
|
* is scaled by a large amount.
|
||||||
|
*
|
||||||
|
* The GL code below is more logical (imho), and the difference with
|
||||||
|
* HWC is due to a limitation of the HWC API to integers -- a question
|
||||||
|
* is suspend is whether we should ignore this problem or revert to
|
||||||
|
* GL composition when a buffer scaling is applied (maybe with some
|
||||||
|
* minimal value)? Or, we could make GL behave like HWC -- but this feel
|
||||||
|
* like more of a hack.
|
||||||
|
*/
|
||||||
|
Rect win(s.active.w, s.active.h);
|
||||||
|
if(!s.active.crop.isEmpty()) {
|
||||||
|
win = s.active.crop;
|
||||||
|
}
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
win = s.transform.transform(win);
|
||||||
|
win.intersect(hw->getViewport(), &win);
|
||||||
|
win = s.transform.inverse().transform(win);
|
||||||
|
win.intersect(Rect(s.active.w, s.active.h), &win);
|
||||||
|
win = reduce(win, s.activeTransparentRegion);
|
||||||
|
#else
|
||||||
|
win = reduce(win, s.activeTransparentRegion);
|
||||||
|
#endif
|
||||||
|
float left = float(win.left) / float(s.active.w);
|
||||||
|
float top = float(win.top) / float(s.active.h);
|
||||||
|
float right = float(win.right) / float(s.active.w);
|
||||||
|
float bottom = float(win.bottom) / float(s.active.h);
|
||||||
|
|
||||||
|
// TODO: we probably want to generate the texture coords with the mesh
|
||||||
|
// here we assume that we only have 4 vertices
|
||||||
|
Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
|
||||||
|
texCoords[0] = vec2(left, 1.0f - top);
|
||||||
|
texCoords[1] = vec2(left, 1.0f - bottom);
|
||||||
|
texCoords[2] = vec2(right, 1.0f - bottom);
|
||||||
|
texCoords[3] = vec2(right, 1.0f - top);
|
||||||
|
|
||||||
|
#if defined(QTI_BSP) && defined(SDM_TARGET)
|
||||||
|
computeGeometryS3D(hw, mMesh, mMeshLeftTop, mMeshRightBottom, s3d_fmt);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RenderEngine& engine(mFlinger->getRenderEngine());
|
||||||
|
engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
|
||||||
|
|
||||||
|
#if defined(QTI_BSP) && defined(SDM_TARGET)
|
||||||
|
if (s3d_fmt != HWC_S3DMODE_NONE) {
|
||||||
|
engine.setScissor(0, 0, hw->getWidth(), hw->getHeight());
|
||||||
|
engine.drawMesh(mMeshLeftTop);
|
||||||
|
engine.drawMesh(mMeshRightBottom);
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
engine.drawMesh(mMesh);
|
||||||
|
#if defined(QTI_BSP) && defined(SDM_TARGET)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
engine.disableBlending();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
void ExLayer::computeGeometryS3D(const sp<const DisplayDevice>& hw, Mesh& mesh,
|
||||||
|
Mesh& meshLeftTop, Mesh &meshRightBottom, uint32_t s3d_fmt) const
|
||||||
|
{
|
||||||
|
Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
|
||||||
|
Mesh::VertexArray<vec2> positionLeftTop(meshLeftTop.getPositionArray<vec2>());
|
||||||
|
Mesh::VertexArray<vec2> positionRightBottom(meshRightBottom.getPositionArray<vec2>());
|
||||||
|
Mesh::VertexArray<vec2> texCoords(mesh.getTexCoordArray<vec2>());
|
||||||
|
Mesh::VertexArray<vec2> texCoordsLeftTop(meshLeftTop.getTexCoordArray<vec2>());
|
||||||
|
Mesh::VertexArray<vec2> texCoordsRightBottom(meshRightBottom.getTexCoordArray<vec2>());
|
||||||
|
|
||||||
|
Rect scissor = hw->getBounds();
|
||||||
|
|
||||||
|
if(s3d_fmt == HWC_S3DMODE_NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t count = mesh.getVertexCount();
|
||||||
|
while(count--) {
|
||||||
|
positionLeftTop[count] = positionRightBottom[count] = position[count];
|
||||||
|
texCoordsLeftTop[count] = texCoordsRightBottom[count] = texCoords[count];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (s3d_fmt) {
|
||||||
|
case HWC_S3DMODE_LR:
|
||||||
|
case HWC_S3DMODE_RL:
|
||||||
|
{
|
||||||
|
positionLeftTop[0].x = (position[0].x - scissor.left) / 2.0f + scissor.left;
|
||||||
|
positionLeftTop[1].x = (position[1].x - scissor.left) / 2.0f + scissor.left;
|
||||||
|
positionLeftTop[2].x = (position[2].x - scissor.left) / 2.0f + scissor.left;
|
||||||
|
positionLeftTop[3].x = (position[3].x - scissor.left) / 2.0f + scissor.left;
|
||||||
|
|
||||||
|
positionRightBottom[0].x = positionLeftTop[0].x + scissor.getWidth()/2;
|
||||||
|
positionRightBottom[1].x = positionLeftTop[1].x + scissor.getWidth()/2;
|
||||||
|
positionRightBottom[2].x = positionLeftTop[2].x + scissor.getWidth()/2;
|
||||||
|
positionRightBottom[3].x = positionLeftTop[3].x + scissor.getWidth()/2;
|
||||||
|
|
||||||
|
if(isYuvLayer()) {
|
||||||
|
texCoordsLeftTop[0].x = texCoords[0].x / 2.0f;
|
||||||
|
texCoordsLeftTop[1].x = texCoords[1].x / 2.0f;
|
||||||
|
texCoordsLeftTop[2].x = texCoords[2].x / 2.0f;
|
||||||
|
texCoordsLeftTop[3].x = texCoords[3].x / 2.0f;
|
||||||
|
|
||||||
|
texCoordsRightBottom[0].x = texCoordsLeftTop[0].x + 0.5f;
|
||||||
|
texCoordsRightBottom[1].x = texCoordsLeftTop[1].x + 0.5f;
|
||||||
|
texCoordsRightBottom[2].x = texCoordsLeftTop[2].x + 0.5f;
|
||||||
|
texCoordsRightBottom[3].x = texCoordsLeftTop[3].x + 0.5f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HWC_S3DMODE_TB:
|
||||||
|
{
|
||||||
|
positionRightBottom[0].y = (position[0].y - scissor.top) / 2.0f + scissor.top;
|
||||||
|
positionRightBottom[1].y = (position[1].y - scissor.top) / 2.0f + scissor.top;
|
||||||
|
positionRightBottom[2].y = (position[2].y - scissor.top) / 2.0f + scissor.top;
|
||||||
|
positionRightBottom[3].y = (position[3].y - scissor.top) / 2.0f + scissor.top;
|
||||||
|
|
||||||
|
positionLeftTop[0].y = positionRightBottom[0].y + scissor.getHeight() / 2.0f;
|
||||||
|
positionLeftTop[1].y = positionRightBottom[1].y + scissor.getHeight() / 2.0f;
|
||||||
|
positionLeftTop[2].y = positionRightBottom[2].y + scissor.getHeight() / 2.0f;
|
||||||
|
positionLeftTop[3].y = positionRightBottom[3].y + scissor.getHeight() / 2.0f;
|
||||||
|
|
||||||
|
positionLeftTop[0].x = positionRightBottom[0].x = position[0].x;
|
||||||
|
positionLeftTop[1].x = positionRightBottom[1].x = position[1].x;
|
||||||
|
positionLeftTop[2].x = positionRightBottom[2].x = position[2].x;
|
||||||
|
positionLeftTop[3].x = positionRightBottom[3].x = position[3].x;
|
||||||
|
|
||||||
|
if(isYuvLayer()) {
|
||||||
|
texCoordsRightBottom[0].y = texCoords[0].y / 2.0f;
|
||||||
|
texCoordsRightBottom[1].y = texCoords[1].y / 2.0f;
|
||||||
|
texCoordsRightBottom[2].y = texCoords[2].y / 2.0f;
|
||||||
|
texCoordsRightBottom[3].y = texCoords[3].y / 2.0f;
|
||||||
|
|
||||||
|
texCoordsLeftTop[0].y = texCoordsRightBottom[0].y + 0.5f;
|
||||||
|
texCoordsLeftTop[1].y = texCoordsRightBottom[1].y + 0.5f;
|
||||||
|
texCoordsLeftTop[2].y = texCoordsRightBottom[2].y + 0.5f;
|
||||||
|
texCoordsLeftTop[3].y = texCoordsRightBottom[3].y + 0.5f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
@ -43,6 +43,22 @@ class ExSurfaceFlinger;
|
|||||||
class ExLayer : public Layer
|
class ExLayer : public Layer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
enum {
|
||||||
|
/*
|
||||||
|
* HWC S3D_MODE is set by HWC driver to indicate that HWC driver can not support
|
||||||
|
* S3D standalone, need surfaceflinger help to draw layers twice to construct
|
||||||
|
* S3D framebuffer target.
|
||||||
|
*/
|
||||||
|
HWC_S3DMODE_NONE = 0x00000000,
|
||||||
|
HWC_S3DMODE_LR = 0x00000001,
|
||||||
|
HWC_S3DMODE_RL = 0x00000002,
|
||||||
|
HWC_S3DMODE_TB = 0x00000003,
|
||||||
|
HWC_S3DMODE_FP = 0x00000004,
|
||||||
|
HWC_S3DMODE_MAX = 0x00000005,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
ExLayer(SurfaceFlinger* flinger, const sp<Client>& client,
|
ExLayer(SurfaceFlinger* flinger, const sp<Client>& client,
|
||||||
const String8& name, uint32_t w, uint32_t h, uint32_t flags);
|
const String8& name, uint32_t w, uint32_t h, uint32_t flags);
|
||||||
virtual ~ExLayer();
|
virtual ~ExLayer();
|
||||||
@ -57,11 +73,27 @@ public:
|
|||||||
HWComposer::HWCLayerInterface& layer);
|
HWComposer::HWCLayerInterface& layer);
|
||||||
virtual bool canAllowGPUForProtected() const;
|
virtual bool canAllowGPUForProtected() const;
|
||||||
|
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
virtual void computeGeometryS3D(const sp<const DisplayDevice>& hw, Mesh& mesh,
|
||||||
|
Mesh& meshLeftTop, Mesh &meshRightBottom, uint32_t s3d_fmt) const;
|
||||||
|
#endif
|
||||||
protected:
|
protected:
|
||||||
bool mDebugLogs;
|
bool mDebugLogs;
|
||||||
bool isDebug() { return mDebugLogs; }
|
bool isDebug() { return mDebugLogs; }
|
||||||
bool mIsGPUAllowedForProtected;
|
bool mIsGPUAllowedForProtected;
|
||||||
|
bool mIsHDMIPrimary;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
// The mesh used to draw the layer in GLES composition mode for s3d left/top
|
||||||
|
mutable Mesh mMeshLeftTop;
|
||||||
|
// The mesh used to draw the layer in GLES composition mode for s3d right/bottom
|
||||||
|
mutable Mesh mMeshRightBottom;
|
||||||
|
|
||||||
|
virtual void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
|
||||||
|
bool useIdentityTransform) const;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|
||||||
|
@ -335,6 +335,10 @@ void ExSurfaceFlinger::dumpDrawCycle(bool prePrepare) {
|
|||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
ptm = localtime(&tv.tv_sec);
|
ptm = localtime(&tv.tv_sec);
|
||||||
|
if (ptm == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
strftime (hms, sizeof (hms), "%H:%M:%S", ptm);
|
strftime (hms, sizeof (hms), "%H:%M:%S", ptm);
|
||||||
millis = tv.tv_usec / 1000;
|
millis = tv.tv_usec / 1000;
|
||||||
snprintf(timeStamp, sizeof(timeStamp), "Timestamp: %s.%03ld", hms, millis);
|
snprintf(timeStamp, sizeof(timeStamp), "Timestamp: %s.%03ld", hms, millis);
|
||||||
|
@ -104,9 +104,12 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
|
|||||||
|
|
||||||
mName = name;
|
mName = name;
|
||||||
|
|
||||||
|
mCurrentState.active.x = 0;
|
||||||
|
mCurrentState.active.y = 0;
|
||||||
mCurrentState.active.w = w;
|
mCurrentState.active.w = w;
|
||||||
mCurrentState.active.h = h;
|
mCurrentState.active.h = h;
|
||||||
mCurrentState.active.crop.makeInvalid();
|
mCurrentState.active.crop.makeInvalid();
|
||||||
|
mCurrentState.active.isPositionPending = false;
|
||||||
mCurrentState.z = 0;
|
mCurrentState.z = 0;
|
||||||
mCurrentState.alpha = 0xFF;
|
mCurrentState.alpha = 0xFF;
|
||||||
mCurrentState.blur = 0xFF;
|
mCurrentState.blur = 0xFF;
|
||||||
@ -464,7 +467,11 @@ void Layer::setGeometry(
|
|||||||
|
|
||||||
// this gives us only the "orientation" component of the transform
|
// this gives us only the "orientation" component of the transform
|
||||||
const State& s(getDrawingState());
|
const State& s(getDrawingState());
|
||||||
|
#if defined(QTI_BSP) && !defined(QCOM_BSP_LEGACY)
|
||||||
|
if (!isOpaque(s)) {
|
||||||
|
#else
|
||||||
if (!isOpaque(s) || s.alpha != 0xFF) {
|
if (!isOpaque(s) || s.alpha != 0xFF) {
|
||||||
|
#endif
|
||||||
layer.setBlending(mPremultipliedAlpha ?
|
layer.setBlending(mPremultipliedAlpha ?
|
||||||
HWC_BLENDING_PREMULT :
|
HWC_BLENDING_PREMULT :
|
||||||
HWC_BLENDING_COVERAGE);
|
HWC_BLENDING_COVERAGE);
|
||||||
@ -1027,6 +1034,17 @@ uint32_t Layer::doTransaction(uint32_t flags) {
|
|||||||
if (flags & eDontUpdateGeometryState) {
|
if (flags & eDontUpdateGeometryState) {
|
||||||
} else {
|
} else {
|
||||||
Layer::State& editCurrentState(getCurrentState());
|
Layer::State& editCurrentState(getCurrentState());
|
||||||
|
// If a position change was requested, and we have the correct
|
||||||
|
// buffer size, no need to delay, update state now.
|
||||||
|
if (editCurrentState.requested.isPositionPending) {
|
||||||
|
float requestedX = editCurrentState.requested.x;
|
||||||
|
float requestedY = editCurrentState.requested.y;
|
||||||
|
if (requestedX != editCurrentState.active.x ||
|
||||||
|
requestedY != editCurrentState.active.y) {
|
||||||
|
editCurrentState.requested.isPositionPending = false;
|
||||||
|
editCurrentState.transform.set(requestedX, requestedY);
|
||||||
|
}
|
||||||
|
}
|
||||||
editCurrentState.active = c.requested;
|
editCurrentState.active = c.requested;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1064,10 +1082,15 @@ uint32_t Layer::setTransactionFlags(uint32_t flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Layer::setPosition(float x, float y) {
|
bool Layer::setPosition(float x, float y) {
|
||||||
if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
|
if ((mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y
|
||||||
|
&& !mCurrentState.requested.isPositionPending) ||
|
||||||
|
(mCurrentState.requested.isPositionPending && mCurrentState.requested.x == x
|
||||||
|
&& mCurrentState.requested.y == y))
|
||||||
return false;
|
return false;
|
||||||
mCurrentState.sequence++;
|
mCurrentState.sequence++;
|
||||||
mCurrentState.transform.set(x, y);
|
mCurrentState.requested.x = x;
|
||||||
|
mCurrentState.requested.y = y;
|
||||||
|
mCurrentState.requested.isPositionPending = true;
|
||||||
setTransactionFlags(eTransactionNeeded);
|
setTransactionFlags(eTransactionNeeded);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1290,6 +1313,19 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
|
|||||||
(bufWidth == front.requested.w &&
|
(bufWidth == front.requested.w &&
|
||||||
bufHeight == front.requested.h))
|
bufHeight == front.requested.h))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// If a position change was requested along with a resize.
|
||||||
|
// Now that we have the correct buffer size, update the position as well.
|
||||||
|
if (current.requested.isPositionPending) {
|
||||||
|
float requestedX = current.requested.x;
|
||||||
|
float requestedY = current.requested.y;
|
||||||
|
if (requestedX != current.active.x || requestedY != current.active.y) {
|
||||||
|
front.transform.set(requestedX, requestedY);
|
||||||
|
current.transform.set(requestedX, requestedY);
|
||||||
|
current.requested.isPositionPending = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Here we pretend the transaction happened by updating the
|
// Here we pretend the transaction happened by updating the
|
||||||
// current and drawing states. Drawing state is only accessed
|
// current and drawing states. Drawing state is only accessed
|
||||||
// in this thread, no need to have it locked
|
// in this thread, no need to have it locked
|
||||||
@ -1412,11 +1448,16 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
|
|||||||
|
|
||||||
// Remove any stale buffers that have been dropped during
|
// Remove any stale buffers that have been dropped during
|
||||||
// updateTexImage
|
// updateTexImage
|
||||||
while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
|
while ((mQueuedFrames > 0) && (mQueueItems[0].mFrameNumber != currentFrameNumber)) {
|
||||||
mQueueItems.removeAt(0);
|
mQueueItems.removeAt(0);
|
||||||
android_atomic_dec(&mQueuedFrames);
|
android_atomic_dec(&mQueuedFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mQueuedFrames == 0) {
|
||||||
|
ALOGE("[%s] mQueuedFrames is zero !!", mName.string());
|
||||||
|
return outDirtyRegion;
|
||||||
|
}
|
||||||
|
|
||||||
mQueueItems.removeAt(0);
|
mQueueItems.removeAt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,11 +95,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Geometry {
|
struct Geometry {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
uint32_t w;
|
uint32_t w;
|
||||||
uint32_t h;
|
uint32_t h;
|
||||||
|
bool isPositionPending;
|
||||||
Rect crop;
|
Rect crop;
|
||||||
inline bool operator ==(const Geometry& rhs) const {
|
inline bool operator ==(const Geometry& rhs) const {
|
||||||
return (w == rhs.w && h == rhs.h && crop == rhs.crop);
|
return (w == rhs.w && h == rhs.h && crop == rhs.crop && x == rhs.x && y == rhs.y
|
||||||
|
&& isPositionPending == rhs.isPositionPending);
|
||||||
}
|
}
|
||||||
inline bool operator !=(const Geometry& rhs) const {
|
inline bool operator !=(const Geometry& rhs) const {
|
||||||
return !operator ==(rhs);
|
return !operator ==(rhs);
|
||||||
@ -158,8 +162,13 @@ public:
|
|||||||
uint32_t getTransactionFlags(uint32_t flags);
|
uint32_t getTransactionFlags(uint32_t flags);
|
||||||
uint32_t setTransactionFlags(uint32_t flags);
|
uint32_t setTransactionFlags(uint32_t flags);
|
||||||
|
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
virtual void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
|
||||||
|
bool useIdentityTransform) const;
|
||||||
|
#else
|
||||||
void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
|
void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
|
||||||
bool useIdentityTransform) const;
|
bool useIdentityTransform) const;
|
||||||
|
#endif
|
||||||
Rect computeBounds(const Region& activeTransparentRegion) const;
|
Rect computeBounds(const Region& activeTransparentRegion) const;
|
||||||
Rect computeBounds() const;
|
Rect computeBounds() const;
|
||||||
|
|
||||||
@ -388,9 +397,14 @@ private:
|
|||||||
// drawing
|
// drawing
|
||||||
void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
|
void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
|
||||||
float r, float g, float b, float alpha) const;
|
float r, float g, float b, float alpha) const;
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
virtual void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
|
||||||
|
bool useIdentityTransform) const;
|
||||||
|
#else
|
||||||
void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
|
void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
|
||||||
bool useIdentityTransform) const;
|
bool useIdentityTransform) const;
|
||||||
|
|
||||||
|
#endif
|
||||||
// Temporary - Used only for LEGACY camera mode.
|
// Temporary - Used only for LEGACY camera mode.
|
||||||
uint32_t getProducerStickyTransform() const;
|
uint32_t getProducerStickyTransform() const;
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <utils/Errors.h>
|
#include <utils/Errors.h>
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
@ -90,16 +91,11 @@ static void setupMesh(Mesh& mesh, int width, int height, int viewportHeight) {
|
|||||||
texCoords[3] = vec2(1.0f, 1.0f);
|
texCoords[3] = vec2(1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LayerBlur::LayerBlur(SurfaceFlinger* flinger, const sp<Client>& client,
|
LayerBlur::LayerBlur(SurfaceFlinger* flinger, const sp<Client>& client,
|
||||||
const String8& name, uint32_t w, uint32_t h, uint32_t flags)
|
const String8& name, uint32_t w, uint32_t h, uint32_t flags)
|
||||||
: Layer(flinger, client, name, w, h, flags), mBlurMaskSampling(1), mBlurMaskAlphaThreshold(0.0f)
|
: Layer(flinger, client, name, w, h, flags), mBlurMaskSampling(1),
|
||||||
,mLastFrameSequence(0)
|
mBlurMaskAlphaThreshold(0.0f) ,mLastFrameSequence(0)
|
||||||
{
|
{
|
||||||
#ifdef UI_BLUR
|
|
||||||
mBlurToken = qtiblur::initBlurToken();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GLuint texnames[3];
|
GLuint texnames[3];
|
||||||
mFlinger->getRenderEngine().genTextures(3, texnames);
|
mFlinger->getRenderEngine().genTextures(3, texnames);
|
||||||
mTextureCapture.init(Texture::TEXTURE_2D, texnames[0]);
|
mTextureCapture.init(Texture::TEXTURE_2D, texnames[0]);
|
||||||
@ -108,9 +104,6 @@ LayerBlur::LayerBlur(SurfaceFlinger* flinger, const sp<Client>& client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
LayerBlur::~LayerBlur() {
|
LayerBlur::~LayerBlur() {
|
||||||
#ifdef UI_BLUR
|
|
||||||
qtiblur::releaseBlurToken(mBlurToken);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
releaseFbo(mFboCapture);
|
releaseFbo(mFboCapture);
|
||||||
releaseFbo(mFboMasking);
|
releaseFbo(mFboMasking);
|
||||||
@ -168,18 +161,15 @@ void LayerBlur::onDraw(const sp<const DisplayDevice>& hw, const Region& /*clip*/
|
|||||||
// blur
|
// blur
|
||||||
size_t outTexWidth = mTextureBlur.getWidth();
|
size_t outTexWidth = mTextureBlur.getWidth();
|
||||||
size_t outTexHeight = mTextureBlur.getHeight();
|
size_t outTexHeight = mTextureBlur.getHeight();
|
||||||
#ifdef UI_BLUR
|
if (mBlurImpl.blur(s.blur,
|
||||||
if (!qtiblur::blur(mBlurToken,
|
|
||||||
s.blur,
|
|
||||||
mTextureCapture.getTextureName(),
|
mTextureCapture.getTextureName(),
|
||||||
mTextureCapture.getWidth(),
|
mTextureCapture.getWidth(),
|
||||||
mTextureCapture.getHeight(),
|
mTextureCapture.getHeight(),
|
||||||
mTextureBlur.getTextureName(),
|
mTextureBlur.getTextureName(),
|
||||||
&outTexWidth,
|
&outTexWidth,
|
||||||
&outTexHeight)) {
|
&outTexHeight) != OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// mTextureBlur now has "Blurred image"
|
// mTextureBlur now has "Blurred image"
|
||||||
mTextureBlur.setDimensions(outTexWidth, outTexHeight);
|
mTextureBlur.setDimensions(outTexWidth, outTexHeight);
|
||||||
@ -238,8 +228,7 @@ bool LayerBlur::captureScreen(const sp<const DisplayDevice>& hw, FBO& fbo, Textu
|
|||||||
texture.getTextureName(), 0);
|
texture.getTextureName(), 0);
|
||||||
|
|
||||||
mFlinger->getRenderEngine().clearWithColor(0.0f, 0.0f, 0.0f, 1.0f);
|
mFlinger->getRenderEngine().clearWithColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
if (hw->isPanelInverseMounted())
|
rotation = (Transform::orientation_flags)(rotation ^ hw->getPanelMountFlip());
|
||||||
rotation = Transform::ROT_180;
|
|
||||||
mFlinger->renderScreenImplLocked(
|
mFlinger->renderScreenImplLocked(
|
||||||
hw,
|
hw,
|
||||||
Rect(0,0,width,height),
|
Rect(0,0,width,height),
|
||||||
@ -412,6 +401,86 @@ void LayerBlur::ensureFbo(FBO& fbo, int width, int height, int textureName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void* LayerBlur::BlurImpl::sLibHandle = NULL;
|
||||||
|
bool LayerBlur::BlurImpl::sUnsupported = false;
|
||||||
|
|
||||||
|
LayerBlur::BlurImpl::initBlurTokenFn LayerBlur::BlurImpl::initBlurToken = NULL;
|
||||||
|
LayerBlur::BlurImpl::releaseBlurTokenFn LayerBlur::BlurImpl::releaseBlurToken = NULL;
|
||||||
|
LayerBlur::BlurImpl::blurFn LayerBlur::BlurImpl::doBlur = NULL;
|
||||||
|
Mutex LayerBlur::BlurImpl::sLock;
|
||||||
|
|
||||||
|
void LayerBlur::BlurImpl::closeBlurImpl() {
|
||||||
|
if (sLibHandle != NULL) {
|
||||||
|
dlclose(sLibHandle);
|
||||||
|
sLibHandle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t LayerBlur::BlurImpl::initBlurImpl() {
|
||||||
|
if (sLibHandle != NULL) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
if (sUnsupported) {
|
||||||
|
return NO_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sLibHandle = dlopen("libuiblur.so", RTLD_NOW);
|
||||||
|
if (sLibHandle == NULL) {
|
||||||
|
sUnsupported = true;
|
||||||
|
return NO_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// happy happy joy joy!
|
||||||
|
|
||||||
|
initBlurToken = (initBlurTokenFn)dlsym(sLibHandle,
|
||||||
|
"_ZN7qtiblur13initBlurTokenEv");
|
||||||
|
releaseBlurToken = (releaseBlurTokenFn)dlsym(sLibHandle,
|
||||||
|
"_ZN7qtiblur16releaseBlurTokenEPv");
|
||||||
|
|
||||||
|
if (sizeof(size_t) == 4) {
|
||||||
|
doBlur = (blurFn)dlsym(sLibHandle,
|
||||||
|
"_ZN7qtiblur4blurEPvijjjjPjS1_");
|
||||||
|
} else if (sizeof(size_t) == 8) {
|
||||||
|
doBlur = (blurFn)dlsym(sLibHandle,
|
||||||
|
"_ZN7qtiblur4blurEPvijmmjPmS1_");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!initBlurToken || !releaseBlurToken || !doBlur) {
|
||||||
|
ALOGE("dlsym failed for blur impl!: %s", dlerror());
|
||||||
|
closeBlurImpl();
|
||||||
|
sUnsupported = true;
|
||||||
|
return NO_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerBlur::BlurImpl::BlurImpl() : mToken(NULL) {
|
||||||
|
Mutex::Autolock _l(sLock);
|
||||||
|
if (initBlurImpl() == OK) {
|
||||||
|
mToken = initBlurToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerBlur::BlurImpl::~BlurImpl() {
|
||||||
|
Mutex::Autolock _l(sLock);
|
||||||
|
if (mToken != NULL) {
|
||||||
|
releaseBlurToken(mToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t LayerBlur::BlurImpl::blur(int level, uint32_t inId, size_t inWidth, size_t inHeight,
|
||||||
|
uint32_t outId, size_t* outWidth, size_t* outHeight) {
|
||||||
|
Mutex::Autolock _l(sLock);
|
||||||
|
if (mToken == NULL) {
|
||||||
|
return NO_INIT;
|
||||||
|
}
|
||||||
|
return doBlur(mToken, level, inId, inWidth, inHeight,
|
||||||
|
outId, outWidth, outHeight) ? OK : NO_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -20,15 +20,12 @@
|
|||||||
#ifndef ANDROID_LAYER_BLUR_H
|
#ifndef ANDROID_LAYER_BLUR_H
|
||||||
#define ANDROID_LAYER_BLUR_H
|
#define ANDROID_LAYER_BLUR_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
|
|
||||||
#ifdef UI_BLUR
|
|
||||||
#include "Blur.h" // libuiblur.so
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
@ -58,9 +55,37 @@ public:
|
|||||||
virtual bool setBlurMaskAlphaThreshold(float alpha) { mBlurMaskAlphaThreshold = alpha; return true; }
|
virtual bool setBlurMaskAlphaThreshold(float alpha) { mBlurMaskAlphaThreshold = alpha; return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef UI_BLUR
|
class BlurImpl {
|
||||||
qtiblur::BLUR_TOKEN mBlurToken;
|
public:
|
||||||
#endif
|
|
||||||
|
BlurImpl();
|
||||||
|
~BlurImpl();
|
||||||
|
|
||||||
|
status_t blur(int level, uint32_t inId, size_t inWidth, size_t inheight,
|
||||||
|
uint32_t outId, size_t* outWidth, size_t* outHeight);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static status_t initBlurImpl();
|
||||||
|
static void closeBlurImpl();
|
||||||
|
static void* sLibHandle;
|
||||||
|
static bool sUnsupported;
|
||||||
|
|
||||||
|
typedef void* (*initBlurTokenFn)();
|
||||||
|
typedef void* (*releaseBlurTokenFn)(void*);
|
||||||
|
typedef void* (*blurFn)(void*, int, uint32_t, size_t, size_t, uint32_t, size_t*, size_t*);
|
||||||
|
|
||||||
|
static initBlurTokenFn initBlurToken;
|
||||||
|
static releaseBlurTokenFn releaseBlurToken;
|
||||||
|
static blurFn doBlur;
|
||||||
|
|
||||||
|
static Mutex sLock;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* mToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
BlurImpl mBlurImpl;
|
||||||
|
|
||||||
wp<Layer> mBlurMaskLayer;
|
wp<Layer> mBlurMaskLayer;
|
||||||
int32_t mBlurMaskSampling;
|
int32_t mBlurMaskSampling;
|
||||||
float mBlurMaskAlphaThreshold;
|
float mBlurMaskAlphaThreshold;
|
||||||
|
@ -74,6 +74,7 @@
|
|||||||
|
|
||||||
#include "DisplayHardware/FramebufferSurface.h"
|
#include "DisplayHardware/FramebufferSurface.h"
|
||||||
#include "DisplayHardware/HWComposer.h"
|
#include "DisplayHardware/HWComposer.h"
|
||||||
|
#include "ExSurfaceFlinger/ExHWComposer.h"
|
||||||
#include "DisplayHardware/VirtualDisplaySurface.h"
|
#include "DisplayHardware/VirtualDisplaySurface.h"
|
||||||
|
|
||||||
#include "Effects/Daltonizer.h"
|
#include "Effects/Daltonizer.h"
|
||||||
@ -82,6 +83,10 @@
|
|||||||
#include <cutils/compiler.h>
|
#include <cutils/compiler.h>
|
||||||
#include "DisplayUtils.h"
|
#include "DisplayUtils.h"
|
||||||
|
|
||||||
|
#ifdef USES_HWC_SERVICES
|
||||||
|
#include "ExynosHWCService.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DISPLAY_COUNT 1
|
#define DISPLAY_COUNT 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -130,6 +135,10 @@ static sp<Layer> lastSurfaceViewLayer;
|
|||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef USES_HWC_SERVICES
|
||||||
|
static bool notifyPSRExit = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
SurfaceFlinger::SurfaceFlinger()
|
SurfaceFlinger::SurfaceFlinger()
|
||||||
: BnSurfaceComposer(),
|
: BnSurfaceComposer(),
|
||||||
mTransactionFlags(0),
|
mTransactionFlags(0),
|
||||||
@ -156,6 +165,7 @@ SurfaceFlinger::SurfaceFlinger()
|
|||||||
mHWVsyncAvailable(false),
|
mHWVsyncAvailable(false),
|
||||||
mDaltonize(false),
|
mDaltonize(false),
|
||||||
mHasColorMatrix(false),
|
mHasColorMatrix(false),
|
||||||
|
mHasSecondaryColorMatrix(false),
|
||||||
mHasPoweredOff(false),
|
mHasPoweredOff(false),
|
||||||
mFrameBuckets(),
|
mFrameBuckets(),
|
||||||
mTotalTime(0),
|
mTotalTime(0),
|
||||||
@ -311,6 +321,14 @@ void SurfaceFlinger::bootFinished()
|
|||||||
// formerly we would just kill the process, but we now ask it to exit so it
|
// formerly we would just kill the process, but we now ask it to exit so it
|
||||||
// can choose where to stop the animation.
|
// can choose where to stop the animation.
|
||||||
property_set("service.bootanim.exit", "1");
|
property_set("service.bootanim.exit", "1");
|
||||||
|
|
||||||
|
#ifdef USES_HWC_SERVICES
|
||||||
|
sp<IServiceManager> sm = defaultServiceManager();
|
||||||
|
sp<android::IExynosHWCService> hwc =
|
||||||
|
interface_cast<android::IExynosHWCService>(sm->getService(String16("Exynos.HWCService")));
|
||||||
|
ALOGD("boot finished. Inform HWC");
|
||||||
|
hwc->setBootFinished();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
|
void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
|
||||||
@ -797,6 +815,19 @@ void SurfaceFlinger::signalTransaction() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::signalLayerUpdate() {
|
void SurfaceFlinger::signalLayerUpdate() {
|
||||||
|
#ifdef USES_HWC_SERVICES
|
||||||
|
if (notifyPSRExit) {
|
||||||
|
notifyPSRExit = false;
|
||||||
|
sp<IServiceManager> sm = defaultServiceManager();
|
||||||
|
sp<IExynosHWCService> hwcService =
|
||||||
|
interface_cast<android::IExynosHWCService>(
|
||||||
|
sm->getService(String16("Exynos.HWCService")));
|
||||||
|
if (hwcService != NULL)
|
||||||
|
hwcService->notifyPSRExit();
|
||||||
|
else
|
||||||
|
ALOGE("HWCService::notifyPSRExit failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
mEventQueue.invalidate();
|
mEventQueue.invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,6 +1012,9 @@ void SurfaceFlinger::handleMessageRefresh() {
|
|||||||
doDebugFlashRegions();
|
doDebugFlashRegions();
|
||||||
doComposition();
|
doComposition();
|
||||||
postComposition();
|
postComposition();
|
||||||
|
#ifdef USES_HWC_SERVICES
|
||||||
|
notifyPSRExit = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);
|
previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);
|
||||||
@ -1193,7 +1227,7 @@ void SurfaceFlinger::setUpHWComposer() {
|
|||||||
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
|
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
|
||||||
const sp<Layer>& layer(currentLayers[i]);
|
const sp<Layer>& layer(currentLayers[i]);
|
||||||
layer->setGeometry(hw, *cur);
|
layer->setGeometry(hw, *cur);
|
||||||
if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
|
if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix || mHasSecondaryColorMatrix) {
|
||||||
cur->setSkip(true);
|
cur->setSkip(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1958,11 +1992,14 @@ void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
|
if (CC_LIKELY(!mDaltonize && !mHasColorMatrix && !mHasSecondaryColorMatrix)) {
|
||||||
if (!doComposeSurfaces(hw, dirtyRegion)) return;
|
if (!doComposeSurfaces(hw, dirtyRegion)) return;
|
||||||
} else {
|
} else {
|
||||||
RenderEngine& engine(getRenderEngine());
|
RenderEngine& engine(getRenderEngine());
|
||||||
mat4 colorMatrix = mColorMatrix;
|
mat4 colorMatrix = mColorMatrix;
|
||||||
|
if (mHasSecondaryColorMatrix) {
|
||||||
|
colorMatrix = mHasColorMatrix ? (colorMatrix * mSecondaryColorMatrix) : mSecondaryColorMatrix;
|
||||||
|
}
|
||||||
if (mDaltonize) {
|
if (mDaltonize) {
|
||||||
colorMatrix = colorMatrix * mDaltonizer();
|
colorMatrix = colorMatrix * mDaltonizer();
|
||||||
}
|
}
|
||||||
@ -1999,7 +2036,12 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Never touch the framebuffer if we don't have any framebuffer layers
|
// Never touch the framebuffer if we don't have any framebuffer layers
|
||||||
|
#if defined(QTI_BSP) && defined(SDM_TARGET)
|
||||||
|
const bool hasHwcComposition = hwc.hasHwcComposition(id) |
|
||||||
|
(reinterpret_cast<ExHWComposer*>(&hwc))->getS3DFlag(id);
|
||||||
|
#else
|
||||||
const bool hasHwcComposition = hwc.hasHwcComposition(id);
|
const bool hasHwcComposition = hwc.hasHwcComposition(id);
|
||||||
|
#endif
|
||||||
if (hasHwcComposition) {
|
if (hasHwcComposition) {
|
||||||
// when using overlays, we assume a fully transparent framebuffer
|
// when using overlays, we assume a fully transparent framebuffer
|
||||||
// NOTE: we could reduce how much we need to clear, for instance
|
// NOTE: we could reduce how much we need to clear, for instance
|
||||||
@ -2948,7 +2990,8 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
|
|||||||
result.appendFormat(" h/w composer %s and %s\n",
|
result.appendFormat(" h/w composer %s and %s\n",
|
||||||
hwc.initCheck()==NO_ERROR ? "present" : "not present",
|
hwc.initCheck()==NO_ERROR ? "present" : "not present",
|
||||||
(mDebugDisableHWC || mDebugRegion || mDaltonize
|
(mDebugDisableHWC || mDebugRegion || mDaltonize
|
||||||
|| mHasColorMatrix) ? "disabled" : "enabled");
|
|| mHasColorMatrix
|
||||||
|
|| mHasSecondaryColorMatrix) ? "disabled" : "enabled");
|
||||||
hwc.dump(result);
|
hwc.dump(result);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3158,6 +3201,28 @@ status_t SurfaceFlinger::onTransact(
|
|||||||
mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
|
mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
case 1030: {
|
||||||
|
// apply a secondary color matrix
|
||||||
|
// this will be combined with any other transformations
|
||||||
|
n = data.readInt32();
|
||||||
|
mHasSecondaryColorMatrix = n ? 1 : 0;
|
||||||
|
if (n) {
|
||||||
|
// color matrix is sent as mat3 matrix followed by vec3
|
||||||
|
// offset, then packed into a mat4 where the last row is
|
||||||
|
// the offset and extra values are 0
|
||||||
|
for (size_t i = 0 ; i < 4; i++) {
|
||||||
|
for (size_t j = 0; j < 4; j++) {
|
||||||
|
mSecondaryColorMatrix[i][j] = data.readFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mSecondaryColorMatrix = mat4();
|
||||||
|
}
|
||||||
|
invalidateHwcGeometry();
|
||||||
|
repaintEverything();
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
@ -3436,10 +3501,9 @@ void SurfaceFlinger::renderScreenImplLocked(
|
|||||||
// make sure to clear all GL error flags
|
// make sure to clear all GL error flags
|
||||||
engine.checkErrors();
|
engine.checkErrors();
|
||||||
|
|
||||||
if (DisplayDevice::DISPLAY_PRIMARY == hw->getDisplayType() &&
|
if (DisplayDevice::DISPLAY_PRIMARY == hw->getDisplayType()) {
|
||||||
hw->isPanelInverseMounted()) {
|
|
||||||
rotation = (Transform::orientation_flags)
|
rotation = (Transform::orientation_flags)
|
||||||
(rotation ^ Transform::ROT_180);
|
(rotation ^ hw->getPanelMountFlip());
|
||||||
}
|
}
|
||||||
|
|
||||||
// set-up our viewport
|
// set-up our viewport
|
||||||
|
@ -146,6 +146,9 @@ private:
|
|||||||
friend class DisplayEventConnection;
|
friend class DisplayEventConnection;
|
||||||
friend class Layer;
|
friend class Layer;
|
||||||
friend class LayerDim;
|
friend class LayerDim;
|
||||||
|
#ifdef QTI_BSP
|
||||||
|
friend class ExLayer;
|
||||||
|
#endif
|
||||||
friend class MonitoredProducer;
|
friend class MonitoredProducer;
|
||||||
friend class LayerBlur;
|
friend class LayerBlur;
|
||||||
|
|
||||||
@ -553,6 +556,9 @@ private:
|
|||||||
mat4 mColorMatrix;
|
mat4 mColorMatrix;
|
||||||
bool mHasColorMatrix;
|
bool mHasColorMatrix;
|
||||||
|
|
||||||
|
mat4 mSecondaryColorMatrix;
|
||||||
|
bool mHasSecondaryColorMatrix;
|
||||||
|
|
||||||
// Static screen stats
|
// Static screen stats
|
||||||
bool mHasPoweredOff;
|
bool mHasPoweredOff;
|
||||||
static const size_t NUM_BUCKETS = 8; // < 1-7, 7+
|
static const size_t NUM_BUCKETS = 8; // < 1-7, 7+
|
||||||
|
@ -249,4 +249,50 @@ TEST_F(LayerUpdateTest, LayerResizeWorks) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure that if we move and resize a surface in the same
|
||||||
|
// transaction, we don't reposition the surface and draw
|
||||||
|
// using the incorrect buffer size
|
||||||
|
TEST_F(LayerUpdateTest, LayerMoveAndResizeWorks) {
|
||||||
|
sp<ScreenCapture> sc;
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("before resize and reposition");
|
||||||
|
ScreenCapture::captureScreen(&sc);
|
||||||
|
sc->checkPixel( 0, 12, 63, 63, 195);
|
||||||
|
sc->checkPixel( 75, 75, 195, 63, 63);
|
||||||
|
sc->checkPixel(145, 145, 63, 63, 195);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALOGD("resizing and repositioning");
|
||||||
|
SurfaceComposerClient::openGlobalTransaction();
|
||||||
|
ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(64, 0));
|
||||||
|
ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setSize(64, 128));
|
||||||
|
SurfaceComposerClient::closeGlobalTransaction(true);
|
||||||
|
|
||||||
|
ALOGD("resized and repositioned");
|
||||||
|
{
|
||||||
|
// This should not reflect the new size, position or color because SurfaceFlinger
|
||||||
|
// has not yet received a buffer of the correct size.
|
||||||
|
SCOPED_TRACE("after resize, before redraw");
|
||||||
|
ScreenCapture::captureScreen(&sc);
|
||||||
|
sc->checkPixel( 0, 12, 63, 63, 195);
|
||||||
|
sc->checkPixel( 75, 75, 195, 63, 63);
|
||||||
|
sc->checkPixel(145, 145, 63, 63, 195);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALOGD("drawing");
|
||||||
|
fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63);
|
||||||
|
waitForPostedBuffers();
|
||||||
|
ALOGD("drawn");
|
||||||
|
{
|
||||||
|
// This should reflect the new size, position and the new color.
|
||||||
|
SCOPED_TRACE("after redraw");
|
||||||
|
ScreenCapture::captureScreen(&sc);
|
||||||
|
sc->checkPixel( 64, 0, 63, 195, 63);
|
||||||
|
// This should pass to imply that we didn't have a frame where the
|
||||||
|
// surface was moved but not yet resized even though the operations
|
||||||
|
// were part of the same transaction
|
||||||
|
sc->checkPixel( 64, 75, 63, 195, 63);
|
||||||
|
sc->checkPixel(145, 145, 63, 63, 195);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user