Merge changes from topic "capture-child-layers" into pi-dev
* changes:
SurfaceFlinger: Add childLayersOnly variant of capture layers.
SurfaceFlinger: Add "Abstract" Layer type.
SurfaceFlinger: Move trivial implementations to layer base class.
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 898aa90..57745ef 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -1221,8 +1221,10 @@
}
bool ok = true;
- ok &= setUpTrace();
- ok &= startTrace();
+ if (traceStart) {
+ ok &= setUpTrace();
+ ok &= startTrace();
+ }
if (ok && traceStart) {
if (!traceStream) {
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index 562898d..b04543b 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -76,6 +76,7 @@
"libdebuggerd_client",
"libdumpstateaidl",
"libdumpstateutil",
+ "libdumputils",
"libhidlbase",
"libhidltransport",
"liblog",
@@ -119,4 +120,4 @@
"tests/dumpstate_smoke_test.cpp",
],
static_libs: ["libgmock"],
-}
\ No newline at end of file
+}
diff --git a/cmds/dumpstate/DumpstateInternal.cpp b/cmds/dumpstate/DumpstateInternal.cpp
index 83e30a2..819d5b9 100644
--- a/cmds/dumpstate/DumpstateInternal.cpp
+++ b/cmds/dumpstate/DumpstateInternal.cpp
@@ -98,13 +98,25 @@
capheader.version = _LINUX_CAPABILITY_VERSION_3;
capheader.pid = 0;
- capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
- capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
- capdata[0].inheritable = 0;
- capdata[1].inheritable = 0;
+ if (capget(&capheader, &capdata[0]) != 0) {
+ MYLOGE("capget failed: %s\n", strerror(errno));
+ return false;
+ }
- if (capset(&capheader, &capdata[0]) < 0) {
- MYLOGE("capset failed: %s\n", strerror(errno));
+ const uint32_t cap_syslog_mask = CAP_TO_MASK(CAP_SYSLOG);
+ const uint32_t cap_syslog_index = CAP_TO_INDEX(CAP_SYSLOG);
+ bool has_cap_syslog = (capdata[cap_syslog_index].effective & cap_syslog_mask) != 0;
+
+ memset(&capdata, 0, sizeof(capdata));
+ if (has_cap_syslog) {
+ // Only attempt to keep CAP_SYSLOG if it was present to begin with.
+ capdata[cap_syslog_index].permitted |= cap_syslog_mask;
+ capdata[cap_syslog_index].effective |= cap_syslog_mask;
+ }
+
+ if (capset(&capheader, &capdata[0]) != 0) {
+ MYLOGE("capset({%#x, %#x}) failed: %s\n", capdata[0].effective,
+ capdata[1].effective, strerror(errno));
return false;
}
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index d8bbdbb..10f252f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -176,6 +176,11 @@
std::unique_ptr<std::vector<DumpData>> dump_data(new std::vector<DumpData>());
std::unique_ptr<DIR, decltype(&closedir)> dump_dir(opendir(dir_path.c_str()), closedir);
+ if (dump_dir == nullptr) {
+ MYLOGW("Unable to open directory %s: %s\n", dir_path.c_str(), strerror(errno));
+ return dump_data.release();
+ }
+
struct dirent* entry = nullptr;
while ((entry = readdir(dump_dir.get()))) {
if (entry->d_type != DT_REG) {
@@ -191,13 +196,13 @@
android::base::unique_fd fd(
TEMP_FAILURE_RETRY(open(abs_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)));
if (fd == -1) {
- MYLOGW("Unable to open dump file: %s %s\n", abs_path.c_str(), strerror(errno));
+ MYLOGW("Unable to open dump file %s: %s\n", abs_path.c_str(), strerror(errno));
break;
}
struct stat st = {};
if (fstat(fd, &st) == -1) {
- MYLOGW("Unable to stat dump file: %s %s\n", abs_path.c_str(), strerror(errno));
+ MYLOGW("Unable to stat dump file %s: %s\n", abs_path.c_str(), strerror(errno));
continue;
}
@@ -1506,6 +1511,12 @@
RunDumpsys("TELEPHONY SERVICES", {"activity", "service", "TelephonyDebugService"});
printf("========================================================\n");
+ printf("== Checkins\n");
+ printf("========================================================\n");
+
+ RunDumpsys("CHECKIN BATTERYSTATS", {"batterystats", "-c"});
+
+ printf("========================================================\n");
printf("== dumpstate: done (id %d)\n", ds.id_);
printf("========================================================\n");
}
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index a89925f..022f4fc 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -48,10 +48,10 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
-#include <android/hidl/manager/1.0/IServiceManager.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
#include <debuggerd/client.h>
+#include <dumputils/dump_utils.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>
@@ -76,36 +76,6 @@
return ds.RunCommand(title, full_command, options);
}
-/* list of native processes to include in the native dumps */
-// This matches the /proc/pid/exe link instead of /proc/pid/cmdline.
-static const char* native_processes_to_dump[] = {
- "/system/bin/audioserver",
- "/system/bin/cameraserver",
- "/system/bin/drmserver",
- "/system/bin/mediadrmserver",
- "/system/bin/mediaextractor", // media.extractor
- "/system/bin/mediametrics", // media.metrics
- "/system/bin/mediaserver",
- "/system/bin/sdcard",
- "/system/bin/statsd",
- "/system/bin/surfaceflinger",
- "/system/bin/vehicle_network_service",
- "/vendor/bin/hw/android.hardware.media.omx@1.0-service", // media.codec
- NULL,
-};
-
-/* list of hal interface to dump containing process during native dumps */
-static const char* hal_interfaces_to_dump[] {
- "android.hardware.audio@2.0::IDevicesFactory",
- "android.hardware.bluetooth@1.0::IBluetoothHci",
- "android.hardware.camera.provider@2.4::ICameraProvider",
- "android.hardware.graphics.composer@2.1::IComposer",
- "android.hardware.media.omx@1.0::IOmx",
- "android.hardware.sensors@1.0::ISensors",
- "android.hardware.vr@1.0::IVr",
- NULL,
-};
-
// Reasonable value for max stats.
static const int STATS_MAX_N_RUNS = 1000;
static const long STATS_MAX_AVERAGE = 100000;
@@ -809,53 +779,6 @@
_redirect_to_file(redirect, path, O_APPEND);
}
-static bool should_dump_hal_interface(const char* interface) {
- for (const char** i = hal_interfaces_to_dump; *i; i++) {
- if (!strcmp(*i, interface)) {
- return true;
- }
- }
- return false;
-}
-
-static bool should_dump_native_traces(const char* path) {
- for (const char** p = native_processes_to_dump; *p; p++) {
- if (!strcmp(*p, path)) {
- return true;
- }
- }
- return false;
-}
-
-std::set<int> get_interesting_hal_pids() {
- using android::hidl::manager::V1_0::IServiceManager;
- using android::sp;
- using android::hardware::Return;
-
- sp<IServiceManager> manager = IServiceManager::getService();
- std::set<int> pids;
-
- Return<void> ret = manager->debugDump([&](auto& hals) {
- for (const auto &info : hals) {
- if (info.pid == static_cast<int>(IServiceManager::PidConstant::NO_PID)) {
- continue;
- }
-
- if (!should_dump_hal_interface(info.interfaceName.c_str())) {
- continue;
- }
-
- pids.insert(info.pid);
- }
- });
-
- if (!ret.isOk()) {
- MYLOGE("Could not get list of HAL PIDs: %s\n", ret.description().c_str());
- }
-
- return pids; // whether it was okay or not
-}
-
const char* DumpTraces(const std::string& traces_path);
const char* DumpTracesTombstoned(const std::string& traces_dir);
@@ -876,18 +799,6 @@
return nullptr;
}
-static bool IsZygote(int pid) {
- static const std::string kZygotePrefix = "zygote";
-
- std::string cmdline;
- if (!android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/cmdline", pid),
- &cmdline)) {
- return true;
- }
-
- return (cmdline.find(kZygotePrefix) == 0);
-}
-
const char* DumpTracesTombstoned(const std::string& traces_dir) {
const std::string temp_file_pattern = traces_dir + "/dumptrace_XXXXXX";
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 230853d..e1e73c7 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -230,7 +230,7 @@
const char* instruction_set, const char* compiler_filter,
bool debuggable, bool post_bootcomplete, bool background_job_compile, int profile_fd,
const char* class_loader_context, int target_sdk_version, bool enable_hidden_api_checks,
- int dex_metadata_fd, const char* compilation_reason) {
+ bool generate_compact_dex, int dex_metadata_fd, const char* compilation_reason) {
static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
@@ -438,9 +438,7 @@
// Disable cdex if update input vdex is true since this combination of options is not
// supported.
- // Disable cdex for non-background compiles since we don't want to regress app install until
- // there are enough benefits to justify the tradeoff.
- const bool disable_cdex = !background_job_compile || (input_vdex_fd == output_vdex_fd);
+ const bool disable_cdex = !generate_compact_dex || (input_vdex_fd == output_vdex_fd);
const char* argv[9 // program name, mandatory arguments and the final NULL
+ (have_dex2oat_isa_variant ? 1 : 0)
@@ -1960,6 +1958,7 @@
bool is_secondary_dex = (dexopt_flags & DEXOPT_SECONDARY_DEX) != 0;
bool background_job_compile = (dexopt_flags & DEXOPT_IDLE_BACKGROUND_JOB) != 0;
bool enable_hidden_api_checks = (dexopt_flags & DEXOPT_ENABLE_HIDDEN_API_CHECKS) != 0;
+ bool generate_compact_dex = (dexopt_flags & DEXOPT_GENERATE_COMPACT_DEX) != 0;
// Check if we're dealing with a secondary dex file and if we need to compile it.
std::string oat_dir_str;
@@ -2073,6 +2072,7 @@
class_loader_context,
target_sdk_version,
enable_hidden_api_checks,
+ generate_compact_dex,
dex_metadata_fd.get(),
compilation_reason);
} else {
diff --git a/cmds/installd/installd_constants.h b/cmds/installd/installd_constants.h
index 6282ba2..26aa443 100644
--- a/cmds/installd/installd_constants.h
+++ b/cmds/installd/installd_constants.h
@@ -53,6 +53,7 @@
// controls whether extra debugging flags can be used (taking more compile time.)
constexpr int DEXOPT_IDLE_BACKGROUND_JOB = 1 << 9;
constexpr int DEXOPT_ENABLE_HIDDEN_API_CHECKS = 1 << 10;
+constexpr int DEXOPT_GENERATE_COMPACT_DEX = 1 << 11;
/* all known values for dexopt flags */
constexpr int DEXOPT_MASK =
@@ -65,7 +66,8 @@
| DEXOPT_STORAGE_CE
| DEXOPT_STORAGE_DE
| DEXOPT_IDLE_BACKGROUND_JOB
- | DEXOPT_ENABLE_HIDDEN_API_CHECKS;
+ | DEXOPT_ENABLE_HIDDEN_API_CHECKS
+ | DEXOPT_GENERATE_COMPACT_DEX;
// NOTE: keep in sync with StorageManager
constexpr int FLAG_STORAGE_DE = 1 << 0;
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index c1a1202..58355f9 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -81,8 +81,9 @@
static_assert(DEXOPT_STORAGE_DE == 1 << 8, "DEXOPT_STORAGE_DE unexpected.");
static_assert(DEXOPT_ENABLE_HIDDEN_API_CHECKS == 1 << 10,
"DEXOPT_ENABLE_HIDDEN_API_CHECKS unexpected");
+static_assert(DEXOPT_GENERATE_COMPACT_DEX == 1 << 11, "DEXOPT_GENERATE_COMPACT_DEX unexpected");
-static_assert(DEXOPT_MASK == (0x5fe | DEXOPT_IDLE_BACKGROUND_JOB),
+static_assert(DEXOPT_MASK == (0xdfe | DEXOPT_IDLE_BACKGROUND_JOB),
"DEXOPT_MASK unexpected.");
diff --git a/cmds/installd/otapreopt_parameters.cpp b/cmds/installd/otapreopt_parameters.cpp
index 802d5d7..d56aec9 100644
--- a/cmds/installd/otapreopt_parameters.cpp
+++ b/cmds/installd/otapreopt_parameters.cpp
@@ -133,6 +133,9 @@
// The compilation reason is ab-ota (match the system property pm.dexopt.ab-ota)
compilation_reason = "ab-ota";
+
+ // Flag is enabled by default for A/B otas.
+ dexopt_flags = DEXOPT_GENERATE_COMPACT_DEX;
}
bool OTAPreoptParameters::ReadArgumentsV1(const char** argv) {
@@ -146,6 +149,8 @@
return false;
}
+ SetDefaultsForPostV1Arguments();
+
size_t param_index = 0;
for (;; ++param_index) {
const char* param = argv[3 + param_index];
@@ -193,8 +198,9 @@
constexpr int OLD_DEXOPT_BOOTCOMPLETE = 1 << 4;
constexpr int OLD_DEXOPT_PROFILE_GUIDED = 1 << 5;
constexpr int OLD_DEXOPT_OTA = 1 << 6;
+ static_assert(DEXOPT_GENERATE_COMPACT_DEX > OLD_DEXOPT_OTA, "must not overlap");
int input = atoi(param);
- dexopt_flags =
+ dexopt_flags |=
ReplaceMask(input, OLD_DEXOPT_PUBLIC, DEXOPT_PUBLIC) |
ReplaceMask(input, OLD_DEXOPT_DEBUGGABLE, DEXOPT_DEBUGGABLE) |
ReplaceMask(input, OLD_DEXOPT_BOOTCOMPLETE, DEXOPT_BOOTCOMPLETE) |
@@ -226,8 +232,6 @@
return false;
}
- SetDefaultsForPostV1Arguments();
-
return true;
}
@@ -239,7 +243,9 @@
case 4: num_args_expected = 13; break;
case 5: num_args_expected = 14; break;
case 6: num_args_expected = 15; break;
- case 7: num_args_expected = 16; break;
+ case 7:
+ // Version 8 adds a new dexopt flag: DEXOPT_GENERATE_COMPACT_DEX
+ case 8: num_args_expected = 16; break;
default:
LOG(ERROR) << "Don't know how to read arguments for version " << version;
return false;
@@ -302,6 +308,10 @@
case 6:
dexopt_flags = atoi(param);
+ // Add CompactDex generation flag for versions less than 8 since it wasn't passed
+ // from the package manager. Only conditionally set the flag here so that it can
+ // be fully controlled by the package manager.
+ dexopt_flags |= (version < 8) ? DEXOPT_GENERATE_COMPACT_DEX : 0u;
break;
case 7:
diff --git a/cmds/installd/tests/installd_otapreopt_test.cpp b/cmds/installd/tests/installd_otapreopt_test.cpp
index 82bf932..63426cb 100644
--- a/cmds/installd/tests/installd_otapreopt_test.cpp
+++ b/cmds/installd/tests/installd_otapreopt_test.cpp
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
#include <gtest/gtest.h>
+#include "installd_constants.h"
#include "otapreopt_parameters.h"
namespace android {
@@ -61,7 +62,7 @@
ASSERT_STREQ(params.instruction_set, args[i++]);
ASSERT_EQ(params.dexopt_needed, atoi(args[i++]));
ASSERT_STREQ(params.oat_dir, args[i++]);
- ASSERT_EQ(params.dexopt_flags, atoi(args[i++]));
+ const int dexopt_flags = atoi(args[i++]);
ASSERT_STREQ(params.compiler_filter, args[i++]);
ASSERT_STREQ(params.volume_uuid, ParseNull(args[i++]));
ASSERT_STREQ(params.shared_libraries, ParseNull(args[i++]));
@@ -78,7 +79,7 @@
if (version > 3) {
ASSERT_EQ(params.target_sdk_version, atoi(args[i++]));
} else {
- ASSERT_EQ(params.target_sdk_version, 0);
+ ASSERT_EQ(params.target_sdk_version, 0);
}
if (version > 4) {
ASSERT_STREQ(params.profile_name, ParseNull(args[i++]));
@@ -95,6 +96,11 @@
} else {
ASSERT_STREQ(params.compilation_reason, "ab-ota");
}
+ if (version > 7) {
+ ASSERT_EQ(params.dexopt_flags, dexopt_flags);
+ } else {
+ ASSERT_EQ(params.dexopt_flags, dexopt_flags | DEXOPT_GENERATE_COMPACT_DEX);
+ }
}
const char* getVersionCStr(uint32_t version) {
@@ -106,6 +112,7 @@
case 5: return "5";
case 6: return "6";
case 7: return "7";
+ case 8: return "8";
}
return nullptr;
}
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index b9e0139..39fddc5 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -280,7 +280,8 @@
"The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
"the library and successfully fetched the passthrough implementation.");
mImplementationsTable.setDescription(
- "All available passthrough implementations (all -impl.so files)");
+ "All available passthrough implementations (all -impl.so files).\n"
+ "These may return subclasses through their respective HIDL_FETCH_I* functions.");
}
static inline bool findAndBumpVersion(vintf::ManifestHal* hal, const vintf::Version& version) {
@@ -394,11 +395,11 @@
interfaces[interfaceName].instances.insert(instanceName);
}
if (!manifest.add(vintf::ManifestHal{
- .format = vintf::HalFormat::HIDL,
- .name = fqName.package(),
- .versions = {version},
- .transportArch = {transport, arch},
- .interfaces = interfaces})) {
+ vintf::HalFormat::HIDL,
+ std::string{fqName.package()},
+ {version},
+ {transport, arch},
+ std::move(interfaces)})) {
err() << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
}
}
diff --git a/data/etc/wearable_core_hardware.xml b/data/etc/wearable_core_hardware.xml
index d7c3730..e2ab71a 100644
--- a/data/etc/wearable_core_hardware.xml
+++ b/data/etc/wearable_core_hardware.xml
@@ -36,9 +36,6 @@
<!-- basic system services -->
<feature name="android.software.home_screen" />
- <!-- device administration -->
- <feature name="android.software.device_admin" />
-
<!-- input management and third-party input method editors -->
<feature name="android.software.input_methods" />
diff --git a/headers/media_plugin/media/openmax/OMX_IndexExt.h b/headers/media_plugin/media/openmax/OMX_IndexExt.h
index 5a029d0..c2bf97e 100644
--- a/headers/media_plugin/media/openmax/OMX_IndexExt.h
+++ b/headers/media_plugin/media/openmax/OMX_IndexExt.h
@@ -85,6 +85,7 @@
OMX_IndexParamMaxFrameDurationForBitrateControl,/**< reference: OMX_PARAM_U32TYPE */
OMX_IndexParamVideoVp9, /**< reference: OMX_VIDEO_PARAM_VP9TYPE */
OMX_IndexParamVideoAndroidVp9Encoder, /**< reference: OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE */
+ OMX_IndexParamVideoAndroidImageGrid, /**< reference: OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE */
OMX_IndexExtVideoEndUnused,
/* Image & Video common configurations */
diff --git a/headers/media_plugin/media/openmax/OMX_Video.h b/headers/media_plugin/media/openmax/OMX_Video.h
index dc5cdab..9fd2fd2 100644
--- a/headers/media_plugin/media/openmax/OMX_Video.h
+++ b/headers/media_plugin/media/openmax/OMX_Video.h
@@ -89,6 +89,7 @@
OMX_VIDEO_CodingVP9, /**< Google VP9 */
OMX_VIDEO_CodingHEVC, /**< ITU H.265/HEVC */
OMX_VIDEO_CodingDolbyVision,/**< Dolby Vision */
+ OMX_VIDEO_CodingImageHEIC, /**< HEIF image encoded with HEVC */
OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_VIDEO_CodingMax = 0x7FFFFFFF
diff --git a/headers/media_plugin/media/openmax/OMX_VideoExt.h b/headers/media_plugin/media/openmax/OMX_VideoExt.h
index c102564..4b90765 100644
--- a/headers/media_plugin/media/openmax/OMX_VideoExt.h
+++ b/headers/media_plugin/media/openmax/OMX_VideoExt.h
@@ -213,6 +213,7 @@
OMX_VIDEO_HEVCProfileUnknown = 0x0,
OMX_VIDEO_HEVCProfileMain = 0x1,
OMX_VIDEO_HEVCProfileMain10 = 0x2,
+ OMX_VIDEO_HEVCProfileMainStill = 0x4,
// Main10 profile with HDR SEI support.
OMX_VIDEO_HEVCProfileMain10HDR10 = 0x1000,
OMX_VIDEO_HEVCProfileMax = 0x7FFFFFFF
@@ -421,6 +422,48 @@
OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
} OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE;
+/**
+ * Android specific param for specifying image grid layout information for image encoding
+ * use cases, corresponding to index OMX_IndexParamVideoAndroidImageGrid.
+ *
+ * OMX_VIDEO_CodingImageHEIC encoders must handle this param type. When this param is set
+ * on the component with bEnabled set to true, nGrid* indicates the desired grid config
+ * by the client. The component can use this as a heuristic, but is free to choose any
+ * suitable grid configs, and the client shall always get the actual from the component
+ * after the param is set. Encoder will receive each input image in full, and shall encode
+ * it into tiles in row-major, top-row first, left-to-right order, and send each encoded
+ * tile in a separate output buffer. All output buffers for the same input buffer shall
+ * carry the same timestamp as the input buffer. If the input buffer is marked EOS,
+ * the EOS should only appear on the last output buffer for that input buffer.
+ *
+ * OMX_VIDEO_CodingHEVC encoders might also receive this param when it's used for image
+ * encoding, although in this case the param only serves as a hint. The encoder will
+ * receive the input image tiles in row-major, top-row first, left-to-right order.
+ * The grid config can be used for quality control, or optimizations.
+ *
+ * If this param is not set, the component shall assume that grid option is disabled.
+ *
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to (output port for encoders)
+ * bEnabled : Whether grid is enabled. If true, nGrid* specifies the grid
+ * config; otherwise nGrid* shall be ignored.
+ * nGridWidth : Width of each tile.
+ * nGridHeight : Height of each tile.
+ * nGridRows : Number of rows in the grid.
+ * nGridCols : Number of cols in the grid.
+ */
+typedef struct OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnabled;
+ OMX_U32 nGridWidth;
+ OMX_U32 nGridHeight;
+ OMX_U32 nGridRows;
+ OMX_U32 nGridCols;
+} OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE;
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libs/dumputils/Android.bp b/libs/dumputils/Android.bp
new file mode 100644
index 0000000..3412e14
--- /dev/null
+++ b/libs/dumputils/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library {
+ name: "libdumputils",
+
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libutils",
+ ],
+
+ srcs: ["dump_utils.cpp"],
+
+ cflags: ["-Wall", "-Werror"],
+
+ export_include_dirs: [
+ "include",
+ ],
+}
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
new file mode 100644
index 0000000..0fd2b81
--- /dev/null
+++ b/libs/dumputils/dump_utils.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <set>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <dumputils/dump_utils.h>
+#include <log/log.h>
+
+/* list of native processes to include in the native dumps */
+// This matches the /proc/pid/exe link instead of /proc/pid/cmdline.
+static const char* native_processes_to_dump[] = {
+ "/system/bin/audioserver",
+ "/system/bin/cameraserver",
+ "/system/bin/drmserver",
+ "/system/bin/mediadrmserver",
+ "/system/bin/mediaextractor", // media.extractor
+ "/system/bin/mediametrics", // media.metrics
+ "/system/bin/mediaserver",
+ "/system/bin/sdcard",
+ "/system/bin/statsd",
+ "/system/bin/surfaceflinger",
+ "/system/bin/vehicle_network_service",
+ "/vendor/bin/hw/android.hardware.media.omx@1.0-service", // media.codec
+ NULL,
+};
+
+/* list of hal interface to dump containing process during native dumps */
+static const char* hal_interfaces_to_dump[] {
+ "android.hardware.audio@2.0::IDevicesFactory",
+ "android.hardware.bluetooth@1.0::IBluetoothHci",
+ "android.hardware.camera.provider@2.4::ICameraProvider",
+ "android.hardware.graphics.composer@2.1::IComposer",
+ "android.hardware.media.omx@1.0::IOmx",
+ "android.hardware.sensors@1.0::ISensors",
+ "android.hardware.vr@1.0::IVr",
+ NULL,
+};
+
+bool should_dump_hal_interface(const char* interface) {
+ for (const char** i = hal_interfaces_to_dump; *i; i++) {
+ if (!strcmp(*i, interface)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool should_dump_native_traces(const char* path) {
+ for (const char** p = native_processes_to_dump; *p; p++) {
+ if (!strcmp(*p, path)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::set<int> get_interesting_hal_pids() {
+ using android::hidl::manager::V1_0::IServiceManager;
+ using android::sp;
+ using android::hardware::Return;
+
+ sp<IServiceManager> manager = IServiceManager::getService();
+ std::set<int> pids;
+
+ Return<void> ret = manager->debugDump([&](auto& hals) {
+ for (const auto &info : hals) {
+ if (info.pid == static_cast<int>(IServiceManager::PidConstant::NO_PID)) {
+ continue;
+ }
+
+ if (!should_dump_hal_interface(info.interfaceName.c_str())) {
+ continue;
+ }
+
+ pids.insert(info.pid);
+ }
+ });
+
+ if (!ret.isOk()) {
+ ALOGE("Could not get list of HAL PIDs: %s\n", ret.description().c_str());
+ }
+
+ return pids; // whether it was okay or not
+}
+
+bool IsZygote(int pid) {
+ static const std::string kZygotePrefix = "zygote";
+
+ std::string cmdline;
+ if (!android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/cmdline", pid),
+ &cmdline)) {
+ return true;
+ }
+
+ return (cmdline.find(kZygotePrefix) == 0);
+}
diff --git a/libs/dumputils/include/dumputils/dump_utils.h b/libs/dumputils/include/dumputils/dump_utils.h
new file mode 100644
index 0000000..25f7127
--- /dev/null
+++ b/libs/dumputils/include/dumputils/dump_utils.h
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DUMPUTILS_H_
+#define DUMPUTILS_H_
+
+#include <set>
+
+bool should_dump_native_traces(const char* path);
+
+std::set<int> get_interesting_hal_pids();
+
+bool IsZygote(int pid);
+
+#endif // DUMPUTILS_H_
diff --git a/libs/gui/HdrMetadata.cpp b/libs/gui/HdrMetadata.cpp
index 299bdfa..b715e43 100644
--- a/libs/gui/HdrMetadata.cpp
+++ b/libs/gui/HdrMetadata.cpp
@@ -66,4 +66,32 @@
return NO_ERROR;
}
+bool HdrMetadata::operator==(const HdrMetadata& rhs) const {
+ if (validTypes != rhs.validTypes) return false;
+
+ if ((validTypes & SMPTE2086) == SMPTE2086) {
+ if (smpte2086.displayPrimaryRed.x != rhs.smpte2086.displayPrimaryRed.x ||
+ smpte2086.displayPrimaryRed.y != rhs.smpte2086.displayPrimaryRed.y ||
+ smpte2086.displayPrimaryGreen.x != rhs.smpte2086.displayPrimaryGreen.x ||
+ smpte2086.displayPrimaryGreen.y != rhs.smpte2086.displayPrimaryGreen.y ||
+ smpte2086.displayPrimaryBlue.x != rhs.smpte2086.displayPrimaryBlue.x ||
+ smpte2086.displayPrimaryBlue.y != rhs.smpte2086.displayPrimaryBlue.y ||
+ smpte2086.whitePoint.x != rhs.smpte2086.whitePoint.x ||
+ smpte2086.whitePoint.y != rhs.smpte2086.whitePoint.y ||
+ smpte2086.maxLuminance != rhs.smpte2086.maxLuminance ||
+ smpte2086.minLuminance != rhs.smpte2086.minLuminance) {
+ return false;
+ }
+ }
+
+ if ((validTypes & CTA861_3) == CTA861_3) {
+ if (cta8613.maxFrameAverageLightLevel != rhs.cta8613.maxFrameAverageLightLevel ||
+ cta8613.maxContentLightLevel != rhs.cta8613.maxContentLightLevel) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // namespace android
diff --git a/libs/gui/include/gui/HdrMetadata.h b/libs/gui/include/gui/HdrMetadata.h
index cd01952..9800602 100644
--- a/libs/gui/include/gui/HdrMetadata.h
+++ b/libs/gui/include/gui/HdrMetadata.h
@@ -38,6 +38,8 @@
size_t getFlattenedSize() const;
status_t flatten(void* buffer, size_t size) const;
status_t unflatten(void const* buffer, size_t size);
+
+ bool operator==(const HdrMetadata& rhs) const;
};
} // namespace android
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index e0d2113..c07a812 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -1090,7 +1090,7 @@
static float calculateImpulseVelocity(const nsecs_t* t, const float* x, size_t count) {
// The input should be in reversed time order (most recent sample at index i=0)
// t[i] is in nanoseconds, but due to FP arithmetic, convert to seconds inside this function
- static constexpr float NANOS_PER_SECOND = 1E-9;
+ static constexpr float SECONDS_PER_NANO = 1E-9;
if (count < 2) {
return 0; // if 0 or 1 points, velocity is zero
@@ -1103,7 +1103,7 @@
ALOGE("Events have identical time stamps t=%" PRId64 ", setting velocity = 0", t[0]);
return 0;
}
- return (x[1] - x[0]) / (NANOS_PER_SECOND * (t[1] - t[0]));
+ return (x[1] - x[0]) / (SECONDS_PER_NANO * (t[1] - t[0]));
}
// Guaranteed to have at least 3 points here
float work = 0;
@@ -1113,7 +1113,7 @@
continue;
}
float vprev = kineticEnergyToVelocity(work); // v[i-1]
- float vcurr = (x[i] - x[i-1]) / (NANOS_PER_SECOND * (t[i] - t[i-1])); // v[i]
+ float vcurr = (x[i] - x[i-1]) / (SECONDS_PER_NANO * (t[i] - t[i-1])); // v[i]
work += (vcurr - vprev) * fabsf(vcurr);
if (i == count - 1) {
work *= 0.5; // initial condition, case 2) above
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index a2712b4..f37ef28 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -343,14 +343,6 @@
"HAL and AHardwareBuffer pixel format don't match");
static_assert(HAL_PIXEL_FORMAT_YCBCR_420_888 == AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
"HAL and AHardwareBuffer pixel format don't match");
- static_assert(HAL_PIXEL_FORMAT_YCBCR_422_888 == AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_422,
- "HAL and AHardwareBuffer pixel format don't match");
- static_assert(HAL_PIXEL_FORMAT_YCBCR_444_888 == AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_444,
- "HAL and AHardwareBuffer pixel format don't match");
- static_assert(HAL_PIXEL_FORMAT_FLEX_RGB_888 == AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8,
- "HAL and AHardwareBuffer pixel format don't match");
- static_assert(HAL_PIXEL_FORMAT_FLEX_RGBA_8888 == AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8A8,
- "HAL and AHardwareBuffer pixel format don't match");
static_assert(HAL_PIXEL_FORMAT_YCBCR_422_SP == AHARDWAREBUFFER_FORMAT_YCbCr_422_SP,
"HAL and AHardwareBuffer pixel format don't match");
static_assert(HAL_PIXEL_FORMAT_YCRCB_420_SP == AHARDWAREBUFFER_FORMAT_YCrCb_420_SP,
@@ -383,10 +375,6 @@
case AHARDWAREBUFFER_FORMAT_RAW_OPAQUE:
case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
- case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_422:
- case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_444:
- case AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8:
- case AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8A8:
case AHARDWAREBUFFER_FORMAT_YCbCr_422_SP:
case AHARDWAREBUFFER_FORMAT_YCrCb_420_SP:
case AHARDWAREBUFFER_FORMAT_YCbCr_422_I:
diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h
index 802edcc..7a4b31f 100644
--- a/libs/nativewindow/include/vndk/hardware_buffer.h
+++ b/libs/nativewindow/include/vndk/hardware_buffer.h
@@ -53,14 +53,6 @@
AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED = 0x22,
/* same as HAL_PIXEL_FORMAT_YCBCR_420_888 */
AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23,
- /* same as HAL_PIXEL_FORMAT_YCBCR_422_888 */
- AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_422 = 0x27,
- /* same as HAL_PIXEL_FORMAT_YCBCR_444_888 */
- AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_444 = 0x28,
- /* same as HAL_PIXEL_FORMAT_FLEX_RGB_888 */
- AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8 = 0x29,
- /* same as HAL_PIXEL_FORMAT_FLEX_RGBA_8888 */
- AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8A8 = 0x2A,
/* same as HAL_PIXEL_FORMAT_YCBCR_422_SP */
AHARDWAREBUFFER_FORMAT_YCbCr_422_SP = 0x10,
/* same as HAL_PIXEL_FORMAT_YCRCB_420_SP */
diff --git a/libs/sensor/OWNERS b/libs/sensor/OWNERS
index 6a38a1f..d4393d6 100644
--- a/libs/sensor/OWNERS
+++ b/libs/sensor/OWNERS
@@ -1,2 +1,2 @@
-ashutoshj@google.com
-pengxu@google.com
+arthuri@google.com
+bduddie@google.com
diff --git a/libs/vr/libbufferhub/buffer_hub_client.cpp b/libs/vr/libbufferhub/buffer_hub_client.cpp
index 8fe9dfb..6db09a9 100644
--- a/libs/vr/libbufferhub/buffer_hub_client.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_client.cpp
@@ -395,25 +395,16 @@
}
BufferProducer::BufferProducer(uint32_t width, uint32_t height, uint32_t format,
- uint32_t usage, size_t user_metadata_size)
- : BufferProducer(width, height, format, usage, usage, user_metadata_size) {}
-
-BufferProducer::BufferProducer(uint32_t width, uint32_t height, uint32_t format,
- uint64_t producer_usage, uint64_t consumer_usage,
- size_t user_metadata_size)
+ uint64_t usage, size_t user_metadata_size)
: BASE(BufferHubRPC::kClientPath) {
ATRACE_NAME("BufferProducer::BufferProducer");
ALOGD_IF(TRACE,
"BufferProducer::BufferProducer: fd=%d width=%u height=%u format=%u "
- "producer_usage=%" PRIx64 " consumer_usage=%" PRIx64
- " user_metadata_size=%zu",
- event_fd(), width, height, format, producer_usage, consumer_usage,
- user_metadata_size);
+ "usage=%" PRIx64 " user_metadata_size=%zu",
+ event_fd(), width, height, format, usage, user_metadata_size);
- // (b/37881101) Deprecate producer/consumer usage
auto status = InvokeRemoteMethod<BufferHubRPC::CreateBuffer>(
- width, height, format, (producer_usage | consumer_usage),
- user_metadata_size);
+ width, height, format, usage, user_metadata_size);
if (!status) {
ALOGE(
"BufferProducer::BufferProducer: Failed to create producer buffer: %s",
@@ -431,26 +422,18 @@
}
}
-BufferProducer::BufferProducer(uint32_t usage, size_t size)
- : BufferProducer(usage, usage, size) {}
-
-BufferProducer::BufferProducer(uint64_t producer_usage, uint64_t consumer_usage,
- size_t size)
+BufferProducer::BufferProducer(uint64_t usage, size_t size)
: BASE(BufferHubRPC::kClientPath) {
ATRACE_NAME("BufferProducer::BufferProducer");
- ALOGD_IF(TRACE,
- "BufferProducer::BufferProducer: producer_usage=%" PRIx64
- " consumer_usage=%" PRIx64 " size=%zu",
- producer_usage, consumer_usage, size);
+ ALOGD_IF(TRACE, "BufferProducer::BufferProducer: usage=%" PRIx64 " size=%zu",
+ usage, size);
const int width = static_cast<int>(size);
const int height = 1;
const int format = HAL_PIXEL_FORMAT_BLOB;
const size_t user_metadata_size = 0;
- // (b/37881101) Deprecate producer/consumer usage
auto status = InvokeRemoteMethod<BufferHubRPC::CreateBuffer>(
- width, height, format, (producer_usage | consumer_usage),
- user_metadata_size);
+ width, height, format, usage, user_metadata_size);
if (!status) {
ALOGE("BufferProducer::BufferProducer: Failed to create blob: %s",
status.GetErrorMessage().c_str());
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
index 8a4440f..c791250 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
@@ -111,10 +111,6 @@
uint32_t usage() const { return buffer_.usage(); }
uint32_t layer_count() const { return buffer_.layer_count(); }
- // TODO(b/37881101) Clean up producer/consumer usage.
- uint64_t producer_usage() const { return buffer_.usage(); }
- uint64_t consumer_usage() const { return buffer_.usage(); }
-
uint64_t GetQueueIndex() const { return metadata_header_->queue_index; }
void SetQueueIndex(uint64_t index) { metadata_header_->queue_index = index; }
@@ -230,14 +226,10 @@
// Constructs a buffer with the given geometry and parameters.
BufferProducer(uint32_t width, uint32_t height, uint32_t format,
- uint32_t usage, size_t metadata_size = 0);
- BufferProducer(uint32_t width, uint32_t height, uint32_t format,
- uint64_t producer_usage, uint64_t consumer_usage,
- size_t metadata_size);
+ uint64_t usage, size_t metadata_size = 0);
// Constructs a blob (flat) buffer with the given usage flags.
- BufferProducer(uint32_t usage, size_t size);
- BufferProducer(uint64_t producer_usage, uint64_t consumer_usage, size_t size);
+ BufferProducer(uint64_t usage, size_t size);
// Imports the given file handle to a producer channel, taking ownership.
explicit BufferProducer(LocalChannelHandle channel);
diff --git a/libs/vr/libbufferhub/include/private/dvr/native_buffer.h b/libs/vr/libbufferhub/include/private/dvr/native_buffer.h
deleted file mode 100644
index 140ffc5..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/native_buffer.h
+++ /dev/null
@@ -1,179 +0,0 @@
-#ifndef ANDROID_DVR_NATIVE_BUFFER_H_
-#define ANDROID_DVR_NATIVE_BUFFER_H_
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <log/log.h>
-#include <ui/ANativeObjectBase.h>
-#include <utils/RefBase.h>
-#include <nativebase/nativebase.h>
-
-#include <private/dvr/buffer_hub_client.h>
-
-namespace android {
-namespace dvr {
-
-// ANativeWindowBuffer is the abstraction Android HALs and frameworks use to
-// pass around hardware graphics buffers. The following classes implement this
-// abstraction with different DVR backing buffers, all of which provide
-// different semantics on top of ion/gralloc buffers.
-
-// An implementation of ANativeWindowBuffer backed by an IonBuffer.
-class NativeBuffer
- : public android::ANativeObjectBase<ANativeWindowBuffer, NativeBuffer,
- android::LightRefBase<NativeBuffer>> {
- public:
- static constexpr int kEmptyFence = -1;
-
- explicit NativeBuffer(const std::shared_ptr<IonBuffer>& buffer)
- : BASE(), buffer_(buffer), fence_(kEmptyFence) {
- ANativeWindowBuffer::width = buffer->width();
- ANativeWindowBuffer::height = buffer->height();
- ANativeWindowBuffer::stride = buffer->stride();
- ANativeWindowBuffer::format = buffer->format();
- ANativeWindowBuffer::usage = buffer->usage();
- handle = buffer_->handle();
- }
-
- virtual ~NativeBuffer() {}
-
- std::shared_ptr<IonBuffer> buffer() { return buffer_; }
- int fence() const { return fence_.Get(); }
-
- void SetFence(int fence) { fence_.Reset(fence); }
-
- private:
- friend class android::LightRefBase<NativeBuffer>;
-
- std::shared_ptr<IonBuffer> buffer_;
- pdx::LocalHandle fence_;
-
- NativeBuffer(const NativeBuffer&) = delete;
- void operator=(NativeBuffer&) = delete;
-};
-
-class NativeBufferProducer : public android::ANativeObjectBase<
- ANativeWindowBuffer, NativeBufferProducer,
- android::LightRefBase<NativeBufferProducer>> {
- public:
- static constexpr int kEmptyFence = -1;
-
- NativeBufferProducer(const std::shared_ptr<BufferProducer>& buffer,
- EGLDisplay display, uint32_t surface_buffer_index)
- : BASE(),
- buffer_(buffer),
- surface_buffer_index_(surface_buffer_index),
- display_(display) {
- ANativeWindowBuffer::width = buffer_->width();
- ANativeWindowBuffer::height = buffer_->height();
- ANativeWindowBuffer::stride = buffer_->stride();
- ANativeWindowBuffer::format = buffer_->format();
- ANativeWindowBuffer::usage = buffer_->usage();
- ANativeWindowBuffer::handle = buffer_->native_handle();
- if (display_) {
- image_khr_ =
- eglCreateImageKHR(display_, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
- static_cast<ANativeWindowBuffer*>(this), nullptr);
- } else {
- image_khr_ = EGL_NO_IMAGE_KHR;
- }
- }
-
- explicit NativeBufferProducer(const std::shared_ptr<BufferProducer>& buffer)
- : NativeBufferProducer(buffer, nullptr, 0) {}
-
- virtual ~NativeBufferProducer() {
- if (image_khr_ != EGL_NO_IMAGE_KHR)
- eglDestroyImageKHR(display_, image_khr_);
- }
-
- EGLImageKHR image_khr() const { return image_khr_; }
- std::shared_ptr<BufferProducer> buffer() const { return buffer_; }
- int release_fence() const { return release_fence_.Get(); }
- uint32_t surface_buffer_index() const { return surface_buffer_index_; }
-
- // Return the release fence, passing ownership to the caller.
- pdx::LocalHandle ClaimReleaseFence() { return std::move(release_fence_); }
-
- // Post the buffer consumer, closing the acquire and release fences.
- int Post(int acquire_fence, uint64_t sequence) {
- release_fence_.Close();
- return buffer_->Post(pdx::LocalHandle(acquire_fence), sequence);
- }
-
- // Gain the buffer producer, closing the previous release fence if valid.
- int Gain() { return buffer_->Gain(&release_fence_); }
-
- // Asynchronously gain the buffer, closing the previous release fence.
- int GainAsync() {
- release_fence_.Close();
- return buffer_->GainAsync();
- }
-
- private:
- friend class android::LightRefBase<NativeBufferProducer>;
-
- std::shared_ptr<BufferProducer> buffer_;
- pdx::LocalHandle release_fence_;
- EGLImageKHR image_khr_;
- uint32_t surface_buffer_index_;
- EGLDisplay display_;
-
- NativeBufferProducer(const NativeBufferProducer&) = delete;
- void operator=(NativeBufferProducer&) = delete;
-};
-
-// NativeBufferConsumer is an implementation of ANativeWindowBuffer backed by a
-// BufferConsumer.
-class NativeBufferConsumer : public android::ANativeObjectBase<
- ANativeWindowBuffer, NativeBufferConsumer,
- android::LightRefBase<NativeBufferConsumer>> {
- public:
- static constexpr int kEmptyFence = -1;
-
- explicit NativeBufferConsumer(const std::shared_ptr<BufferConsumer>& buffer)
- : BASE(), buffer_(buffer), acquire_fence_(kEmptyFence), sequence_(0) {
- ANativeWindowBuffer::width = buffer_->width();
- ANativeWindowBuffer::height = buffer_->height();
- ANativeWindowBuffer::stride = buffer_->stride();
- ANativeWindowBuffer::format = buffer_->format();
- ANativeWindowBuffer::usage = buffer_->usage();
- handle = buffer_->native_handle();
- }
-
- virtual ~NativeBufferConsumer() {}
-
- std::shared_ptr<BufferConsumer> buffer() const { return buffer_; }
- int acquire_fence() const { return acquire_fence_.Get(); }
- uint64_t sequence() const { return sequence_; }
-
- // Return the acquire fence, passing ownership to the caller.
- pdx::LocalHandle ClaimAcquireFence() { return std::move(acquire_fence_); }
-
- // Acquire the underlying buffer consumer, closing the previous acquire fence
- // if valid.
- int Acquire() { return buffer_->Acquire(&acquire_fence_, &sequence_); }
-
- // Release the buffer consumer, closing the acquire and release fences if
- // valid.
- int Release(int release_fence) {
- acquire_fence_.Close();
- sequence_ = 0;
- return buffer_->Release(pdx::LocalHandle(release_fence));
- }
-
- private:
- friend class android::LightRefBase<NativeBufferConsumer>;
-
- std::shared_ptr<BufferConsumer> buffer_;
- pdx::LocalHandle acquire_fence_;
- uint64_t sequence_;
-
- NativeBufferConsumer(const NativeBufferConsumer&) = delete;
- void operator=(NativeBufferConsumer&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_NATIVE_BUFFER_H_
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
index 442c82d..f67e258 100644
--- a/libs/vr/libdisplay/display_client.cpp
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -9,7 +9,6 @@
#include <mutex>
#include <private/dvr/display_protocol.h>
-#include <private/dvr/native_buffer.h>
using android::pdx::ErrorStatus;
using android::pdx::LocalHandle;
diff --git a/libs/vr/libdvr/tests/dvr_api_test.h b/libs/vr/libdvr/tests/dvr_api_test.h
index 648af75..d8359e7 100644
--- a/libs/vr/libdvr/tests/dvr_api_test.h
+++ b/libs/vr/libdvr/tests/dvr_api_test.h
@@ -3,8 +3,6 @@
#include <gtest/gtest.h>
-#define ASSERT_NOT_NULL(x) ASSERT_TRUE((x) != nullptr)
-
/** DvrTestBase loads the libdvr.so at runtime and get the Dvr API version 1. */
class DvrApiTest : public ::testing::Test {
protected:
@@ -17,11 +15,11 @@
// https://github.com/android-ndk/ndk/issues/360
flags |= RTLD_NODELETE;
platform_handle_ = dlopen("libdvr.so", flags);
- ASSERT_NOT_NULL(platform_handle_) << "Dvr shared library missing.";
+ ASSERT_NE(nullptr, platform_handle_) << "Dvr shared library missing.";
auto dvr_get_api = reinterpret_cast<decltype(&dvrGetApi)>(
dlsym(platform_handle_, "dvrGetApi"));
- ASSERT_NOT_NULL(dvr_get_api) << "Platform library missing dvrGetApi.";
+ ASSERT_NE(nullptr, dvr_get_api) << "Platform library missing dvrGetApi.";
ASSERT_EQ(dvr_get_api(&api_, sizeof(api_), /*version=*/1), 0)
<< "Unable to find compatible Dvr API.";
diff --git a/libs/vr/libdvr/tests/dvr_display-test.cpp b/libs/vr/libdvr/tests/dvr_display-test.cpp
index 1165573..c72f940 100644
--- a/libs/vr/libdvr/tests/dvr_display-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_display-test.cpp
@@ -16,20 +16,58 @@
class DvrDisplayTest : public DvrApiTest {
protected:
+ void SetUp() override {
+ DvrApiTest::SetUp();
+ int ret = api_.GetNativeDisplayMetrics(sizeof(display_metrics_),
+ &display_metrics_);
+ ASSERT_EQ(ret, 0) << "Failed to get display metrics.";
+ ALOGD(
+ "display_width: %d, display_height: %d, display_x_dpi: %d, "
+ "display_y_dpi: %d, vsync_period_ns: %d.",
+ display_metrics_.display_width, display_metrics_.display_height,
+ display_metrics_.display_x_dpi, display_metrics_.display_y_dpi,
+ display_metrics_.vsync_period_ns);
+ }
+
void TearDown() override {
if (write_queue_ != nullptr) {
api_.WriteBufferQueueDestroy(write_queue_);
write_queue_ = nullptr;
}
+ if (direct_surface_ != nullptr) {
+ api_.SurfaceDestroy(direct_surface_);
+ direct_surface_ = nullptr;
+ }
DvrApiTest::TearDown();
}
+ /* Convert a write buffer to an android hardware buffer and fill in
+ * color_textures evenly to the buffer.
+ * AssertionError if the width of the buffer is not equal to the input width,
+ * AssertionError if the height of the buffer is not equal to the input
+ * height.
+ */
+ void FillWriteBuffer(DvrWriteBuffer* write_buffer,
+ const std::vector<uint32_t>& color_textures,
+ uint32_t width, uint32_t height);
+
+ // Write buffer queue properties.
+ static constexpr uint64_t kUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
+ AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
+ uint32_t kFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+ static constexpr size_t kMetadataSize = 0;
+ static constexpr int kTimeoutMs = 1000; // Time for getting buffer.
+ uint32_t kLayerCount = 1;
DvrWriteBufferQueue* write_queue_ = nullptr;
+ DvrSurface* direct_surface_ = nullptr;
+
+ // Device display properties.
+ DvrNativeDisplayMetrics display_metrics_;
};
-TEST_F(DvrDisplayTest, DisplaySingleColor) {
- // Create direct surface.
- DvrSurface* direct_surface = nullptr;
+TEST_F(DvrDisplayTest, DisplayWithOneBuffer) {
+ // Create a direct surface.
std::vector<DvrSurfaceAttribute> direct_surface_attributes = {
{.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
@@ -43,73 +81,32 @@
};
int ret =
api_.SurfaceCreate(direct_surface_attributes.data(),
- direct_surface_attributes.size(), &direct_surface);
+ direct_surface_attributes.size(), &direct_surface_);
ASSERT_EQ(ret, 0) << "Failed to create direct surface.";
- // Get screen dimension.
- DvrNativeDisplayMetrics display_metrics;
- ret = api_.GetNativeDisplayMetrics(sizeof(display_metrics), &display_metrics);
- ASSERT_EQ(ret, 0) << "Failed to get display metrics.";
- ALOGD(
- "display_width: %d, display_height: %d, display_x_dpi: %d, "
- "display_y_dpi: %d, vsync_period_ns: %d.",
- display_metrics.display_width, display_metrics.display_height,
- display_metrics.display_x_dpi, display_metrics.display_y_dpi,
- display_metrics.vsync_period_ns);
-
// Create a buffer queue with the direct surface.
- constexpr uint32_t kLayerCount = 1;
- constexpr uint64_t kUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
- AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
- AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
- constexpr uint32_t kFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
constexpr size_t kCapacity = 1;
- constexpr size_t kMetadataSize = 0;
- uint32_t width = display_metrics.display_width;
- uint32_t height = display_metrics.display_height;
+ uint32_t width = display_metrics_.display_width;
+ uint32_t height = display_metrics_.display_height;
ret = api_.SurfaceCreateWriteBufferQueue(
- direct_surface, width, height, kFormat, kLayerCount, kUsage, kCapacity,
+ direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity,
kMetadataSize, &write_queue_);
EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
- ASSERT_NOT_NULL(write_queue_) << "Write buffer queue should not be null.";
+ ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null.";
// Get buffer from WriteBufferQueue.
DvrWriteBuffer* write_buffer = nullptr;
- constexpr int kTimeoutMs = 1000;
DvrNativeBufferMetadata out_meta;
int out_fence_fd = -1;
ret = api_.WriteBufferQueueGainBuffer(write_queue_, kTimeoutMs, &write_buffer,
&out_meta, &out_fence_fd);
EXPECT_EQ(0, ret) << "Failed to get the buffer.";
- ASSERT_NOT_NULL(write_buffer) << "Gained buffer should not be null.";
+ ASSERT_NE(nullptr, write_buffer) << "Gained buffer should not be null.";
- // Convert to an android hardware buffer.
- AHardwareBuffer* ah_buffer{nullptr};
- ret = api_.WriteBufferGetAHardwareBuffer(write_buffer, &ah_buffer);
- EXPECT_EQ(0, ret) << "Failed to get a hardware buffer from the write buffer.";
- ASSERT_NOT_NULL(ah_buffer) << "AHardware buffer should not be null.";
-
- // Change the content of the android hardware buffer.
- void* buffer_data{nullptr};
- int32_t fence = -1;
- ret = AHardwareBuffer_lock(ah_buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
- fence, nullptr, &buffer_data);
- EXPECT_EQ(0, ret) << "Failed to lock the hardware buffer.";
- ASSERT_NOT_NULL(buffer_data) << "Buffer data should not be null.";
-
- uint32_t color_texture = 0xff0000ff; // Red color in RGBA.
- for (uint32_t i = 0; i < width * height; ++i) {
- memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) +
- i * sizeof(color_texture)),
- &color_texture, sizeof(color_texture));
- }
-
- fence = -1;
- ret = AHardwareBuffer_unlock(ah_buffer, &fence);
- EXPECT_EQ(0, ret) << "Failed to unlock the hardware buffer.";
-
- // Release the android hardware buffer.
- AHardwareBuffer_release(ah_buffer);
+ // Color the write buffer.
+ FillWriteBuffer(write_buffer,
+ {0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
+ width, height);
// Post buffer.
int ready_fence_fd = -1;
@@ -118,4 +115,237 @@
EXPECT_EQ(0, ret) << "Failed to post the buffer.";
sleep(5); // For visual check on the device under test.
+ // Should observe three primary colors on the screen center.
+}
+
+TEST_F(DvrDisplayTest, DisplayWithDoubleBuffering) {
+ // Create a direct surface.
+ std::vector<DvrSurfaceAttribute> direct_surface_attributes = {
+ {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
+ .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
+ .value.bool_value = true},
+ {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
+ .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
+ .value.int32_value = 10},
+ {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
+ .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
+ .value.bool_value = true},
+ };
+ int ret =
+ api_.SurfaceCreate(direct_surface_attributes.data(),
+ direct_surface_attributes.size(), &direct_surface_);
+ ASSERT_EQ(ret, 0) << "Failed to create direct surface.";
+
+ // Create a buffer queue with the direct surface.
+ constexpr size_t kCapacity = 2;
+ uint32_t width = display_metrics_.display_width;
+ uint32_t height = display_metrics_.display_height;
+ ret = api_.SurfaceCreateWriteBufferQueue(
+ direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity,
+ kMetadataSize, &write_queue_);
+ EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
+ ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null.";
+
+ int num_display_cycles_in_5s = 5 / (display_metrics_.vsync_period_ns / 1e9);
+ ALOGD("The number of display cycles: %d", num_display_cycles_in_5s);
+ int bufferhub_id_prev_write_buffer = -1;
+ for (int i = 0; i < num_display_cycles_in_5s; ++i) {
+ // Get a buffer from the WriteBufferQueue.
+ DvrWriteBuffer* write_buffer = nullptr;
+ DvrNativeBufferMetadata out_meta;
+ int out_fence_fd = -1;
+ ret = api_.WriteBufferQueueGainBuffer(
+ write_queue_, kTimeoutMs, &write_buffer, &out_meta, &out_fence_fd);
+ EXPECT_EQ(0, ret) << "Failed to get the a write buffer.";
+ ASSERT_NE(nullptr, write_buffer) << "The gained buffer should not be null.";
+
+ int bufferhub_id = api_.WriteBufferGetId(write_buffer);
+ ALOGD("Display cycle: %d, bufferhub id of the write buffer: %d", i,
+ bufferhub_id);
+ EXPECT_NE(bufferhub_id_prev_write_buffer, bufferhub_id)
+ << "Double buffering should be using the two buffers in turns, not "
+ "reusing the same write buffer.";
+ bufferhub_id_prev_write_buffer = bufferhub_id;
+
+ // Color the write buffer.
+ if (i % 2) {
+ FillWriteBuffer(write_buffer, {0xffff0000, 0xff00ff00, 0xff0000ff}, width,
+ height);
+ } else {
+ FillWriteBuffer(write_buffer, {0xff00ff00, 0xff0000ff, 0xffff0000}, width,
+ height);
+ }
+
+ // Post the write buffer.
+ int ready_fence_fd = -1;
+ ret = api_.WriteBufferQueuePostBuffer(write_queue_, write_buffer, &out_meta,
+ ready_fence_fd);
+ EXPECT_EQ(0, ret) << "Failed to post the buffer.";
+ }
+ // Should observe blinking screen in secondary colors
+ // although it is actually displaying primary colors.
+}
+
+TEST_F(DvrDisplayTest, DisplayWithTwoHardwareLayers) {
+ // Create the direct_surface_0 of z order 10 and direct_surface_1 of z
+ // order 11.
+ DvrSurface* direct_surface_0 = nullptr;
+ std::vector<DvrSurfaceAttribute> direct_surface_0_attributes = {
+ {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
+ .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
+ .value.bool_value = true},
+ {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
+ .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
+ .value.int32_value = 10},
+ {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
+ .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
+ .value.bool_value = true},
+ };
+ int ret =
+ api_.SurfaceCreate(direct_surface_0_attributes.data(),
+ direct_surface_0_attributes.size(), &direct_surface_0);
+ EXPECT_EQ(ret, 0) << "Failed to create direct surface.";
+
+ DvrSurface* direct_surface_1 = nullptr;
+ std::vector<DvrSurfaceAttribute> direct_surface_1_attributes = {
+ {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
+ .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
+ .value.bool_value = true},
+ {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
+ .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
+ .value.int32_value = 11},
+ {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
+ .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
+ .value.bool_value = true},
+ };
+ ret =
+ api_.SurfaceCreate(direct_surface_1_attributes.data(),
+ direct_surface_1_attributes.size(), &direct_surface_1);
+ EXPECT_EQ(ret, 0) << "Failed to create direct surface.";
+
+ // Create a buffer queue for each of the direct surfaces.
+ constexpr size_t kCapacity = 1;
+ uint32_t width = display_metrics_.display_width;
+ uint32_t height = display_metrics_.display_height;
+
+ DvrWriteBufferQueue* write_queue_0 = nullptr;
+ ret = api_.SurfaceCreateWriteBufferQueue(
+ direct_surface_0, width, height, kFormat, kLayerCount, kUsage, kCapacity,
+ kMetadataSize, &write_queue_0);
+ EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
+ EXPECT_NE(nullptr, write_queue_0) << "Write buffer queue should not be null.";
+
+ DvrWriteBufferQueue* write_queue_1 = nullptr;
+ ret = api_.SurfaceCreateWriteBufferQueue(
+ direct_surface_1, width, height, kFormat, kLayerCount, kUsage, kCapacity,
+ kMetadataSize, &write_queue_1);
+ EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
+ EXPECT_NE(nullptr, write_queue_1) << "Write buffer queue should not be null.";
+
+ // Get a buffer from each of the write buffer queues.
+ DvrWriteBuffer* write_buffer_0 = nullptr;
+ DvrNativeBufferMetadata out_meta_0;
+ int out_fence_fd = -1;
+ ret = api_.WriteBufferQueueGainBuffer(
+ write_queue_0, kTimeoutMs, &write_buffer_0, &out_meta_0, &out_fence_fd);
+ EXPECT_EQ(0, ret) << "Failed to get the buffer.";
+ EXPECT_NE(nullptr, write_buffer_0) << "Gained buffer should not be null.";
+
+ DvrWriteBuffer* write_buffer_1 = nullptr;
+ DvrNativeBufferMetadata out_meta_1;
+ out_fence_fd = -1;
+ ret = api_.WriteBufferQueueGainBuffer(
+ write_queue_1, kTimeoutMs, &write_buffer_1, &out_meta_1, &out_fence_fd);
+ EXPECT_EQ(0, ret) << "Failed to get the buffer.";
+ EXPECT_NE(nullptr, write_buffer_1) << "Gained buffer should not be null.";
+
+ // Color the write buffers.
+ FillWriteBuffer(write_buffer_0, {0xffff0000, 0xff00ff00, 0xff0000ff}, width,
+ height);
+ FillWriteBuffer(write_buffer_1, {0x7f00ff00, 0x7f0000ff, 0x7fff0000}, width,
+ height);
+
+ // Post buffers.
+ int ready_fence_fd = -1;
+ ret = api_.WriteBufferQueuePostBuffer(write_queue_0, write_buffer_0,
+ &out_meta_0, ready_fence_fd);
+ EXPECT_EQ(0, ret) << "Failed to post the buffer.";
+
+ ready_fence_fd = -1;
+ ret = api_.WriteBufferQueuePostBuffer(write_queue_1, write_buffer_1,
+ &out_meta_1, ready_fence_fd);
+ EXPECT_EQ(0, ret) << "Failed to post the buffer.";
+
+ sleep(5); // For visual check on the device under test.
+ // Should observe three secondary colors.
+
+ // Test finished. Clean up buffers and surfaces.
+ if (write_queue_0 != nullptr) {
+ api_.WriteBufferQueueDestroy(write_queue_0);
+ write_queue_0 = nullptr;
+ }
+ if (write_queue_1 != nullptr) {
+ api_.WriteBufferQueueDestroy(write_queue_1);
+ write_queue_1 = nullptr;
+ }
+ if (direct_surface_0 != nullptr) {
+ api_.SurfaceDestroy(direct_surface_0);
+ }
+ if (direct_surface_1 != nullptr) {
+ api_.SurfaceDestroy(direct_surface_1);
+ }
+}
+
+void DvrDisplayTest::FillWriteBuffer(
+ DvrWriteBuffer* write_buffer, const std::vector<uint32_t>& color_textures,
+ uint32_t width, uint32_t height) {
+ uint32_t num_colors = color_textures.size();
+ // Convert the first write buffer to an android hardware buffer.
+ AHardwareBuffer* ah_buffer = nullptr;
+ int ret = api_.WriteBufferGetAHardwareBuffer(write_buffer, &ah_buffer);
+ ASSERT_EQ(0, ret) << "Failed to get a hardware buffer from the write buffer.";
+ ASSERT_NE(nullptr, ah_buffer) << "AHardware buffer should not be null.";
+ AHardwareBuffer_Desc ah_buffer_describe;
+ AHardwareBuffer_describe(ah_buffer, &ah_buffer_describe);
+ ASSERT_EQ(ah_buffer_describe.format, kFormat)
+ << "The format of the android hardware buffer is wrong.";
+ ASSERT_EQ(ah_buffer_describe.layers, kLayerCount)
+ << "The obtained android hardware buffer should have 2 layers.";
+ ASSERT_EQ(ah_buffer_describe.width, width)
+ << "The obtained android hardware buffer width is wrong.";
+ ASSERT_EQ(ah_buffer_describe.height, height)
+ << "The obtained android hardware buffer height is wrong.";
+ // Change the content of the android hardware buffer.
+ void* buffer_data = nullptr;
+ int32_t fence = -1;
+ ret = AHardwareBuffer_lock(ah_buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
+ fence, nullptr, &buffer_data);
+ ASSERT_EQ(0, ret) << "Failed to lock the hardware buffer.";
+ ASSERT_NE(nullptr, buffer_data) << "Buffer data should not be null.";
+
+ uint32_t num_pixels = width * height / num_colors;
+ for (uint32_t color_index = 0; color_index < num_colors - 1; ++color_index) {
+ uint32_t color_texture = color_textures[color_index];
+ for (uint32_t i = 0; i < num_pixels; ++i) {
+ memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) +
+ (i + num_pixels * color_index) *
+ sizeof(color_texture)),
+ &color_texture, sizeof(color_texture));
+ }
+ }
+ uint32_t color_texture = color_textures[num_colors - 1];
+ uint32_t num_colored_pixels = num_pixels * (num_colors - 1);
+ num_pixels = width * height - num_colored_pixels;
+ for (uint32_t i = 0; i < num_pixels; ++i) {
+ memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) +
+ (i + num_colored_pixels) *
+ sizeof(color_texture)),
+ &color_texture, sizeof(color_texture));
+ }
+ fence = -1;
+ ret = AHardwareBuffer_unlock(ah_buffer, &fence);
+ EXPECT_EQ(0, ret) << "Failed to unlock the hardware buffer.";
+
+ // Release the android hardware buffer.
+ AHardwareBuffer_release(ah_buffer);
}
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
index 0ee77f4..32d40e8 100644
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ b/libs/vr/libpdx_uds/service_endpoint.cpp
@@ -594,9 +594,10 @@
if (socket_fd_ && event.data.fd == socket_fd_.Get()) {
auto status = AcceptConnection(message);
- if (!status)
- return status;
- return ReenableEpollEvent(socket_fd_.Borrow());
+ auto reenable_status = ReenableEpollEvent(socket_fd_.Borrow());
+ if (!reenable_status)
+ return reenable_status;
+ return status;
}
BorrowedHandle channel_fd{event.data.fd};
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index 23a9853..3e4a42c 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -39,6 +39,7 @@
"android.frameworks.vr.composer@1.0",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.2",
"libbinder",
"libbase",
"libbufferhubqueue",
@@ -62,6 +63,7 @@
headerLibraries = [
"android.hardware.graphics.composer@2.1-command-buffer",
+ "android.hardware.graphics.composer@2.2-command-buffer",
"libdvr_headers",
"libsurfaceflinger_headers",
]
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index be8a721..5b49645 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -45,9 +45,6 @@
namespace {
-const char kBacklightBrightnessSysFile[] =
- "/sys/class/leds/lcd-backlight/brightness";
-
const char kDvrPerformanceProperty[] = "sys.dvr.performance";
const char kDvrStandaloneProperty[] = "ro.boot.vr";
@@ -257,13 +254,6 @@
EnableVsync(true);
- // TODO(skiazyk): We need to do something about accessing this directly,
- // supposedly there is a backlight service on the way.
- // TODO(steventhomas): When we change the backlight setting, will surface
- // flinger (or something else) set it back to its original value once we give
- // control of the display back to surface flinger?
- SetBacklightBrightness(255);
-
// Trigger target-specific performance mode change.
property_set(kDvrPerformanceProperty, "performance");
}
@@ -698,16 +688,6 @@
bool thread_policy_setup =
SetThreadPolicy("graphics:high", "/system/performance");
-#if ENABLE_BACKLIGHT_BRIGHTNESS
- // TODO(hendrikw): This isn't required at the moment. It's possible that there
- // is another method to access this when needed.
- // Open the backlight brightness control sysfs node.
- backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
- ALOGW_IF(!backlight_brightness_fd_,
- "HardwareComposer: Failed to open backlight brightness control: %s",
- strerror(errno));
-#endif // ENABLE_BACKLIGHT_BRIGHTNESS
-
// Create a timerfd based on CLOCK_MONOTINIC.
vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
LOG_ALWAYS_FATAL_IF(
@@ -983,14 +963,6 @@
vsync_callback_ = callback;
}
-void HardwareComposer::SetBacklightBrightness(int brightness) {
- if (backlight_brightness_fd_) {
- std::array<char, 32> text;
- const int length = snprintf(text.data(), text.size(), "%d", brightness);
- write(backlight_brightness_fd_.Get(), text.data(), length);
- }
-}
-
Return<void> HardwareComposer::ComposerCallback::onHotplug(
Hwc2::Display display, IComposerCallback::Connection conn) {
// Our first onHotplug callback is always for the primary display.
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index 1d0c7ef..4a503f8 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -391,8 +391,6 @@
HWC::Error Validate(hwc2_display_t display);
HWC::Error Present(hwc2_display_t display);
- void SetBacklightBrightness(int brightness);
-
void PostLayers();
void PostThread();
@@ -499,9 +497,6 @@
// notified via post_thread_wait_.
bool boot_finished_ = false;
- // Backlight LED brightness sysfs node.
- pdx::LocalHandle backlight_brightness_fd_;
-
// VSync sleep timerfd.
pdx::LocalHandle vsync_sleep_timer_fd_;
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 46e7a97..b453d19 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -87,6 +87,8 @@
"EGL_ANDROID_get_native_client_buffer "
"EGL_ANDROID_front_buffer_auto_refresh "
"EGL_ANDROID_get_frame_timestamps "
+ "EGL_EXT_surface_SMPTE2086_metadata "
+ "EGL_EXT_surface_CTA861_3_metadata "
;
char const * const gExtensionString =
@@ -240,8 +242,6 @@
!strcmp((procname), "eglHibernateProcessIMG") || \
!strcmp((procname), "eglAwakenProcessIMG"))
-
-
// accesses protected by sExtensionMapMutex
static std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
@@ -476,26 +476,61 @@
return dataSpace;
}
-// Return true if we stripped any EGL_GL_COLORSPACE_KHR or HDR metadata attributes.
-// Protect devices from attributes they don't recognize that are managed by Android
+// stripAttributes is used by eglCreateWindowSurface, eglCreatePbufferSurface
+// and eglCreatePixmapSurface to clean up color space related Window parameters
+// that a driver does not advertise support for.
+// Return true if stripped_attrib_list has stripped contents.
+
static EGLBoolean stripAttributes(egl_display_ptr dp, const EGLint* attrib_list,
EGLint format,
std::vector<EGLint>& stripped_attrib_list) {
std::vector<EGLint> allowedColorSpaces;
+ bool haveColorSpaceSupport = dp->haveExtension("EGL_KHR_gl_colorspace");
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGB_565:
- // driver okay with linear & sRGB for 8888, but can't handle
- // Display-P3 or other spaces.
- allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
- allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
+ if (haveColorSpaceSupport) {
+ // Spec says:
+ // [fn1] Only OpenGL and OpenGL ES contexts which support sRGB
+ // rendering must respect requests for EGL_GL_COLORSPACE_SRGB_KHR, and
+ // only to sRGB formats supported by the context (normally just SRGB8)
+ // Older versions not supporting sRGB rendering will ignore this
+ // surface attribute.
+ //
+ // We support sRGB and pixel format is SRGB8, so allow
+ // the EGL_GL_COLORSPACE_SRGB_KHR and
+ // EGL_GL_COLORSPACE_LINEAR_KHR
+ // colorspaces to be specified.
+
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_display_p3_linear")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_display_p3")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_bt2020_linear")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_LINEAR_EXT);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_bt2020_pq")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
+ }
+ if (findExtension(dp->disp.queryString.extensions,
+ "EGL_EXT_gl_colorspace_scrgb_linear")) {
+ allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT);
+ }
break;
case HAL_PIXEL_FORMAT_RGBA_FP16:
case HAL_PIXEL_FORMAT_RGBA_1010102:
- default:
- // driver does not want to see colorspace attributes for 1010102 or fp16.
+ case HAL_PIXEL_FORMAT_RGB_565:
// Future: if driver supports XXXX extension, we can pass down that colorspace
+ default:
break;
}
@@ -513,40 +548,23 @@
found = true;
}
}
- if (found || !dp->haveExtension("EGL_KHR_gl_colorspace")) {
+ if (found) {
+ // Found supported attribute
+ stripped_attrib_list.push_back(attr[0]);
+ stripped_attrib_list.push_back(attr[1]);
+ } else if (!haveColorSpaceSupport) {
+ // Device does not support colorspace extension
+ // pass on the attribute and let downstream
+ // components validate like normal
stripped_attrib_list.push_back(attr[0]);
stripped_attrib_list.push_back(attr[1]);
} else {
+ // Found supported attribute that driver does not
+ // support, strip it.
stripped = true;
}
}
break;
- case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
- case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
- case EGL_SMPTE2086_WHITE_POINT_X_EXT:
- case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
- case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
- case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
- if (dp->haveExtension("EGL_EXT_surface_SMPTE2086_metadata")) {
- stripped = true;
- } else {
- stripped_attrib_list.push_back(attr[0]);
- stripped_attrib_list.push_back(attr[1]);
- }
- break;
- case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
- case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
- if (dp->haveExtension("EGL_EXT_surface_CTA861_3_metadata")) {
- stripped = true;
- } else {
- stripped_attrib_list.push_back(attr[0]);
- stripped_attrib_list.push_back(attr[1]);
- }
- break;
default:
stripped_attrib_list.push_back(attr[0]);
stripped_attrib_list.push_back(attr[1]);
@@ -700,34 +718,26 @@
}
}
-EGLBoolean setSurfaceMetadata(egl_surface_t* s, NativeWindowType window,
- const EGLint *attrib_list) {
- // set any HDR metadata
- bool smpte2086 = false;
- bool cta8613 = false;
- if (attrib_list == nullptr) return EGL_TRUE;
-
- for (const EGLint* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
- smpte2086 |= s->setSmpte2086Attribute(attr[0], attr[1]);
- cta8613 |= s->setCta8613Attribute(attr[0], attr[1]);
- }
- if (smpte2086) {
- android_smpte2086_metadata metadata = s->getSmpte2086Metadata();
- int err = native_window_set_buffers_smpte2086_metadata(window, &metadata);
+EGLBoolean sendSurfaceMetadata(egl_surface_t* s) {
+ android_smpte2086_metadata smpteMetadata;
+ if (s->getSmpte2086Metadata(smpteMetadata)) {
+ int err =
+ native_window_set_buffers_smpte2086_metadata(s->getNativeWindow(), &smpteMetadata);
+ s->resetSmpte2086Metadata();
if (err != 0) {
ALOGE("error setting native window smpte2086 metadata: %s (%d)",
strerror(-err), err);
- native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
return EGL_FALSE;
}
}
- if (cta8613) {
- android_cta861_3_metadata metadata = s->getCta8613Metadata();
- int err = native_window_set_buffers_cta861_3_metadata(window, &metadata);
+ android_cta861_3_metadata cta8613Metadata;
+ if (s->getCta8613Metadata(cta8613Metadata)) {
+ int err =
+ native_window_set_buffers_cta861_3_metadata(s->getNativeWindow(), &cta8613Metadata);
+ s->resetCta8613Metadata();
if (err != 0) {
ALOGE("error setting native window CTS 861.3 metadata: %s (%d)",
strerror(-err), err);
- native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
return EGL_FALSE;
}
}
@@ -812,11 +822,7 @@
if (surface != EGL_NO_SURFACE) {
egl_surface_t* s =
new egl_surface_t(dp.get(), config, window, surface, colorSpace, cnx);
-
- if (setSurfaceMetadata(s, window, origAttribList)) {
- return s;
- }
- eglDestroySurface(dpy, s);
+ return s;
}
// EGLSurface creation failed
@@ -1424,7 +1430,7 @@
if (!_s.get())
return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
- egl_surface_t const * const s = get_surface(draw);
+ egl_surface_t* const s = get_surface(draw);
if (CC_UNLIKELY(dp->traceGpuCompletion)) {
EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
@@ -1443,6 +1449,11 @@
}
}
+ if (!sendSurfaceMetadata(s)) {
+ native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
+ return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
+ }
+
if (n_rects == 0) {
return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
}
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 0f36614..74ddd1c 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -51,8 +51,11 @@
// ----------------------------------------------------------------------------
-static bool findExtension(const char* exts, const char* name, size_t nameLen) {
+bool findExtension(const char* exts, const char* name, size_t nameLen) {
if (exts) {
+ if (!nameLen) {
+ nameLen = strlen(name);
+ }
for (const char* match = strstr(exts, name); match; match = strstr(match + nameLen, name)) {
if (match[nameLen] == '\0' || match[nameLen] == ' ') {
return true;
@@ -226,11 +229,6 @@
"EGL_EXT_gl_colorspace_bt2020_linear EGL_EXT_gl_colorspace_bt2020_pq ");
}
- // Always advertise HDR metadata extensions since it's okay for an application
- // to specify such information even though it may not be used by the system.
- mExtensionString.append(
- "EGL_EXT_surface_SMPTE2086_metadata EGL_EXT_surface_CTA861_3_metadata ");
-
char const* start = gExtensionString;
do {
// length of the extension name
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 661f47e..ccd333d 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -42,6 +42,8 @@
class egl_context_t;
struct egl_connection_t;
+bool findExtension(const char* exts, const char* name, size_t nameLen = 0);
+
// ----------------------------------------------------------------------------
class EGLAPI egl_display_t { // marked as EGLAPI for testing purposes
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index b68fd61..f879254 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -64,8 +64,17 @@
cnx(cnx),
connected(true),
colorSpace(colorSpace),
- egl_smpte2086_metadata({}),
- egl_cta861_3_metadata({}) {
+ egl_smpte2086_dirty(false),
+ egl_cta861_3_dirty(false) {
+ egl_smpte2086_metadata.displayPrimaryRed = { EGL_DONT_CARE, EGL_DONT_CARE };
+ egl_smpte2086_metadata.displayPrimaryGreen = { EGL_DONT_CARE, EGL_DONT_CARE };
+ egl_smpte2086_metadata.displayPrimaryBlue = { EGL_DONT_CARE, EGL_DONT_CARE };
+ egl_smpte2086_metadata.whitePoint = { EGL_DONT_CARE, EGL_DONT_CARE };
+ egl_smpte2086_metadata.maxLuminance = EGL_DONT_CARE;
+ egl_smpte2086_metadata.minLuminance = EGL_DONT_CARE;
+ egl_cta861_3_metadata.maxFrameAverageLightLevel = EGL_DONT_CARE;
+ egl_cta861_3_metadata.maxContentLightLevel = EGL_DONT_CARE;
+
if (win) {
win->incStrong(this);
}
@@ -92,33 +101,43 @@
switch (attribute) {
case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
egl_smpte2086_metadata.displayPrimaryRed.x = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
egl_smpte2086_metadata.displayPrimaryRed.y = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
egl_smpte2086_metadata.displayPrimaryGreen.x = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
egl_smpte2086_metadata.displayPrimaryGreen.y = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
egl_smpte2086_metadata.displayPrimaryBlue.x = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
egl_smpte2086_metadata.displayPrimaryBlue.y = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_WHITE_POINT_X_EXT:
egl_smpte2086_metadata.whitePoint.x = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
egl_smpte2086_metadata.whitePoint.y = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
egl_smpte2086_metadata.maxLuminance = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
egl_smpte2086_metadata.minLuminance = value;
+ egl_smpte2086_dirty = true;
return EGL_TRUE;
}
return EGL_FALSE;
@@ -128,16 +147,32 @@
switch (attribute) {
case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
egl_cta861_3_metadata.maxContentLightLevel = value;
+ egl_cta861_3_dirty = true;
return EGL_TRUE;
case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
egl_cta861_3_metadata.maxFrameAverageLightLevel = value;
+ egl_cta861_3_dirty = true;
return EGL_TRUE;
}
return EGL_FALSE;
}
-const android_smpte2086_metadata egl_surface_t::getSmpte2086Metadata() {
- android_smpte2086_metadata metadata;
+EGLBoolean egl_surface_t::getSmpte2086Metadata(android_smpte2086_metadata& metadata) const {
+ if (!egl_smpte2086_dirty) return EGL_FALSE;
+ if (egl_smpte2086_metadata.displayPrimaryRed.x == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryRed.y == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryGreen.x == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryGreen.y == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryBlue.x == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.displayPrimaryBlue.y == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.whitePoint.x == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.whitePoint.y == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.maxLuminance == EGL_DONT_CARE ||
+ egl_smpte2086_metadata.minLuminance == EGL_DONT_CARE) {
+ ALOGW("egl_surface_t: incomplete SMPTE 2086 metadata!");
+ return EGL_FALSE;
+ }
+
metadata.displayPrimaryRed.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.x) / EGL_METADATA_SCALING_EXT;
metadata.displayPrimaryRed.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.y) / EGL_METADATA_SCALING_EXT;
metadata.displayPrimaryGreen.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.x) / EGL_METADATA_SCALING_EXT;
@@ -149,14 +184,22 @@
metadata.maxLuminance = static_cast<float>(egl_smpte2086_metadata.maxLuminance) / EGL_METADATA_SCALING_EXT;
metadata.minLuminance = static_cast<float>(egl_smpte2086_metadata.minLuminance) / EGL_METADATA_SCALING_EXT;
- return metadata;
+ return EGL_TRUE;
}
-const android_cta861_3_metadata egl_surface_t::getCta8613Metadata() {
- android_cta861_3_metadata metadata;
+EGLBoolean egl_surface_t::getCta8613Metadata(android_cta861_3_metadata& metadata) const {
+ if (!egl_cta861_3_dirty) return EGL_FALSE;
+
+ if (egl_cta861_3_metadata.maxContentLightLevel == EGL_DONT_CARE ||
+ egl_cta861_3_metadata.maxFrameAverageLightLevel == EGL_DONT_CARE) {
+ ALOGW("egl_surface_t: incomplete CTA861.3 metadata!");
+ return EGL_FALSE;
+ }
+
metadata.maxContentLightLevel = static_cast<float>(egl_cta861_3_metadata.maxContentLightLevel) / EGL_METADATA_SCALING_EXT;
metadata.maxFrameAverageLightLevel = static_cast<float>(egl_cta861_3_metadata.maxFrameAverageLightLevel) / EGL_METADATA_SCALING_EXT;
- return metadata;
+
+ return EGL_TRUE;
}
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index bda91bb..4e1de5c 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -142,8 +142,10 @@
EGLBoolean getColorSpaceAttribute(EGLint attribute, EGLint* value) const;
EGLBoolean getSmpte2086Attribute(EGLint attribute, EGLint* value) const;
EGLBoolean getCta8613Attribute(EGLint attribute, EGLint* value) const;
- const android_smpte2086_metadata getSmpte2086Metadata();
- const android_cta861_3_metadata getCta8613Metadata();
+ EGLBoolean getSmpte2086Metadata(android_smpte2086_metadata& smpte2086) const;
+ EGLBoolean getCta8613Metadata(android_cta861_3_metadata& cta861_3) const;
+ void resetSmpte2086Metadata() { egl_smpte2086_dirty = false; }
+ void resetCta8613Metadata() { egl_cta861_3_dirty = false; }
// Try to keep the order of these fields and size unchanged. It's not public API, but
// it's not hard to imagine native games accessing them.
@@ -176,6 +178,10 @@
EGLint maxContentLightLevel;
EGLint maxFrameAverageLightLevel;
};
+
+ bool egl_smpte2086_dirty;
+ bool egl_cta861_3_dirty;
+
egl_smpte2086_metadata egl_smpte2086_metadata;
egl_cta861_3_metadata egl_cta861_3_metadata;
};
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index 9ffe036..5927dc1 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -61,8 +61,8 @@
class EGLTest : public ::testing::Test {
public:
void get8BitConfig(EGLConfig& config);
- void addOptionalWindowMetadata(std::vector<EGLint>& attrs);
- void checkOptionalWindowMetadata(EGLSurface eglSurface);
+ void setSurfaceSmpteMetadata(EGLSurface surface);
+ void checkSurfaceSmpteMetadata(EGLSurface eglSurface);
protected:
EGLDisplay mEglDisplay;
@@ -421,39 +421,39 @@
EXPECT_EQ(components[3], 8);
}
-void EGLTest::addOptionalWindowMetadata(std::vector<EGLint>& attrs) {
+void EGLTest::setSurfaceSmpteMetadata(EGLSurface surface) {
if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_SMPTE2086_metadata")) {
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT);
- attrs.push_back(METADATA_SCALE(0.640));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT);
- attrs.push_back(METADATA_SCALE(0.330));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT);
- attrs.push_back(METADATA_SCALE(0.290));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT);
- attrs.push_back(METADATA_SCALE(0.600));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT);
- attrs.push_back(METADATA_SCALE(0.150));
- attrs.push_back(EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT);
- attrs.push_back(METADATA_SCALE(0.060));
- attrs.push_back(EGL_SMPTE2086_WHITE_POINT_X_EXT);
- attrs.push_back(METADATA_SCALE(0.3127));
- attrs.push_back(EGL_SMPTE2086_WHITE_POINT_Y_EXT);
- attrs.push_back(METADATA_SCALE(0.3290));
- attrs.push_back(EGL_SMPTE2086_MAX_LUMINANCE_EXT);
- attrs.push_back(METADATA_SCALE(300));
- attrs.push_back(EGL_SMPTE2086_MIN_LUMINANCE_EXT);
- attrs.push_back(METADATA_SCALE(0.7));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT,
+ METADATA_SCALE(0.640));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT,
+ METADATA_SCALE(0.330));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT,
+ METADATA_SCALE(0.290));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT,
+ METADATA_SCALE(0.600));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT,
+ METADATA_SCALE(0.150));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT,
+ METADATA_SCALE(0.060));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT,
+ METADATA_SCALE(0.3127));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT,
+ METADATA_SCALE(0.3290));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT,
+ METADATA_SCALE(300));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT,
+ METADATA_SCALE(0.7));
}
if (hasEglExtension(mEglDisplay, "EGL_EXT_surface_CTA861_3_metadata")) {
- attrs.push_back(EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT);
- attrs.push_back(METADATA_SCALE(300));
- attrs.push_back(EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT);
- attrs.push_back(METADATA_SCALE(75));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(300));
+ eglSurfaceAttrib(mEglDisplay, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
+ METADATA_SCALE(75));
}
}
-void EGLTest::checkOptionalWindowMetadata(EGLSurface eglSurface) {
+void EGLTest::checkSurfaceSmpteMetadata(EGLSurface eglSurface) {
EGLBoolean success;
EGLint value;
@@ -534,8 +534,6 @@
winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
- ASSERT_NO_FATAL_FAILURE(addOptionalWindowMetadata(winAttrs));
-
winAttrs.push_back(EGL_NONE);
EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
@@ -547,7 +545,9 @@
ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
- ASSERT_NO_FATAL_FAILURE(checkOptionalWindowMetadata(eglSurface));
+ ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
+
+ ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
}
@@ -584,9 +584,6 @@
std::vector<EGLint> winAttrs;
winAttrs.push_back(EGL_GL_COLORSPACE_KHR);
winAttrs.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
-
- ASSERT_NO_FATAL_FAILURE(addOptionalWindowMetadata(winAttrs));
-
winAttrs.push_back(EGL_NONE);
EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), winAttrs.data());
@@ -598,7 +595,9 @@
ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
ASSERT_EQ(EGL_GL_COLORSPACE_BT2020_PQ_EXT, value);
- ASSERT_NO_FATAL_FAILURE(checkOptionalWindowMetadata(eglSurface));
+ ASSERT_NO_FATAL_FAILURE(setSurfaceSmpteMetadata(eglSurface));
+
+ ASSERT_NO_FATAL_FAILURE(checkSurfaceSmpteMetadata(eglSurface));
EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface));
}
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index 13f6fba..0bb77f3 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -32,6 +32,8 @@
using namespace android;
extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+#define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
+
static void printGLString(const char *name, GLenum s) {
// fprintf(stderr, "printGLString %s, %d\n", name, s);
const char *v = (const char *) glGetString(s);
@@ -265,6 +267,39 @@
return true;
}
+void setSurfaceMetadata(EGLDisplay dpy, EGLSurface surface) {
+ static EGLBoolean toggle = GL_FALSE;
+ if (EGLUtils::hasEglExtension(dpy, "EGL_EXT_surface_SMPTE2086_metadata")) {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, METADATA_SCALE(0.640));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, METADATA_SCALE(0.330));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, METADATA_SCALE(0.290));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, METADATA_SCALE(0.600));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, METADATA_SCALE(0.150));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, METADATA_SCALE(0.060));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT, METADATA_SCALE(0.3127));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, METADATA_SCALE(0.3290));
+ if (toggle) {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(350));
+ } else {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(300));
+ }
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, METADATA_SCALE(0.7));
+ }
+
+ if (EGLUtils::hasEglExtension(dpy, "EGL_EXT_surface_CTA861_3_metadata")) {
+ if (toggle) {
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(300));
+ } else {
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(325));
+ }
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
+ METADATA_SCALE(75));
+ }
+ toggle = !toggle;
+}
+
int main(int /*argc*/, char** /*argv*/) {
EGLBoolean returnValue;
EGLConfig myConfig = {0};
@@ -318,10 +353,11 @@
printf("Chose this configuration:\n");
printEGLConfiguration(dpy, myConfig);
- surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
+ EGLint winAttribs[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE};
+ surface = eglCreateWindowSurface(dpy, myConfig, window, winAttribs);
checkEglError("eglCreateWindowSurface");
if (surface == EGL_NO_SURFACE) {
- printf("gelCreateWindowSurface failed.\n");
+ printf("eglCreateWindowSurface failed.\n");
return 0;
}
@@ -356,6 +392,7 @@
for (;;) {
renderFrame();
+ setSurfaceMetadata(dpy, surface);
eglSwapBuffers(dpy, surface);
checkEglError("eglSwapBuffers");
}
diff --git a/opengl/tests/gl2_jni/Android.mk b/opengl/tests/gl2_jni/Android.mk
index af65b5f..b0081c2 100644
--- a/opengl/tests/gl2_jni/Android.mk
+++ b/opengl/tests/gl2_jni/Android.mk
@@ -37,13 +37,13 @@
gl_code.cpp
LOCAL_SHARED_LIBRARIES := \
- libutils \
liblog \
libEGL \
libGLESv2
LOCAL_MODULE := libgl2jni
+LOCAL_SDK_VERSION := current
include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/tests/gl2_jni/jni/gl_code.cpp b/opengl/tests/gl2_jni/jni/gl_code.cpp
index 5af4f6b..9b22c6c 100644
--- a/opengl/tests/gl2_jni/jni/gl_code.cpp
+++ b/opengl/tests/gl2_jni/jni/gl_code.cpp
@@ -2,7 +2,12 @@
#include <jni.h>
#define LOG_TAG "GL2JNI gl_code.cpp"
-#include <utils/Log.h>
+#include <android/log.h>
+
+#define ALOG(priority, tag, ...) ((void)__android_log_print(ANDROID_##priority, tag, __VA_ARGS__))
+
+#define ALOGI(...) ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define ALOGE(...) ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)
#include <EGL/egl.h>
#include <GLES2/gl2.h>
diff --git a/opengl/tests/gl_basic/gl_basic.cpp b/opengl/tests/gl_basic/gl_basic.cpp
index a675c7c..63d94be 100644
--- a/opengl/tests/gl_basic/gl_basic.cpp
+++ b/opengl/tests/gl_basic/gl_basic.cpp
@@ -15,6 +15,8 @@
using namespace android;
+#define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
+
EGLDisplay eglDisplay;
EGLSurface eglSurface;
EGLContext eglContext;
@@ -330,6 +332,39 @@
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
+void setSurfaceMetadata(EGLDisplay dpy, EGLSurface surface) {
+ static EGLBoolean toggle = GL_FALSE;
+ if (EGLUtils::hasEglExtension(dpy, "EGL_EXT_surface_SMPTE2086_metadata")) {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, METADATA_SCALE(0.640));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, METADATA_SCALE(0.330));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, METADATA_SCALE(0.290));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, METADATA_SCALE(0.600));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, METADATA_SCALE(0.150));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, METADATA_SCALE(0.060));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_WHITE_POINT_X_EXT, METADATA_SCALE(0.3127));
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_WHITE_POINT_Y_EXT, METADATA_SCALE(0.3290));
+ if (toggle) {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(350));
+ } else {
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(300));
+ }
+ eglSurfaceAttrib(dpy, surface, EGL_SMPTE2086_MIN_LUMINANCE_EXT, METADATA_SCALE(0.7));
+ }
+
+ if (EGLUtils::hasEglExtension(dpy, "EGL_EXT_surface_CTA861_3_metadata")) {
+ if (toggle) {
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(300));
+ } else {
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT,
+ METADATA_SCALE(325));
+ }
+ eglSurfaceAttrib(dpy, surface, EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT,
+ METADATA_SCALE(75));
+ }
+ toggle = !toggle;
+}
+
void render()
{
const GLfloat vertices[] = {
@@ -354,5 +389,6 @@
int nelem = sizeof(indices)/sizeof(indices[0]);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
+ setSurfaceMetadata(eglDisplay, eglSurface);
eglSwapBuffers(eglDisplay, eglSurface);
}
diff --git a/opengl/tests/gl_jni/Android.mk b/opengl/tests/gl_jni/Android.mk
index 570ae2b..d64dfcf 100644
--- a/opengl/tests/gl_jni/Android.mk
+++ b/opengl/tests/gl_jni/Android.mk
@@ -37,13 +37,14 @@
gl_code.cpp
LOCAL_SHARED_LIBRARIES := \
- libutils \
liblog \
libEGL \
libGLESv1_CM
LOCAL_MODULE := libgljni
+LOCAL_SDK_VERSION := current
+
LOCAL_ARM_MODE := arm
diff --git a/opengl/tests/gl_jni/jni/gl_code.cpp b/opengl/tests/gl_jni/jni/gl_code.cpp
index 3aa8adb..88f3228 100644
--- a/opengl/tests/gl_jni/jni/gl_code.cpp
+++ b/opengl/tests/gl_jni/jni/gl_code.cpp
@@ -2,7 +2,12 @@
#include <jni.h>
#define LOG_TAG "GLJNI gl_code.cpp"
-#include <utils/Log.h>
+#include <android/log.h>
+
+#define ALOG(priority, tag, ...) ((void)__android_log_print(ANDROID_##priority, tag, __VA_ARGS__))
+
+#define ALOGI(...) ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define ALOGE(...) ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)
#include <GLES/gl.h>
diff --git a/opengl/tests/gl_perfapp/Android.mk b/opengl/tests/gl_perfapp/Android.mk
index 854b54f..3f411ea 100644
--- a/opengl/tests/gl_perfapp/Android.mk
+++ b/opengl/tests/gl_perfapp/Android.mk
@@ -39,11 +39,12 @@
gl_code.cpp
LOCAL_SHARED_LIBRARIES := \
- libutils \
liblog \
libEGL \
libGLESv2
+LOCAL_SDK_VERSION := current
+
LOCAL_MODULE := libglperf
diff --git a/opengl/tests/gl_perfapp/jni/gl_code.cpp b/opengl/tests/gl_perfapp/jni/gl_code.cpp
index 0cb594a..bd1fd83 100644
--- a/opengl/tests/gl_perfapp/jni/gl_code.cpp
+++ b/opengl/tests/gl_perfapp/jni/gl_code.cpp
@@ -2,16 +2,21 @@
#include <jni.h>
#define LOG_TAG "GLPerf gl_code.cpp"
-#include <utils/Log.h>
+#include <android/log.h>
+
+#define ALOG(priority, tag, ...) ((void)__android_log_print(ANDROID_##priority, tag, __VA_ARGS__))
+
+#define ALOGI(...) ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define ALOGE(...) ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-#include <utils/Timers.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
+#include <time.h>
#include "../../gl_perf/fill_common.cpp"
diff --git a/opengl/tests/gldual/Android.mk b/opengl/tests/gldual/Android.mk
index dc265b6..5bdc0a8 100644
--- a/opengl/tests/gldual/Android.mk
+++ b/opengl/tests/gldual/Android.mk
@@ -37,13 +37,13 @@
gl_code.cpp
LOCAL_SHARED_LIBRARIES := \
- libutils \
liblog \
libEGL \
libGLESv2
LOCAL_MODULE := libgldualjni
+LOCAL_SDK_VERSION := current
include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/tests/gldual/jni/gl_code.cpp b/opengl/tests/gldual/jni/gl_code.cpp
index 90d150b..4e44976 100644
--- a/opengl/tests/gldual/jni/gl_code.cpp
+++ b/opengl/tests/gldual/jni/gl_code.cpp
@@ -2,7 +2,12 @@
#include <jni.h>
#define LOG_TAG "GL2JNI gl_code.cpp"
-#include <utils/Log.h>
+#include <android/log.h>
+
+#define ALOG(priority, tag, ...) ((void)__android_log_print(ANDROID_##priority, tag, __VA_ARGS__))
+
+#define ALOGI(...) ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define ALOGE(...) ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)
#include <EGL/egl.h>
#include <GLES2/gl2.h>
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 86492fd..c3f4f58 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -52,6 +52,7 @@
#include <time.h>
#include <unistd.h>
+#include <android-base/chrono_utils.h>
#include <android-base/stringprintf.h>
#include <log/log.h>
#include <utils/Trace.h>
@@ -69,28 +70,32 @@
// Default input dispatching timeout if there is no focused application or paused window
// from which to determine an appropriate dispatching timeout.
-const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
+constexpr nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
// Amount of time to allow for all pending events to be processed when an app switch
// key is on the way. This is used to preempt input dispatch and drop input events
// when an application takes too long to respond and the user has pressed an app switch key.
-const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
+constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
// Amount of time to allow for an event to be dispatched (measured since its eventTime)
// before considering it stale and dropping it.
-const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
+constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
// Amount of time to allow touch events to be streamed out to a connection before requiring
// that the first event be finished. This value extends the ANR timeout by the specified
// amount. For example, if streaming is allowed to get ahead by one second relative to the
// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
-const nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
+constexpr nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
-const nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
+constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
+
+// Log a warning when an interception call takes longer than this to process.
+constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
// Number of recent events to keep for debugging purposes.
-const size_t RECENT_QUEUE_MAX_SIZE = 10;
+constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
+
static inline nsecs_t now() {
return systemTime(SYSTEM_TIME_MONOTONIC);
@@ -2448,7 +2453,12 @@
flags, keyCode, args->scanCode, metaState, 0,
args->downTime, args->eventTime);
+ android::base::Timer t;
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
+ if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
+ ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
+ std::to_string(t.duration().count()).c_str());
+ }
bool needWake;
{ // acquire lock
@@ -2517,7 +2527,13 @@
uint32_t policyFlags = args->policyFlags;
policyFlags |= POLICY_FLAG_TRUSTED;
+
+ android::base::Timer t;
mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
+ if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
+ ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
+ std::to_string(t.duration().count()).c_str());
+ }
bool needWake;
{ // acquire lock
@@ -2629,7 +2645,12 @@
}
if (!(policyFlags & POLICY_FLAG_FILTERED)) {
+ android::base::Timer t;
mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
+ if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
+ ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
+ std::to_string(t.duration().count()).c_str());
+ }
}
mLock.lock();
@@ -2654,7 +2675,12 @@
if (!(policyFlags & POLICY_FLAG_FILTERED)) {
nsecs_t eventTime = motionEvent->getEventTime();
+ android::base::Timer t;
mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
+ if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
+ ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
+ std::to_string(t.duration().count()).c_str());
+ }
}
mLock.lock();
@@ -3540,8 +3566,13 @@
mLock.unlock();
+ android::base::Timer t;
nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
&event, entry->policyFlags);
+ if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
+ ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
+ std::to_string(t.duration().count()).c_str());
+ }
mLock.lock();
diff --git a/services/sensorservice/OWNERS b/services/sensorservice/OWNERS
index 6a38a1f..d4393d6 100644
--- a/services/sensorservice/OWNERS
+++ b/services/sensorservice/OWNERS
@@ -1,2 +1,2 @@
-ashutoshj@google.com
-pengxu@google.com
+arthuri@google.com
+bduddie@google.com
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index c32ffb9..2bd0a19 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -24,6 +24,7 @@
#include <cutils/properties.h>
#include <hardware/sensors.h>
#include <hardware_legacy/power.h>
+#include <log/log.h>
#include <openssl/digest.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
@@ -1093,10 +1094,15 @@
// check specific to memory type
switch(type) {
case SENSOR_DIRECT_MEM_TYPE_ASHMEM: { // channel backed by ashmem
+ if (resource->numFds < 1) {
+ ALOGE("Ashmem direct channel requires a memory region to be supplied");
+ android_errorWriteLog(0x534e4554, "70986337"); // SafetyNet
+ return nullptr;
+ }
int fd = resource->data[0];
int size2 = ashmem_get_size_region(fd);
// check size consistency
- if (size2 < static_cast<int>(size)) {
+ if (size2 < static_cast<int64_t>(size)) {
ALOGE("Ashmem direct channel size %" PRIu32 " greater than shared memory size %d",
size, size2);
return nullptr;
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index ecb5971..ba28eb5 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -24,6 +24,7 @@
"android.hardware.configstore@1.0",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.2",
"android.hardware.power@1.0",
"libbase",
"libbinder",
@@ -57,6 +58,7 @@
],
header_libs: [
"android.hardware.graphics.composer@2.1-command-buffer",
+ "android.hardware.graphics.composer@2.2-command-buffer",
],
export_static_lib_headers: [
"libserviceutils",
@@ -64,6 +66,7 @@
export_shared_lib_headers: [
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.2",
"libhidlbase",
"libhidltransport",
"libhwbinder",
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 3dbc136..d22c021 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -629,6 +629,13 @@
to_string(error).c_str(), static_cast<int32_t>(error));
}
+ const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata();
+ error = hwcLayer->setHdrMetadata(metadata);
+ if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
+ ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ }
+
uint32_t hwcSlot = 0;
sp<GraphicBuffer> hwcBuffer;
hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot,
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 03b714f..0425a8a 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -19,15 +19,23 @@
#include <inttypes.h>
#include <log/log.h>
-#include <gui/BufferQueue.h>
#include "ComposerHal.h"
+#include <android/hardware/graphics/composer/2.2/IComposer.h>
+#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
+#include <gui/BufferQueue.h>
+#include <hidl/HidlTransportUtils.h>
+
namespace android {
using hardware::Return;
using hardware::hidl_vec;
using hardware::hidl_handle;
+using namespace hardware::graphics::composer;
+using PerFrameMetadata = hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadata;
+using PerFrameMetadataKey =
+ hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadataKey;
namespace Hwc2 {
@@ -117,10 +125,9 @@
void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId)
{
constexpr uint16_t kSetLayerInfoLength = 2;
- beginCommand(
- static_cast<IComposerClient::Command>(
- IVrComposerClient::VrCommand::SET_LAYER_INFO),
- kSetLayerInfoLength);
+ beginCommand(static_cast<hardware::graphics::composer::V2_1::IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_LAYER_INFO),
+ kSetLayerInfoLength);
write(type);
write(appId);
endCommand();
@@ -130,10 +137,9 @@
const IVrComposerClient::BufferMetadata& metadata)
{
constexpr uint16_t kSetClientTargetMetadataLength = 7;
- beginCommand(
- static_cast<IComposerClient::Command>(
- IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA),
- kSetClientTargetMetadataLength);
+ beginCommand(static_cast<hardware::graphics::composer::V2_1::IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA),
+ kSetClientTargetMetadataLength);
writeBufferMetadata(metadata);
endCommand();
}
@@ -142,10 +148,9 @@
const IVrComposerClient::BufferMetadata& metadata)
{
constexpr uint16_t kSetLayerBufferMetadataLength = 7;
- beginCommand(
- static_cast<IComposerClient::Command>(
- IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA),
- kSetLayerBufferMetadataLength);
+ beginCommand(static_cast<hardware::graphics::composer::V2_1::IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA),
+ kSetLayerBufferMetadataLength);
writeBufferMetadata(metadata);
endCommand();
}
@@ -182,6 +187,13 @@
LOG_ALWAYS_FATAL("failed to create composer client");
}
+ // 2.2 support is optional
+ sp<V2_2::IComposer> composer_2_2 = V2_2::IComposer::castFrom(mComposer);
+ if (composer_2_2 != nullptr) {
+ mClient_2_2 = IComposerClient::castFrom(mClient);
+ LOG_ALWAYS_FATAL_IF(mClient_2_2 == nullptr, "IComposer 2.2 did not return IComposerClient 2.2");
+ }
+
if (mIsUsingVrComposer) {
sp<IVrComposerClient> vrClient = IVrComposerClient::castFrom(mClient);
if (vrClient == nullptr) {
@@ -451,6 +463,25 @@
return error;
}
+Error Composer::getPerFrameMetadataKeys(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) {
+ if (!mClient_2_2) {
+ return Error::UNSUPPORTED;
+ }
+
+ Error error = kDefaultError;
+ mClient_2_2->getPerFrameMetadataKeys(display, [&](const auto& tmpError, const auto& tmpKeys) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outKeys = tmpKeys;
+ });
+
+ return error;
+}
+
Error Composer::getReleaseFences(Display display,
std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
{
@@ -530,7 +561,15 @@
Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode)
{
- auto ret = mClient->setPowerMode(display, mode);
+ hardware::Return<Error> ret(Error::UNSUPPORTED);
+ if (mClient_2_2) {
+ ret = mClient_2_2->setPowerMode_2_2(display, mode);
+ } else if (mode != IComposerClient::PowerMode::ON_SUSPEND) {
+ ret = mClient->setPowerMode(display,
+ static_cast<hardware::graphics::composer::V2_1::
+ IComposerClient::PowerMode>(mode));
+ }
+
return unwrapRet(ret);
}
@@ -666,6 +705,47 @@
return Error::NONE;
}
+Error Composer::setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) {
+ if (!mClient_2_2) {
+ return Error::UNSUPPORTED;
+ }
+
+ mWriter.selectDisplay(display);
+ mWriter.selectLayer(layer);
+
+ std::vector<PerFrameMetadata> composerMetadata;
+ if (metadata.validTypes & HdrMetadata::SMPTE2086) {
+ composerMetadata
+ .insert(composerMetadata.end(),
+ {{PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
+ metadata.smpte2086.displayPrimaryRed.x},
+ {PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
+ metadata.smpte2086.displayPrimaryRed.y},
+ {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
+ metadata.smpte2086.displayPrimaryGreen.x},
+ {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
+ metadata.smpte2086.displayPrimaryGreen.y},
+ {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
+ metadata.smpte2086.displayPrimaryBlue.x},
+ {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
+ metadata.smpte2086.displayPrimaryBlue.y},
+ {PerFrameMetadataKey::WHITE_POINT_X, metadata.smpte2086.whitePoint.x},
+ {PerFrameMetadataKey::WHITE_POINT_Y, metadata.smpte2086.whitePoint.y},
+ {PerFrameMetadataKey::MAX_LUMINANCE, metadata.smpte2086.maxLuminance},
+ {PerFrameMetadataKey::MIN_LUMINANCE, metadata.smpte2086.minLuminance}});
+ }
+ if (metadata.validTypes & HdrMetadata::CTA861_3) {
+ composerMetadata.insert(composerMetadata.end(),
+ {{PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
+ metadata.cta8613.maxContentLightLevel},
+ {PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
+ metadata.cta8613.maxFrameAverageLightLevel}});
+ }
+
+ mWriter.setPerFrameMetadata(composerMetadata);
+ return Error::NONE;
+}
+
Error Composer::setLayerDisplayFrame(Display display, Layer layer,
const IComposerClient::Rect& frame)
{
@@ -810,7 +890,8 @@
mReader.takeErrors();
for (const auto& cmdErr : commandErrors) {
- auto command = mWriter.getCommand(cmdErr.location);
+ auto command =
+ static_cast<IComposerClient::Command>(mWriter.getCommand(cmdErr.location));
if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
command == IComposerClient::Command::PRESENT_DISPLAY ||
@@ -841,7 +922,10 @@
uint16_t length = 0;
while (!isEmpty()) {
- if (!beginCommand(&command, &length)) {
+ auto command_2_1 =
+ reinterpret_cast<hardware::graphics::composer::V2_1::IComposerClient::Command*>(
+ &command);
+ if (!beginCommand(command_2_1, &length)) {
break;
}
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 77675fb..c0373aa 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -24,8 +24,10 @@
#include <vector>
#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
-#include <android/hardware/graphics/composer/2.1/IComposer.h>
-#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
+#include <android/hardware/graphics/composer/2.2/IComposer.h>
+#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
+#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
+#include <gui/HdrMetadata.h>
#include <ui/GraphicBuffer.h>
#include <utils/StrongPointer.h>
@@ -42,16 +44,16 @@
using android::hardware::graphics::common::V1_0::PixelFormat;
using android::hardware::graphics::common::V1_0::Transform;
+using android::hardware::graphics::composer::V2_1::Config;
+using android::hardware::graphics::composer::V2_1::Display;
+using android::hardware::graphics::composer::V2_1::Error;
using android::hardware::graphics::composer::V2_1::IComposer;
using android::hardware::graphics::composer::V2_1::IComposerCallback;
-using android::hardware::graphics::composer::V2_1::IComposerClient;
-using android::hardware::graphics::composer::V2_1::Error;
-using android::hardware::graphics::composer::V2_1::Display;
using android::hardware::graphics::composer::V2_1::Layer;
-using android::hardware::graphics::composer::V2_1::Config;
+using android::hardware::graphics::composer::V2_2::IComposerClient;
-using android::hardware::graphics::composer::V2_1::CommandWriterBase;
-using android::hardware::graphics::composer::V2_1::CommandReaderBase;
+using android::hardware::graphics::composer::V2_2::CommandReaderBase;
+using android::hardware::graphics::composer::V2_2::CommandWriterBase;
using android::hardware::kSynchronizedReadWrite;
using android::hardware::MessageQueue;
@@ -111,6 +113,9 @@
float* outMaxLuminance, float* outMaxAverageLuminance,
float* outMinLuminance) = 0;
+ virtual Error getPerFrameMetadataKeys(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
+
virtual Error getReleaseFences(Display display, std::vector<Layer>* outLayers,
std::vector<int>* outReleaseFences) = 0;
@@ -155,6 +160,8 @@
virtual Error setLayerCompositionType(Display display, Layer layer,
IComposerClient::Composition type) = 0;
virtual Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) = 0;
+ virtual Error setLayerHdrMetadata(Display display, Layer layer,
+ const HdrMetadata& metadata) = 0;
virtual Error setLayerDisplayFrame(Display display, Layer layer,
const IComposerClient::Rect& frame) = 0;
virtual Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) = 0;
@@ -298,6 +305,9 @@
Error getHdrCapabilities(Display display, std::vector<Hdr>* outTypes, float* outMaxLuminance,
float* outMaxAverageLuminance, float* outMinLuminance) override;
+ Error getPerFrameMetadataKeys(
+ Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override;
+
Error getReleaseFences(Display display, std::vector<Layer>* outLayers,
std::vector<int>* outReleaseFences) override;
@@ -339,6 +349,7 @@
Error setLayerCompositionType(Display display, Layer layer,
IComposerClient::Composition type) override;
Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) override;
+ Error setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) override;
Error setLayerDisplayFrame(Display display, Layer layer,
const IComposerClient::Rect& frame) override;
Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override;
@@ -375,7 +386,8 @@
Error execute();
sp<IComposer> mComposer;
- sp<IComposerClient> mClient;
+ sp<hardware::graphics::composer::V2_1::IComposerClient> mClient;
+ sp<IComposerClient> mClient_2_2;
// 64KiB minus a small space for metadata such as read/write pointers
static constexpr size_t kWriterInitialSize =
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 814b55e..f14c2fe 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -37,6 +37,7 @@
using android::FloatRect;
using android::GraphicBuffer;
using android::HdrCapabilities;
+using android::HdrMetadata;
using android::Rect;
using android::Region;
using android::sp;
@@ -687,8 +688,7 @@
// Layer methods
-Layer::Layer(android::Hwc2::Composer& composer,
- const std::unordered_set<Capability>& capabilities,
+Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
hwc2_display_t displayId, hwc2_layer_t layerId)
: mComposer(composer),
mCapabilities(capabilities),
@@ -788,6 +788,16 @@
return static_cast<Error>(intError);
}
+Error Layer::setHdrMetadata(const android::HdrMetadata& metadata) {
+ if (metadata == mHdrMetadata) {
+ return Error::None;
+ }
+
+ mHdrMetadata = metadata;
+ auto intError = mComposer.setLayerHdrMetadata(mDisplayId, mId, metadata);
+ return static_cast<Error>(intError);
+}
+
Error Layer::setDisplayFrame(const Rect& frame)
{
Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index aade4e0..e74f00d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -23,8 +23,9 @@
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11
-#include <ui/HdrCapabilities.h>
+#include <gui/HdrMetadata.h>
#include <math/mat4.h>
+#include <ui/HdrCapabilities.h>
#include <utils/Log.h>
#include <utils/StrongPointer.h>
@@ -306,6 +307,7 @@
[[clang::warn_unused_result]] Error setCompositionType(Composition type);
[[clang::warn_unused_result]] Error setDataspace(
android_dataspace_t dataspace);
+ [[clang::warn_unused_result]] Error setHdrMetadata(const android::HdrMetadata& metadata);
[[clang::warn_unused_result]] Error setDisplayFrame(
const android::Rect& frame);
[[clang::warn_unused_result]] Error setPlaneAlpha(float alpha);
@@ -329,6 +331,7 @@
hwc2_display_t mDisplayId;
hwc2_layer_t mId;
android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN;
+ android::HdrMetadata mHdrMetadata;
std::function<void(Layer*)> mLayerDestroyedListener;
};
diff --git a/services/surfaceflinger/tests/unittests/MockComposer.h b/services/surfaceflinger/tests/unittests/MockComposer.h
index 248afcf..acd9b30 100644
--- a/services/surfaceflinger/tests/unittests/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/MockComposer.h
@@ -39,8 +39,8 @@
using android::hardware::graphics::composer::V2_1::Error;
using android::hardware::graphics::composer::V2_1::IComposer;
using android::hardware::graphics::composer::V2_1::IComposerCallback;
-using android::hardware::graphics::composer::V2_1::IComposerClient;
using android::hardware::graphics::composer::V2_1::Layer;
+using android::hardware::graphics::composer::V2_2::IComposerClient;
class Composer : public Hwc2::Composer {
public:
@@ -73,6 +73,8 @@
MOCK_METHOD2(getDisplayType, Error(Display, IComposerClient::DisplayType*));
MOCK_METHOD2(getDozeSupport, Error(Display, bool*));
MOCK_METHOD5(getHdrCapabilities, Error(Display, std::vector<Hdr>*, float*, float*, float*));
+ MOCK_METHOD2(getPerFrameMetadataKeys,
+ Error(Display, std::vector<IComposerClient::PerFrameMetadataKey>*));
MOCK_METHOD3(getReleaseFences, Error(Display, std::vector<Layer>*, std::vector<int>*));
MOCK_METHOD2(presentDisplay, Error(Display, int*));
MOCK_METHOD2(setActiveConfig, Error(Display, Config));
@@ -95,6 +97,7 @@
MOCK_METHOD3(setLayerColor, Error(Display, Layer, const IComposerClient::Color&));
MOCK_METHOD3(setLayerCompositionType, Error(Display, Layer, IComposerClient::Composition));
MOCK_METHOD3(setLayerDataspace, Error(Display, Layer, Dataspace));
+ MOCK_METHOD3(setLayerHdrMetadata, Error(Display, Layer, const HdrMetadata&));
MOCK_METHOD3(setLayerDisplayFrame, Error(Display, Layer, const IComposerClient::Rect&));
MOCK_METHOD3(setLayerPlaneAlpha, Error(Display, Layer, float));
MOCK_METHOD3(setLayerSidebandStream, Error(Display, Layer, const native_handle_t*));
diff --git a/services/vr/bufferhubd/Android.bp b/services/vr/bufferhubd/Android.bp
new file mode 100644
index 0000000..6009a95
--- /dev/null
+++ b/services/vr/bufferhubd/Android.bp
@@ -0,0 +1,55 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+sourceFiles = [
+ "buffer_hub.cpp",
+ "bufferhubd.cpp",
+ "consumer_channel.cpp",
+ "producer_channel.cpp",
+ "consumer_queue_channel.cpp",
+ "producer_queue_channel.cpp",
+]
+
+headerLibraries = ["libdvr_headers"]
+
+staticLibraries = [
+ "libperformance",
+ "libbufferhub",
+]
+
+sharedLibraries = [
+ "libbase",
+ "libbinder",
+ "libcutils",
+ "liblog",
+ "libsync",
+ "libutils",
+ "libgui",
+ "libui",
+ "libpdx_default_transport",
+]
+
+cc_binary {
+ srcs: sourceFiles,
+ cflags: [
+ "-DLOG_TAG=\"bufferhubd\"",
+ "-DTRACE=0",
+ "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+ ],
+ header_libs: headerLibraries,
+ static_libs: staticLibraries,
+ shared_libs: sharedLibraries,
+ name: "bufferhubd",
+ init_rc: ["bufferhubd.rc"],
+}
diff --git a/services/vr/bufferhubd/Android.mk b/services/vr/bufferhubd/Android.mk
deleted file mode 100644
index 1a99cf4..0000000
--- a/services/vr/bufferhubd/Android.mk
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
- buffer_hub.cpp \
- bufferhubd.cpp \
- consumer_channel.cpp \
- producer_channel.cpp \
- consumer_queue_channel.cpp \
- producer_queue_channel.cpp \
-
-headerLibraries := \
- libdvr_headers
-
-staticLibraries := \
- libperformance \
- libbufferhub
-
-sharedLibraries := \
- libbase \
- libbinder \
- libcutils \
- liblog \
- libsync \
- libutils \
- libgui \
- libui \
- libpdx_default_transport \
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_CFLAGS := -DLOG_TAG=\"bufferhubd\"
-LOCAL_CFLAGS += -DTRACE=0
-LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_GRAPHICS
-LOCAL_HEADER_LIBRARIES := $(headerLibraries)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := bufferhubd
-LOCAL_INIT_RC := bufferhubd.rc
-include $(BUILD_EXECUTABLE)
-
diff --git a/services/vr/hardware_composer/impl/vr_hwc.cpp b/services/vr/hardware_composer/impl/vr_hwc.cpp
index 180e232..313c022 100644
--- a/services/vr/hardware_composer/impl/vr_hwc.cpp
+++ b/services/vr/hardware_composer/impl/vr_hwc.cpp
@@ -15,6 +15,7 @@
*/
#include "impl/vr_hwc.h"
+#include "android-base/stringprintf.h"
#include <cutils/properties.h>
#include <private/dvr/display_client.h>
#include <ui/Fence.h>
@@ -26,6 +27,7 @@
using namespace android::hardware::graphics::common::V1_0;
using namespace android::hardware::graphics::composer::V2_1;
+using android::base::StringPrintf;
using android::hardware::hidl_handle;
using android::hardware::hidl_string;
using android::hardware::hidl_vec;
@@ -225,6 +227,20 @@
memcpy(color_transform_, matrix, sizeof(color_transform_));
}
+void HwcDisplay::dumpDebugInfo(std::string* result) const {
+ if (!result) {
+ return;
+ }
+ *result += StringPrintf("HwcDisplay: width: %d, height: %d, layers size: %zu, colormode: %d\
+ , config: %d\n", width_, height_, layers_.size(), color_mode_, active_config_);
+ *result += StringPrintf("HwcDisplay buffer metadata: width: %d, height: %d, stride: %d,\
+ layerCount: %d, pixelFormat: %d\n", buffer_metadata_.width, buffer_metadata_.height,
+ buffer_metadata_.stride, buffer_metadata_.layerCount, buffer_metadata_.format);
+ for (const auto& layer : layers_) {
+ layer.dumpDebugInfo(result);
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// VrHwcClient
@@ -831,7 +847,19 @@
}
Return<void> VrHwc::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
- hidl_cb(hidl_string());
+ std::string result;
+
+ {
+ std::lock_guard<std::mutex> guard(mutex_);
+ result = "\nVrHwc states:\n";
+ for (const auto& pair : displays_) {
+ result += StringPrintf("Display id: %lu\n", (unsigned long)pair.first);
+ pair.second->dumpDebugInfo(&result);
+ }
+ result += "\n";
+ }
+
+ hidl_cb(hidl_string(result));
return Void();
}
@@ -881,5 +909,22 @@
return iter == displays_.end() ? nullptr : iter->second.get();
}
+void HwcLayer::dumpDebugInfo(std::string* result) const {
+ if (!result) {
+ return;
+ }
+ *result += StringPrintf("Layer: composition_type: %d, type: %d, app_id: %d, z_order: %d,\
+ cursor_x: %d, cursor_y: %d, color(rgba): (%d,%d,%d,%d), dataspace: %d, transform: %d,\
+ display_frame(LTRB): (%d,%d,%d,%d), crop(LTRB): (%.1f,%.1f,%.1f,%.1f), blend_mode: %d\n",
+ composition_type, info.type, info.app_id, info.z_order, info.cursor_x, info.cursor_y,
+ info.color.r, info.color.g, info.color.b, info.color.a, info.dataspace, info.transform,
+ info.display_frame.left, info.display_frame.top, info.display_frame.right,
+ info.display_frame.bottom, info.crop.left, info.crop.top, info.crop.right,
+ info.crop.bottom, info.blend_mode);
+ *result += StringPrintf("Layer buffer metadata: width: %d, height: %d, stride: %d, layerCount: %d\
+ , pixelFormat: %d\n", buffer_metadata.width, buffer_metadata.height, buffer_metadata.stride,
+ buffer_metadata.layerCount, buffer_metadata.format);
+}
+
} // namespace dvr
} // namespace android
diff --git a/services/vr/hardware_composer/impl/vr_hwc.h b/services/vr/hardware_composer/impl/vr_hwc.h
index 1c308f2..d5d5f55 100644
--- a/services/vr/hardware_composer/impl/vr_hwc.h
+++ b/services/vr/hardware_composer/impl/vr_hwc.h
@@ -116,6 +116,8 @@
info.id = new_id;
}
+ void dumpDebugInfo(std::string* result) const;
+
Composition composition_type;
ComposerView::ComposerLayer info;
IVrComposerClient::BufferMetadata buffer_metadata;
@@ -163,6 +165,8 @@
int32_t color_transform_hint() const { return color_transform_hint_; }
void SetColorTransform(const float* matrix, int32_t hint);
+ void dumpDebugInfo(std::string* result) const;
+
private:
// The client target buffer and the associated fence.
sp<GraphicBuffer> buffer_;
diff --git a/services/vr/hardware_composer/vr_hwc.rc b/services/vr/hardware_composer/vr_hwc.rc
index 6f930a8..645ab80 100644
--- a/services/vr/hardware_composer/vr_hwc.rc
+++ b/services/vr/hardware_composer/vr_hwc.rc
@@ -3,3 +3,4 @@
user system
group system graphics
onrestart restart surfaceflinger
+ writepid /dev/cpuset/system-background/tasks
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index a9d473d..dec39e0 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -407,6 +407,12 @@
for (uint32_t i = 0; i < ext_count; i++)
FilterExtension(ext_names[i]);
+ // Enable device extensions that contain physical-device commands, so that
+ // vkGetInstanceProcAddr will return those physical-device commands.
+ if (is_instance_) {
+ hook_extensions_.set(ProcHook::KHR_swapchain);
+ }
+
ext_names = extension_filter_.names;
ext_count = extension_filter_.name_count;