Merge "Remove GLES wording from SurfaceFlinger."
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 95957a0..f5a53f1 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -2595,6 +2595,8 @@
std::getline(in, ignored);
if (android::base::GetBoolProperty(kFuseProp, false)) {
+ // TODO(b/146139106): Use sdcardfs mounts on devices running sdcardfs so we don't bypass
+ // it's VFS cache
if (target.compare(0, 17, "/mnt/pass_through") == 0) {
LOG(DEBUG) << "Found storage mount " << source << " at " << target;
mStorageMounts[source] = target;
@@ -2616,6 +2618,17 @@
std::lock_guard<std::recursive_mutex> lock(mMountsLock);
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
auto path = StringPrintf("%s/media", create_data_path(uuid_).c_str());
+ if (android::base::GetBoolProperty(kFuseProp, false)) {
+ // TODO(b/146139106): This is only safe on devices not running sdcardfs where there is no
+ // risk of bypassing the sdcardfs VFS cache
+
+ // Always use the lower filesystem path on FUSE enabled devices not running sdcardfs
+ // The upper filesystem path, /mnt/pass_through/<userid>/<vol>/ which was a bind mount
+ // to the lower filesytem may have been unmounted already when a user is
+ // removed and the path will now be pointing to a tmpfs without content
+ return StringPrintf("%s/%u", path.c_str(), userid);
+ }
+
auto resolved = mStorageMounts[path];
if (resolved.empty()) {
LOG(WARNING) << "Failed to find storage mount for " << path;
diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h
index eaa562b..b327d76 100644
--- a/include/input/InputEventLabels.h
+++ b/include/input/InputEventLabels.h
@@ -405,13 +405,12 @@
{ nullptr, 0 }
};
-static const InputEventLabel FLAGS[] = {
- DEFINE_FLAG(VIRTUAL),
- DEFINE_FLAG(FUNCTION),
- DEFINE_FLAG(GESTURE),
+static const InputEventLabel FLAGS[] = {DEFINE_FLAG(VIRTUAL),
+ DEFINE_FLAG(FUNCTION),
+ DEFINE_FLAG(GESTURE),
+ DEFINE_FLAG(WAKE),
- { nullptr, 0 }
-};
+ {nullptr, 0}};
static int lookupValueByLabel(const char* literal, const InputEventLabel *list) {
while (list->literal) {
diff --git a/libs/gralloc/types/Gralloc4.cpp b/libs/gralloc/types/Gralloc4.cpp
index 0330dac..fd91b15 100644
--- a/libs/gralloc/types/Gralloc4.cpp
+++ b/libs/gralloc/types/Gralloc4.cpp
@@ -25,15 +25,19 @@
using android::hardware::hidl_vec;
-using ::aidl::android::hardware::graphics::common::BlendMode;
-using ::aidl::android::hardware::graphics::common::Dataspace;
-using ::aidl::android::hardware::graphics::common::PlaneLayout;
-using ::aidl::android::hardware::graphics::common::PlaneLayoutComponent;
-using ::aidl::android::hardware::graphics::common::ExtendableType;
-using ::aidl::android::hardware::graphics::common::Rect;
-using ::aidl::android::hardware::graphics::common::StandardMetadataType;
+using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::ChromaSiting;
+using aidl::android::hardware::graphics::common::Compression;
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::ExtendableType;
+using aidl::android::hardware::graphics::common::Interlaced;
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using aidl::android::hardware::graphics::common::Rect;
+using aidl::android::hardware::graphics::common::StandardMetadataType;
-using MetadataType = ::android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
namespace android {
@@ -545,12 +549,9 @@
/**
* Public API functions
*/
-bool isStandardMetadataType(const MetadataType& metadataType) {
- return !std::strncmp(metadataType.name.c_str(), GRALLOC4_STANDARD_METADATA_TYPE, metadataType.name.size());
-}
-
-StandardMetadataType getStandardMetadataTypeValue(const MetadataType& metadataType) {
- return static_cast<StandardMetadataType>(metadataType.value);
+PlaneLayoutComponentType getStandardPlaneLayoutComponentTypeValue(
+ const ExtendableType& planeLayoutComponentType) {
+ return static_cast<PlaneLayoutComponentType>(planeLayoutComponentType.value);
}
status_t encodeBufferId(uint64_t bufferId, hidl_vec<uint8_t>* outBufferId) {
@@ -691,6 +692,119 @@
return decode(blendMode, reinterpret_cast<int32_t*>(outBlendMode), decodeInteger);
}
+bool isStandardMetadataType(const MetadataType& metadataType) {
+ return !std::strncmp(metadataType.name.c_str(), GRALLOC4_STANDARD_METADATA_TYPE,
+ metadataType.name.size());
+}
+
+bool isStandardCompression(const ExtendableType& compression) {
+ return !std::strncmp(compression.name.c_str(), GRALLOC4_STANDARD_COMPRESSION,
+ compression.name.size());
+}
+
+bool isStandardInterlaced(const ExtendableType& interlaced) {
+ return !std::strncmp(interlaced.name.c_str(), GRALLOC4_STANDARD_INTERLACED,
+ interlaced.name.size());
+}
+
+bool isStandardChromaSiting(const ExtendableType& chromaSiting) {
+ return !std::strncmp(chromaSiting.name.c_str(), GRALLOC4_STANDARD_CHROMA_SITING,
+ chromaSiting.name.size());
+}
+
+bool isStandardPlaneLayoutComponentType(const ExtendableType& planeLayoutComponentType) {
+ return !std::strncmp(planeLayoutComponentType.name.c_str(), GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE,
+ planeLayoutComponentType.name.size());
+}
+
+StandardMetadataType getStandardMetadataTypeValue(const MetadataType& metadataType) {
+ return static_cast<StandardMetadataType>(metadataType.value);
+}
+
+Compression getStandardCompressionValue(const ExtendableType& compression) {
+ return static_cast<Compression>(compression.value);
+}
+
+Interlaced getStandardInterlacedValue(const ExtendableType& interlaced) {
+ return static_cast<Interlaced>(interlaced.value);
+}
+
+ChromaSiting getStandardChromaSitingValue(const ExtendableType& chromaSiting) {
+ return static_cast<ChromaSiting>(chromaSiting.value);
+}
+
+std::string getCompressionName(const ExtendableType& compression) {
+ if (!isStandardCompression(compression)) {
+ std::ostringstream stream;
+ stream << compression.name << "#" << compression.value;
+ return stream.str();
+ }
+ switch (getStandardCompressionValue(compression)) {
+ case Compression::NONE:
+ return "None";
+ case Compression::DISPLAY_STREAM_COMPRESSION:
+ return "DisplayStreamCompression";
+ }
+}
+
+std::string getInterlacedName(const ExtendableType& interlaced) {
+ if (!isStandardInterlaced(interlaced)) {
+ std::ostringstream stream;
+ stream << interlaced.name << "#" << interlaced.value;
+ return stream.str();
+ }
+ switch (getStandardInterlacedValue(interlaced)) {
+ case Interlaced::NONE:
+ return "None";
+ case Interlaced::TOP_BOTTOM:
+ return "TopBottom";
+ case Interlaced::RIGHT_LEFT:
+ return "RightLeft";
+ }
+}
+
+std::string getChromaSitingName(const ExtendableType& chromaSiting) {
+ if (!isStandardChromaSiting(chromaSiting)) {
+ std::ostringstream stream;
+ stream << chromaSiting.name << "#" << chromaSiting.value;
+ return stream.str();
+ }
+ switch (getStandardChromaSitingValue(chromaSiting)) {
+ case ChromaSiting::NONE:
+ return "None";
+ case ChromaSiting::UNKNOWN:
+ return "Unknown";
+ case ChromaSiting::SITED_INTERSTITIAL:
+ return "SitedInterstitial";
+ case ChromaSiting::COSITED_HORIZONTAL:
+ return "CositedHorizontal";
+ }
+}
+
+std::string getPlaneLayoutComponentTypeName(const ExtendableType& planeLayoutComponentType) {
+ if (!isStandardPlaneLayoutComponentType(planeLayoutComponentType)) {
+ std::ostringstream stream;
+ stream << planeLayoutComponentType.name << "#" << planeLayoutComponentType.value;
+ return stream.str();
+ }
+ switch (getStandardPlaneLayoutComponentTypeValue(planeLayoutComponentType)) {
+ case PlaneLayoutComponentType::Y:
+ return "Y";
+ case PlaneLayoutComponentType::CB:
+ return "Cb";
+ case PlaneLayoutComponentType::CR:
+ return "Cr";
+ case PlaneLayoutComponentType::R:
+ return "R";
+ case PlaneLayoutComponentType::G:
+ return "G";
+ case PlaneLayoutComponentType::B:
+ return "B";
+ case PlaneLayoutComponentType::A:
+ return "A";
+ }
+}
+
} // namespace gralloc4
} // namespace android
diff --git a/libs/gralloc/types/include/gralloctypes/Gralloc4.h b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
index 80588cd..a5d3bb2 100644
--- a/libs/gralloc/types/include/gralloctypes/Gralloc4.h
+++ b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
@@ -34,10 +34,11 @@
namespace gralloc4 {
#define GRALLOC4_STANDARD_METADATA_TYPE "android.hardware.graphics.common.StandardMetadataType"
-#define GRALLOC4_CHROMA_SITING "android.hardware.graphics.common.ChromaSiting"
-#define GRALLOC4_COMPRESSION "android.hardware.graphics.common.Compression"
-#define GRALLOC4_INTERLACED "android.hardware.graphics.common.Interlaced"
-#define GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE "android.hardware.graphics.common.PlaneLayoutComponentType"
+#define GRALLOC4_STANDARD_CHROMA_SITING "android.hardware.graphics.common.ChromaSiting"
+#define GRALLOC4_STANDARD_COMPRESSION "android.hardware.graphics.common.Compression"
+#define GRALLOC4_STANDARD_INTERLACED "android.hardware.graphics.common.Interlaced"
+#define GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE \
+ "android.hardware.graphics.common.PlaneLayoutComponentType"
/*---------------------------------------------------------------------------------------------*/
/**
@@ -118,13 +119,15 @@
* Definitions of the standard compression strategies. It is recommended that everyone uses
* these definitions directly for standard compression strategies.
*/
-static const aidl::android::hardware::graphics::common::ExtendableType Compression_None = {
- GRALLOC4_COMPRESSION, static_cast<int64_t>(aidl::android::hardware::graphics::common::Compression::NONE)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType Compression_None =
+ {GRALLOC4_STANDARD_COMPRESSION,
+ static_cast<int64_t>(aidl::android::hardware::graphics::common::Compression::NONE)};
-static const aidl::android::hardware::graphics::common::ExtendableType Compression_DisplayStreamCompression = {
- GRALLOC4_COMPRESSION, static_cast<int64_t>(aidl::android::hardware::graphics::common::Compression::DISPLAY_STREAM_COMPRESSION)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType
+ Compression_DisplayStreamCompression =
+ {GRALLOC4_STANDARD_COMPRESSION,
+ static_cast<int64_t>(aidl::android::hardware::graphics::common::Compression::
+ DISPLAY_STREAM_COMPRESSION)};
/*---------------------------------------------------------------------------------------------*/
@@ -132,17 +135,17 @@
* Definitions of the standard interlaced strategies. It is recommended that everyone uses
* these definitions directly for standard interlaced strategies.
*/
-static const aidl::android::hardware::graphics::common::ExtendableType Interlaced_None = {
- GRALLOC4_INTERLACED, static_cast<int64_t>(aidl::android::hardware::graphics::common::Interlaced::NONE)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType Interlaced_None =
+ {GRALLOC4_STANDARD_INTERLACED,
+ static_cast<int64_t>(aidl::android::hardware::graphics::common::Interlaced::NONE)};
-static const aidl::android::hardware::graphics::common::ExtendableType Interlaced_TopBottom = {
- GRALLOC4_INTERLACED, static_cast<int64_t>(aidl::android::hardware::graphics::common::Interlaced::TOP_BOTTOM)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType Interlaced_TopBottom =
+ {GRALLOC4_STANDARD_INTERLACED,
+ static_cast<int64_t>(aidl::android::hardware::graphics::common::Interlaced::TOP_BOTTOM)};
-static const aidl::android::hardware::graphics::common::ExtendableType Interlaced_RightLeft = {
- GRALLOC4_INTERLACED, static_cast<int64_t>(aidl::android::hardware::graphics::common::Interlaced::RIGHT_LEFT)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType Interlaced_RightLeft =
+ {GRALLOC4_STANDARD_INTERLACED,
+ static_cast<int64_t>(aidl::android::hardware::graphics::common::Interlaced::RIGHT_LEFT)};
/*---------------------------------------------------------------------------------------------*/
@@ -150,21 +153,25 @@
* Definitions of the standard chroma siting. It is recommended that everyone uses
* these definitions directly for standard chroma siting.
*/
-static const aidl::android::hardware::graphics::common::ExtendableType ChromaSiting_None = {
- GRALLOC4_CHROMA_SITING, static_cast<int64_t>(aidl::android::hardware::graphics::common::ChromaSiting::NONE)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType ChromaSiting_None =
+ {GRALLOC4_STANDARD_CHROMA_SITING,
+ static_cast<int64_t>(aidl::android::hardware::graphics::common::ChromaSiting::NONE)};
-static const aidl::android::hardware::graphics::common::ExtendableType ChromaSiting_Unknown = {
- GRALLOC4_CHROMA_SITING, static_cast<int64_t>(aidl::android::hardware::graphics::common::ChromaSiting::UNKNOWN)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType ChromaSiting_Unknown =
+ {GRALLOC4_STANDARD_CHROMA_SITING,
+ static_cast<int64_t>(aidl::android::hardware::graphics::common::ChromaSiting::UNKNOWN)};
-static const aidl::android::hardware::graphics::common::ExtendableType ChromaSiting_SitedInterstitial = {
- GRALLOC4_CHROMA_SITING, static_cast<int64_t>(aidl::android::hardware::graphics::common::ChromaSiting::SITED_INTERSTITIAL)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType
+ ChromaSiting_SitedInterstitial = {GRALLOC4_STANDARD_CHROMA_SITING,
+ static_cast<int64_t>(
+ aidl::android::hardware::graphics::common::
+ ChromaSiting::SITED_INTERSTITIAL)};
-static const aidl::android::hardware::graphics::common::ExtendableType ChromaSiting_CositedHorizontal = {
- GRALLOC4_CHROMA_SITING, static_cast<int64_t>(aidl::android::hardware::graphics::common::ChromaSiting::COSITED_HORIZONTAL)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType
+ ChromaSiting_CositedHorizontal = {GRALLOC4_STANDARD_CHROMA_SITING,
+ static_cast<int64_t>(
+ aidl::android::hardware::graphics::common::
+ ChromaSiting::COSITED_HORIZONTAL)};
/*---------------------------------------------------------------------------------------------*/
@@ -172,44 +179,44 @@
* Definitions of the standard plane layout component types. It is recommended that everyone uses
* these definitions directly for standard plane layout component types
*/
-static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_Y = {
- GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, static_cast<int64_t>(aidl::android::hardware::graphics::common::PlaneLayoutComponentType::Y)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_Y =
+ {GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE,
+ static_cast<int64_t>(
+ aidl::android::hardware::graphics::common::PlaneLayoutComponentType::Y)};
-static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_CB = {
- GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, static_cast<int64_t>(aidl::android::hardware::graphics::common::PlaneLayoutComponentType::CB)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_CB =
+ {GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE,
+ static_cast<int64_t>(
+ aidl::android::hardware::graphics::common::PlaneLayoutComponentType::CB)};
-static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_CR = {
- GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, static_cast<int64_t>(aidl::android::hardware::graphics::common::PlaneLayoutComponentType::CR)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_CR =
+ {GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE,
+ static_cast<int64_t>(
+ aidl::android::hardware::graphics::common::PlaneLayoutComponentType::CR)};
-static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_R = {
- GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, static_cast<int64_t>(aidl::android::hardware::graphics::common::PlaneLayoutComponentType::R)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_R =
+ {GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE,
+ static_cast<int64_t>(
+ aidl::android::hardware::graphics::common::PlaneLayoutComponentType::R)};
-static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_G = {
- GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, static_cast<int64_t>(aidl::android::hardware::graphics::common::PlaneLayoutComponentType::G)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_G =
+ {GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE,
+ static_cast<int64_t>(
+ aidl::android::hardware::graphics::common::PlaneLayoutComponentType::G)};
-static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_B = {
- GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, static_cast<int64_t>(aidl::android::hardware::graphics::common::PlaneLayoutComponentType::B)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_B =
+ {GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE,
+ static_cast<int64_t>(
+ aidl::android::hardware::graphics::common::PlaneLayoutComponentType::B)};
-static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_A = {
- GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, static_cast<int64_t>(aidl::android::hardware::graphics::common::PlaneLayoutComponentType::A)
-};
+static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_A =
+ {GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE,
+ static_cast<int64_t>(
+ aidl::android::hardware::graphics::common::PlaneLayoutComponentType::A)};
/*---------------------------------------------------------------------------------------------*/
/**
- * The functions below can be used to parse a StandardMetadataType.
- */
-bool isStandardMetadataType(const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType);
-
-aidl::android::hardware::graphics::common::StandardMetadataType getStandardMetadataTypeValue(const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType);
-
-/**
* The functions below encode and decode standard metadata into a byte stream. It is STRONGLY
* recommended that both the vendor and system partitions use these functions when getting
* and setting metadata through gralloc 4 (IMapper 4.0).
@@ -265,6 +272,44 @@
status_t encodeBlendMode(const aidl::android::hardware::graphics::common::BlendMode& blendMode, android::hardware::hidl_vec<uint8_t>* outBlendMode);
status_t decodeBlendMode(const android::hardware::hidl_vec<uint8_t>& blendMode, aidl::android::hardware::graphics::common::BlendMode* outBlendMode);
+/**
+ * The functions below can be used to parse extendable types.
+ */
+bool isStandardMetadataType(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType);
+bool isStandardCompression(
+ const aidl::android::hardware::graphics::common::ExtendableType& compression);
+bool isStandardInterlaced(
+ const aidl::android::hardware::graphics::common::ExtendableType& interlaced);
+bool isStandardChromaSiting(
+ const aidl::android::hardware::graphics::common::ExtendableType& chromaSiting);
+bool isStandardPlaneLayoutComponentType(
+ const aidl::android::hardware::graphics::common::ExtendableType& planeLayoutComponentType);
+
+aidl::android::hardware::graphics::common::StandardMetadataType getStandardMetadataTypeValue(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType);
+aidl::android::hardware::graphics::common::Compression getStandardCompressionValue(
+ const aidl::android::hardware::graphics::common::ExtendableType& compression);
+aidl::android::hardware::graphics::common::Interlaced getStandardInterlacedValue(
+ const aidl::android::hardware::graphics::common::ExtendableType& interlaced);
+aidl::android::hardware::graphics::common::ChromaSiting getStandardChromaSitingValue(
+ const aidl::android::hardware::graphics::common::ExtendableType& chromaSiting);
+aidl::android::hardware::graphics::common::PlaneLayoutComponentType
+getStandardPlaneLayoutComponentTypeValue(
+ const aidl::android::hardware::graphics::common::ExtendableType& planeLayoutComponentType);
+
+/**
+ * The functions below return string representations of ExtendableTypes
+ */
+std::string getCompressionName(
+ const aidl::android::hardware::graphics::common::ExtendableType& compression);
+std::string getInterlacedName(
+ const aidl::android::hardware::graphics::common::ExtendableType& interlaced);
+std::string getChromaSitingName(
+ const aidl::android::hardware::graphics::common::ExtendableType& chromaSiting);
+std::string getPlaneLayoutComponentTypeName(
+ const aidl::android::hardware::graphics::common::ExtendableType& planeLayoutComponentType);
+
} // namespace gralloc4
} // namespace android
diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h
index abe1e3f..25ce1ca 100644
--- a/libs/gui/include/gui/IGraphicBufferProducer.h
+++ b/libs/gui/include/gui/IGraphicBufferProducer.h
@@ -286,36 +286,6 @@
virtual status_t attachBuffer(int* outSlot,
const sp<GraphicBuffer>& buffer) = 0;
- // queueBuffer indicates that the client has finished filling in the
- // contents of the buffer associated with slot and transfers ownership of
- // that slot back to the server.
- //
- // It is not valid to call queueBuffer on a slot that is not owned
- // by the client or one for which a buffer associated via requestBuffer
- // (an attempt to do so will fail with a return value of BAD_VALUE).
- //
- // In addition, the input must be described by the client (as documented
- // below). Any other properties (zero point, etc)
- // are client-dependent, and should be documented by the client.
- //
- // The slot must be in the range of [0, NUM_BUFFER_SLOTS).
- //
- // Upon success, the output will be filled with meaningful values
- // (refer to the documentation below).
- //
- // Return of a value other than NO_ERROR means an error has occurred:
- // * NO_INIT - the buffer queue has been abandoned or the producer is not
- // connected.
- // * BAD_VALUE - one of the below conditions occurred:
- // * fence was NULL
- // * scaling mode was unknown
- // * both in async mode and buffer count was less than the
- // max numbers of buffers that can be allocated at once
- // * slot index was out of range (see above).
- // * the slot was not in the dequeued state
- // * the slot was enqueued without requesting a buffer
- // * crop rect is out of bounds of the buffer dimensions
-
struct QueueBufferInput : public Flattenable<QueueBufferInput> {
friend class Flattenable<QueueBufferInput>;
explicit inline QueueBufferInput(const Parcel& parcel);
@@ -415,6 +385,35 @@
int maxBufferCount{0};
};
+ // queueBuffer indicates that the client has finished filling in the
+ // contents of the buffer associated with slot and transfers ownership of
+ // that slot back to the server.
+ //
+ // It is not valid to call queueBuffer on a slot that is not owned
+ // by the client or one for which a buffer associated via requestBuffer
+ // (an attempt to do so will fail with a return value of BAD_VALUE).
+ //
+ // In addition, the input must be described by the client (as documented
+ // below). Any other properties (zero point, etc)
+ // are client-dependent, and should be documented by the client.
+ //
+ // The slot must be in the range of [0, NUM_BUFFER_SLOTS).
+ //
+ // Upon success, the output will be filled with meaningful values
+ // (refer to the documentation below).
+ //
+ // Return of a value other than NO_ERROR means an error has occurred:
+ // * NO_INIT - the buffer queue has been abandoned or the producer is not
+ // connected.
+ // * BAD_VALUE - one of the below conditions occurred:
+ // * fence was NULL
+ // * scaling mode was unknown
+ // * both in async mode and buffer count was less than the
+ // max numbers of buffers that can be allocated at once
+ // * slot index was out of range (see above).
+ // * the slot was not in the dequeued state
+ // * the slot was enqueued without requesting a buffer
+ // * crop rect is out of bounds of the buffer dimensions
virtual status_t queueBuffer(int slot, const QueueBufferInput& input,
QueueBufferOutput* output) = 0;
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 3775e2b..124bda2 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -89,14 +89,19 @@
"android.hardware.graphics.mapper@4.0",
"libbase",
"libcutils",
+ "libgralloctypes",
"libhidlbase",
"libsync",
"libutils",
"liblog",
+ "vintf-graphics-common-ndk_platform",
],
export_shared_lib_headers: [
"android.hardware.graphics.common@1.2",
+ "android.hardware.graphics.mapper@4.0",
+ "libgralloctypes",
+ "vintf-graphics-common-ndk_platform",
],
static_libs: [
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
index 0e23ddf..040a62b 100644
--- a/libs/ui/Gralloc2.cpp
+++ b/libs/ui/Gralloc2.cpp
@@ -351,12 +351,6 @@
return releaseFence;
}
-status_t Gralloc2Mapper::isSupported(uint32_t /*width*/, uint32_t /*height*/,
- android::PixelFormat /*format*/, uint32_t /*layerCount*/,
- uint64_t /*usage*/, bool* /*outSupported*/) const {
- return INVALID_OPERATION;
-}
-
Gralloc2Allocator::Gralloc2Allocator(const Gralloc2Mapper& mapper) : mMapper(mapper) {
mAllocator = IAllocator::getService();
if (mAllocator == nullptr) {
@@ -369,7 +363,7 @@
return mAllocator != nullptr;
}
-std::string Gralloc2Allocator::dumpDebugInfo() const {
+std::string Gralloc2Allocator::dumpDebugInfo(bool /*less*/) const {
std::string debugInfo;
mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
@@ -379,10 +373,10 @@
return debugInfo;
}
-status_t Gralloc2Allocator::allocate(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
- uint32_t* outStride, buffer_handle_t* outBufferHandles,
- bool importBuffers) const {
+status_t Gralloc2Allocator::allocate(std::string /*requestorName*/, uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount, uint64_t usage,
+ uint32_t bufferCount, uint32_t* outStride,
+ buffer_handle_t* outBufferHandles, bool importBuffers) const {
IMapper::BufferDescriptorInfo descriptorInfo = {};
descriptorInfo.width = width;
descriptorInfo.height = height;
diff --git a/libs/ui/Gralloc3.cpp b/libs/ui/Gralloc3.cpp
index e189281..882674f 100644
--- a/libs/ui/Gralloc3.cpp
+++ b/libs/ui/Gralloc3.cpp
@@ -352,7 +352,7 @@
return mAllocator != nullptr;
}
-std::string Gralloc3Allocator::dumpDebugInfo() const {
+std::string Gralloc3Allocator::dumpDebugInfo(bool /*less*/) const {
std::string debugInfo;
mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
@@ -360,10 +360,10 @@
return debugInfo;
}
-status_t Gralloc3Allocator::allocate(uint32_t width, uint32_t height, android::PixelFormat format,
- uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
- uint32_t* outStride, buffer_handle_t* outBufferHandles,
- bool importBuffers) const {
+status_t Gralloc3Allocator::allocate(std::string /*requestorName*/, uint32_t width, uint32_t height,
+ android::PixelFormat format, uint32_t layerCount,
+ uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
+ buffer_handle_t* outBufferHandles, bool importBuffers) const {
IMapper::BufferDescriptorInfo descriptorInfo;
sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index afe26b7..2c897cf 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -27,11 +27,20 @@
#include <sync/sync.h>
#pragma clang diagnostic pop
+using aidl::android::hardware::graphics::common::ExtendableType;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using aidl::android::hardware::graphics::common::StandardMetadataType;
+using android::hardware::hidl_vec;
using android::hardware::graphics::allocator::V4_0::IAllocator;
using android::hardware::graphics::common::V1_2::BufferUsage;
using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
using android::hardware::graphics::mapper::V4_0::Error;
using android::hardware::graphics::mapper::V4_0::IMapper;
+using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
+using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+using MetadataTypeDescription =
+ android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
namespace android {
@@ -59,10 +68,10 @@
outRect.height = rect.height();
return outRect;
}
-static inline void sBufferDescriptorInfo(uint32_t width, uint32_t height,
- android::PixelFormat format, uint32_t layerCount,
- uint64_t usage,
+static inline void sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount, uint64_t usage,
IMapper::BufferDescriptorInfo* outDescriptorInfo) {
+ outDescriptorInfo->name = name;
outDescriptorInfo->width = width;
outDescriptorInfo->height = height;
outDescriptorInfo->layerCount = layerCount;
@@ -151,11 +160,12 @@
}
status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
- uint32_t height, android::PixelFormat format,
+ uint32_t height, PixelFormat format,
uint32_t layerCount, uint64_t usage,
uint32_t stride) const {
IMapper::BufferDescriptorInfo descriptorInfo;
- sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
+ sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount, usage,
+ &descriptorInfo);
auto buffer = const_cast<native_handle_t*>(bufferHandle);
auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
@@ -189,14 +199,36 @@
status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
int acquireFence, void** outData, int32_t* outBytesPerPixel,
int32_t* outBytesPerStride) const {
- // In Gralloc 4 we can get this info per plane. Clients should check per plane.
- if (outBytesPerPixel) {
- // TODO add support to check per plane
- *outBytesPerPixel = -1;
- }
- if (outBytesPerStride) {
- // TODO add support to check per plane
- *outBytesPerStride = -1;
+ std::vector<ui::PlaneLayout> planeLayouts;
+ status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
+
+ if (err != NO_ERROR && !planeLayouts.empty()) {
+ if (outBytesPerPixel) {
+ int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
+ for (const auto& planeLayout : planeLayouts) {
+ if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
+ bitsPerPixel = -1;
+ }
+ }
+ if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
+ *outBytesPerPixel = bitsPerPixel / 8;
+ } else {
+ *outBytesPerPixel = -1;
+ }
+ }
+ if (outBytesPerStride) {
+ int32_t bytesPerStride = planeLayouts.front().strideInBytes;
+ for (const auto& planeLayout : planeLayouts) {
+ if (bytesPerStride != planeLayout.strideInBytes) {
+ bytesPerStride = -1;
+ }
+ }
+ if (bytesPerStride >= 0) {
+ *outBytesPerStride = bytesPerStride;
+ } else {
+ *outBytesPerStride = -1;
+ }
+ }
}
auto buffer = const_cast<native_handle_t*>(bufferHandle);
@@ -234,10 +266,104 @@
return static_cast<status_t>(error);
}
-status_t Gralloc4Mapper::lock(buffer_handle_t /*bufferHandle*/, uint64_t /*usage*/,
- const Rect& /*bounds*/, int /*acquireFence*/,
- android_ycbcr* /*ycbcr*/) const {
- // TODO add lockYCbCr support
+status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
+ int acquireFence, android_ycbcr* outYcbcr) const {
+ if (!outYcbcr) {
+ return BAD_VALUE;
+ }
+
+ std::vector<ui::PlaneLayout> planeLayouts;
+ status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
+ if (error != NO_ERROR) {
+ return error;
+ }
+
+ void* data = nullptr;
+ error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
+ if (error != NO_ERROR) {
+ return error;
+ }
+
+ android_ycbcr ycbcr;
+
+ ycbcr.y = nullptr;
+ ycbcr.cb = nullptr;
+ ycbcr.cr = nullptr;
+ ycbcr.ystride = 0;
+ ycbcr.cstride = 0;
+ ycbcr.chroma_step = 0;
+
+ for (const auto& planeLayout : planeLayouts) {
+ for (const auto& planeLayoutComponent : planeLayout.components) {
+ if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
+ continue;
+ }
+ if (0 != planeLayoutComponent.offsetInBits % 8) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+
+ uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes +
+ (planeLayoutComponent.offsetInBits / 8);
+ uint64_t sampleIncrementInBytes;
+
+ auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
+ switch (type) {
+ case PlaneLayoutComponentType::Y:
+ if ((ycbcr.y != nullptr) || (planeLayoutComponent.sizeInBits != 8) ||
+ (planeLayout.sampleIncrementInBits != 8)) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+ ycbcr.y = tmpData;
+ ycbcr.ystride = planeLayout.strideInBytes;
+ break;
+
+ case PlaneLayoutComponentType::CB:
+ case PlaneLayoutComponentType::CR:
+ if (planeLayout.sampleIncrementInBits % 8 != 0) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+
+ sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
+ if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2)) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+
+ if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
+ ycbcr.cstride = planeLayout.strideInBytes;
+ ycbcr.chroma_step = sampleIncrementInBytes;
+ } else {
+ if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
+ (ycbcr.chroma_step != sampleIncrementInBytes)) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+ }
+
+ if (type == PlaneLayoutComponentType::CB) {
+ if (ycbcr.cb != nullptr) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+ ycbcr.cb = tmpData;
+ } else {
+ if (ycbcr.cr != nullptr) {
+ unlock(bufferHandle);
+ return BAD_VALUE;
+ }
+ ycbcr.cr = tmpData;
+ }
+ break;
+ default:
+ break;
+ };
+ }
+ }
+
+ *outYcbcr = ycbcr;
return static_cast<status_t>(Error::UNSUPPORTED);
}
@@ -275,11 +401,11 @@
return releaseFence;
}
-status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, android::PixelFormat format,
+status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
uint32_t layerCount, uint64_t usage,
bool* outSupported) const {
IMapper::BufferDescriptorInfo descriptorInfo;
- sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
+ sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage, &descriptorInfo);
Error error;
auto ret = mMapper->isSupported(descriptorInfo,
@@ -305,6 +431,605 @@
return static_cast<status_t>(error);
}
+template <class T>
+status_t Gralloc4Mapper::get(buffer_handle_t bufferHandle, const MetadataType& metadataType,
+ DecodeFunction<T> decodeFunction, T* outMetadata) const {
+ if (!outMetadata) {
+ return BAD_VALUE;
+ }
+
+ hidl_vec<uint8_t> vec;
+ Error error;
+ auto ret = mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
+ [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
+ error = tmpError;
+ vec = tmpVec;
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+
+ if (error != Error::NONE) {
+ ALOGE("get(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
+ metadataType.value, error);
+ return static_cast<status_t>(error);
+ }
+
+ return decodeFunction(vec, outMetadata);
+}
+
+status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
+ return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
+ outBufferId);
+}
+
+status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
+ return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
+}
+
+status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
+ return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
+}
+
+status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
+ return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
+}
+
+status_t Gralloc4Mapper::getLayerCount(buffer_handle_t bufferHandle,
+ uint64_t* outLayerCount) const {
+ return get(bufferHandle, gralloc4::MetadataType_LayerCount, gralloc4::decodeLayerCount,
+ outLayerCount);
+}
+
+status_t Gralloc4Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
+ ui::PixelFormat* outPixelFormatRequested) const {
+ return get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested,
+ gralloc4::decodePixelFormatRequested, outPixelFormatRequested);
+}
+
+status_t Gralloc4Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
+ uint32_t* outPixelFormatFourCC) const {
+ return get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC,
+ gralloc4::decodePixelFormatFourCC, outPixelFormatFourCC);
+}
+
+status_t Gralloc4Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
+ uint64_t* outPixelFormatModifier) const {
+ return get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier,
+ gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
+}
+
+status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
+ return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
+}
+
+status_t Gralloc4Mapper::getAllocationSize(buffer_handle_t bufferHandle,
+ uint64_t* outAllocationSize) const {
+ return get(bufferHandle, gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
+ outAllocationSize);
+}
+
+status_t Gralloc4Mapper::getProtectedContent(buffer_handle_t bufferHandle,
+ uint64_t* outProtectedContent) const {
+ return get(bufferHandle, gralloc4::MetadataType_ProtectedContent,
+ gralloc4::decodeProtectedContent, outProtectedContent);
+}
+
+status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
+ ExtendableType* outCompression) const {
+ return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
+ outCompression);
+}
+
+status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
+ ui::Compression* outCompression) const {
+ if (!outCompression) {
+ return BAD_VALUE;
+ }
+ ExtendableType compression;
+ status_t error = getCompression(bufferHandle, &compression);
+ if (error) {
+ return error;
+ }
+ if (!gralloc4::isStandardCompression(compression)) {
+ return BAD_TYPE;
+ }
+ *outCompression = gralloc4::getStandardCompressionValue(compression);
+ return NO_ERROR;
+}
+
+status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
+ ExtendableType* outInterlaced) const {
+ return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
+ outInterlaced);
+}
+
+status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
+ ui::Interlaced* outInterlaced) const {
+ if (!outInterlaced) {
+ return BAD_VALUE;
+ }
+ ExtendableType interlaced;
+ status_t error = getInterlaced(bufferHandle, &interlaced);
+ if (error) {
+ return error;
+ }
+ if (!gralloc4::isStandardInterlaced(interlaced)) {
+ return BAD_TYPE;
+ }
+ *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
+ return NO_ERROR;
+}
+
+status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
+ ExtendableType* outChromaSiting) const {
+ return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
+ outChromaSiting);
+}
+
+status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
+ ui::ChromaSiting* outChromaSiting) const {
+ if (!outChromaSiting) {
+ return BAD_VALUE;
+ }
+ ExtendableType chromaSiting;
+ status_t error = getChromaSiting(bufferHandle, &chromaSiting);
+ if (error) {
+ return error;
+ }
+ if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
+ return BAD_TYPE;
+ }
+ *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
+ return NO_ERROR;
+}
+
+status_t Gralloc4Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
+ std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
+ return get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, gralloc4::decodePlaneLayouts,
+ outPlaneLayouts);
+}
+
+status_t Gralloc4Mapper::getDataspace(buffer_handle_t bufferHandle,
+ ui::Dataspace* outDataspace) const {
+ if (!outDataspace) {
+ return BAD_VALUE;
+ }
+ aidl::android::hardware::graphics::common::Dataspace dataspace;
+ status_t error = get(bufferHandle, gralloc4::MetadataType_Dataspace, gralloc4::decodeDataspace,
+ &dataspace);
+ if (error) {
+ return error;
+ }
+
+ // Gralloc4 uses stable AIDL dataspace but the rest of the system still uses HIDL dataspace
+ *outDataspace = static_cast<ui::Dataspace>(dataspace);
+ return NO_ERROR;
+}
+
+status_t Gralloc4Mapper::getBlendMode(buffer_handle_t bufferHandle,
+ ui::BlendMode* outBlendMode) const {
+ return get(bufferHandle, gralloc4::MetadataType_BlendMode, gralloc4::decodeBlendMode,
+ outBlendMode);
+}
+
+template <class T>
+status_t Gralloc4Mapper::getDefault(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ const MetadataType& metadataType,
+ DecodeFunction<T> decodeFunction, T* outMetadata) const {
+ if (!outMetadata) {
+ return BAD_VALUE;
+ }
+
+ IMapper::BufferDescriptorInfo descriptorInfo;
+ sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage, &descriptorInfo);
+
+ hidl_vec<uint8_t> vec;
+ Error error;
+ auto ret = mMapper->getFromBufferDescriptorInfo(descriptorInfo, metadataType,
+ [&](const auto& tmpError,
+ const hidl_vec<uint8_t>& tmpVec) {
+ error = tmpError;
+ vec = tmpVec;
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+
+ if (error != Error::NONE) {
+ ALOGE("getDefault(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
+ metadataType.value, error);
+ return static_cast<status_t>(error);
+ }
+
+ return decodeFunction(vec, outMetadata);
+}
+
+status_t Gralloc4Mapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint32_t* outPixelFormatFourCC) const {
+ return getDefault(width, height, format, layerCount, usage,
+ gralloc4::MetadataType_PixelFormatFourCC, gralloc4::decodePixelFormatFourCC,
+ outPixelFormatFourCC);
+}
+
+status_t Gralloc4Mapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint64_t* outPixelFormatModifier) const {
+ return getDefault(width, height, format, layerCount, usage,
+ gralloc4::MetadataType_PixelFormatModifier,
+ gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
+}
+
+status_t Gralloc4Mapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint64_t* outAllocationSize) const {
+ return getDefault(width, height, format, layerCount, usage,
+ gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
+ outAllocationSize);
+}
+
+status_t Gralloc4Mapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint64_t* outProtectedContent) const {
+ return getDefault(width, height, format, layerCount, usage,
+ gralloc4::MetadataType_ProtectedContent, gralloc4::decodeProtectedContent,
+ outProtectedContent);
+}
+
+status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ExtendableType* outCompression) const {
+ return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Compression,
+ gralloc4::decodeCompression, outCompression);
+}
+
+status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::Compression* outCompression) const {
+ if (!outCompression) {
+ return BAD_VALUE;
+ }
+ ExtendableType compression;
+ status_t error = getDefaultCompression(width, height, format, layerCount, usage, &compression);
+ if (error) {
+ return error;
+ }
+ if (!gralloc4::isStandardCompression(compression)) {
+ return BAD_TYPE;
+ }
+ *outCompression = gralloc4::getStandardCompressionValue(compression);
+ return NO_ERROR;
+}
+
+status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ExtendableType* outInterlaced) const {
+ return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Interlaced,
+ gralloc4::decodeInterlaced, outInterlaced);
+}
+
+status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::Interlaced* outInterlaced) const {
+ if (!outInterlaced) {
+ return BAD_VALUE;
+ }
+ ExtendableType interlaced;
+ status_t error = getDefaultInterlaced(width, height, format, layerCount, usage, &interlaced);
+ if (error) {
+ return error;
+ }
+ if (!gralloc4::isStandardInterlaced(interlaced)) {
+ return BAD_TYPE;
+ }
+ *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
+ return NO_ERROR;
+}
+
+status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ExtendableType* outChromaSiting) const {
+ return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_ChromaSiting,
+ gralloc4::decodeChromaSiting, outChromaSiting);
+}
+
+status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::ChromaSiting* outChromaSiting) const {
+ if (!outChromaSiting) {
+ return BAD_VALUE;
+ }
+ ExtendableType chromaSiting;
+ status_t error =
+ getDefaultChromaSiting(width, height, format, layerCount, usage, &chromaSiting);
+ if (error) {
+ return error;
+ }
+ if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
+ return BAD_TYPE;
+ }
+ *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
+ return NO_ERROR;
+}
+
+status_t Gralloc4Mapper::getDefaultPlaneLayouts(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
+ std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
+ return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_PlaneLayouts,
+ gralloc4::decodePlaneLayouts, outPlaneLayouts);
+}
+
+std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
+ hidl_vec<MetadataTypeDescription> descriptions;
+ Error error;
+ auto ret = mMapper->listSupportedMetadataTypes(
+ [&](const auto& tmpError, const auto& tmpDescriptions) {
+ error = tmpError;
+ descriptions = tmpDescriptions;
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+
+ if (error != Error::NONE) {
+ ALOGE("listSupportedMetadataType() failed with %d", error);
+ return {};
+ }
+
+ return static_cast<std::vector<MetadataTypeDescription>>(descriptions);
+}
+
+template <class T>
+status_t Gralloc4Mapper::metadataDumpHelper(const BufferDump& bufferDump,
+ StandardMetadataType metadataType,
+ DecodeFunction<T> decodeFunction, T* outT) const {
+ const auto& metadataDump = bufferDump.metadataDump;
+
+ auto itr =
+ std::find_if(metadataDump.begin(), metadataDump.end(),
+ [&](const MetadataDump& tmpMetadataDump) {
+ if (!gralloc4::isStandardMetadataType(tmpMetadataDump.metadataType)) {
+ return false;
+ }
+ return metadataType ==
+ gralloc4::getStandardMetadataTypeValue(
+ tmpMetadataDump.metadataType);
+ });
+ if (itr == metadataDump.end()) {
+ return BAD_VALUE;
+ }
+
+ return decodeFunction(itr->metadata, outT);
+}
+
+status_t Gralloc4Mapper::bufferDumpHelper(const BufferDump& bufferDump, std::ostringstream* outDump,
+ uint64_t* outAllocationSize, bool less) const {
+ uint64_t bufferId;
+ std::string name;
+ uint64_t width;
+ uint64_t height;
+ uint64_t layerCount;
+ ui::PixelFormat pixelFormatRequested;
+ uint32_t pixelFormatFourCC;
+ uint64_t pixelFormatModifier;
+ uint64_t usage;
+ uint64_t allocationSize;
+ uint64_t protectedContent;
+ ExtendableType compression;
+ ExtendableType interlaced;
+ ExtendableType chromaSiting;
+ std::vector<ui::PlaneLayout> planeLayouts;
+
+ status_t error = metadataDumpHelper(bufferDump, StandardMetadataType::BUFFER_ID,
+ gralloc4::decodeBufferId, &bufferId);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::NAME, gralloc4::decodeName, &name);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::WIDTH, gralloc4::decodeWidth,
+ &width);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::HEIGHT, gralloc4::decodeHeight,
+ &height);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::LAYER_COUNT,
+ gralloc4::decodeLayerCount, &layerCount);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
+ gralloc4::decodePixelFormatRequested, &pixelFormatRequested);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_FOURCC,
+ gralloc4::decodePixelFormatFourCC, &pixelFormatFourCC);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_MODIFIER,
+ gralloc4::decodePixelFormatModifier, &pixelFormatModifier);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::USAGE, gralloc4::decodeUsage,
+ &usage);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::ALLOCATION_SIZE,
+ gralloc4::decodeAllocationSize, &allocationSize);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::PROTECTED_CONTENT,
+ gralloc4::decodeProtectedContent, &protectedContent);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::COMPRESSION,
+ gralloc4::decodeCompression, &compression);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::INTERLACED,
+ gralloc4::decodeInterlaced, &interlaced);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::CHROMA_SITING,
+ gralloc4::decodeChromaSiting, &chromaSiting);
+ if (error != NO_ERROR) {
+ return error;
+ }
+ error = metadataDumpHelper(bufferDump, StandardMetadataType::PLANE_LAYOUTS,
+ gralloc4::decodePlaneLayouts, &planeLayouts);
+ if (error != NO_ERROR) {
+ return error;
+ }
+
+ if (outAllocationSize) {
+ *outAllocationSize = allocationSize;
+ }
+ double allocationSizeKiB = static_cast<double>(allocationSize) / 1024;
+
+ *outDump << "+ name:" << name << ", id:" << bufferId << ", size:" << allocationSizeKiB
+ << "KiB, w/h:" << width << "x" << height << ", usage: 0x" << std::hex << usage
+ << std::dec << ", req fmt:" << static_cast<int32_t>(pixelFormatRequested)
+ << ", fourcc/mod:" << pixelFormatFourCC << "/" << pixelFormatModifier
+ << ", compressed: ";
+
+ if (less) {
+ bool isCompressed = !gralloc4::isStandardCompression(compression) ||
+ (gralloc4::getStandardCompressionValue(compression) != ui::Compression::NONE);
+ *outDump << std::boolalpha << isCompressed << "\n";
+ } else {
+ *outDump << gralloc4::getCompressionName(compression) << "\n";
+ }
+
+ bool firstPlane = true;
+ for (const auto& planeLayout : planeLayouts) {
+ if (firstPlane) {
+ firstPlane = false;
+ *outDump << "\tplanes: ";
+ } else {
+ *outDump << "\t ";
+ }
+
+ for (size_t i = 0; i < planeLayout.components.size(); i++) {
+ const auto& planeLayoutComponent = planeLayout.components[i];
+ *outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
+ if (i < planeLayout.components.size() - 1) {
+ *outDump << "/";
+ } else {
+ *outDump << ":\t";
+ }
+ }
+ *outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
+ << ", stride:" << planeLayout.strideInBytes
+ << " bytes, size:" << planeLayout.totalSizeInBytes;
+ if (!less) {
+ *outDump << ", inc:" << planeLayout.sampleIncrementInBits
+ << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
+ << planeLayout.verticalSubsampling;
+ }
+ *outDump << "\n";
+ }
+
+ if (!less) {
+ *outDump << "\tlayer cnt: " << layerCount << ", protected content: " << protectedContent
+ << ", interlaced: " << gralloc4::getInterlacedName(interlaced)
+ << ", chroma siting:" << gralloc4::getChromaSitingName(chromaSiting) << "\n";
+ }
+
+ return NO_ERROR;
+}
+
+std::string Gralloc4Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ BufferDump bufferDump;
+ Error error;
+ auto ret = mMapper->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
+ error = tmpError;
+ bufferDump = tmpBufferDump;
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+
+ if (error != Error::NONE) {
+ ALOGE("dumpBuffer() failed with %d", error);
+ return "";
+ }
+
+ std::ostringstream stream;
+ stream.precision(2);
+
+ status_t err = bufferDumpHelper(bufferDump, &stream, nullptr, less);
+ if (err != NO_ERROR) {
+ ALOGE("bufferDumpHelper() failed with %d", err);
+ return "";
+ }
+
+ return stream.str();
+}
+
+std::string Gralloc4Mapper::dumpBuffers(bool less) const {
+ hidl_vec<BufferDump> bufferDumps;
+ Error error;
+ auto ret = mMapper->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
+ error = tmpError;
+ bufferDumps = tmpBufferDump;
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+
+ if (error != Error::NONE) {
+ ALOGE("dumpBuffer() failed with %d", error);
+ return "";
+ }
+
+ uint64_t totalAllocationSize = 0;
+ std::ostringstream stream;
+ stream.precision(2);
+
+ stream << "Imported gralloc buffers:\n";
+
+ for (const auto& bufferDump : bufferDumps) {
+ uint64_t allocationSize = 0;
+ status_t err = bufferDumpHelper(bufferDump, &stream, &allocationSize, less);
+ if (err != NO_ERROR) {
+ ALOGE("bufferDumpHelper() failed with %d", err);
+ return "";
+ }
+ totalAllocationSize += allocationSize;
+ }
+
+ double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
+ stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
+ return stream.str();
+}
+
Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
mAllocator = IAllocator::getService();
if (mAllocator == nullptr) {
@@ -317,20 +1042,16 @@
return mAllocator != nullptr;
}
-std::string Gralloc4Allocator::dumpDebugInfo() const {
- std::string debugInfo;
-
- mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
-
- return debugInfo;
+std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
+ return mMapper.dumpBuffers(less);
}
-status_t Gralloc4Allocator::allocate(uint32_t width, uint32_t height, android::PixelFormat format,
- uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
- uint32_t* outStride, buffer_handle_t* outBufferHandles,
- bool importBuffers) const {
+status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
+ android::PixelFormat format, uint32_t layerCount,
+ uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
+ buffer_handle_t* outBufferHandles, bool importBuffers) const {
IMapper::BufferDescriptorInfo descriptorInfo;
- sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
+ sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage, &descriptorInfo);
BufferDescriptor descriptor;
status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 3a90a98..943d13e 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -78,11 +78,11 @@
return total;
}
-void GraphicBufferAllocator::dump(std::string& result) const {
+void GraphicBufferAllocator::dump(std::string& result, bool less) const {
Mutex::Autolock _l(sLock);
KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
uint64_t total = 0;
- result.append("Allocated buffers:\n");
+ result.append("GraphicBufferAllocator buffers:\n");
const size_t c = list.size();
for (size_t i=0 ; i<c ; i++) {
const alloc_rec_t& rec(list.valueAt(i));
@@ -99,15 +99,15 @@
}
total += rec.size;
}
- StringAppendF(&result, "Total allocated (estimate): %.2f KB\n", static_cast<double>(total) / 1024.0);
+ StringAppendF(&result, "Total allocated by GraphicBufferAllocator (estimate): %.2f KB\n",
+ static_cast<double>(total) / 1024.0);
- result.append(mAllocator->dumpDebugInfo());
+ result.append(mAllocator->dumpDebugInfo(less));
}
-void GraphicBufferAllocator::dumpToSystemLog()
-{
+void GraphicBufferAllocator::dumpToSystemLog(bool less) {
std::string s;
- GraphicBufferAllocator::getInstance().dump(s);
+ GraphicBufferAllocator::getInstance().dump(s, less);
ALOGD("%s", s.c_str());
}
@@ -137,8 +137,8 @@
// TODO(b/72323293, b/72703005): Remove these invalid bits from callers
usage &= ~static_cast<uint64_t>((1 << 10) | (1 << 13));
- status_t error = mAllocator->allocate(width, height, format, layerCount, usage, 1, stride,
- handle, importBuffer);
+ status_t error = mAllocator->allocate(requestorName, width, height, format, layerCount, usage,
+ 1, stride, handle, importBuffer);
if (error != NO_ERROR) {
ALOGE("Failed to allocate (%u x %u) layerCount %u format %d "
"usage %" PRIx64 ": %d",
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 4d087d1..8540fd3 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -71,6 +71,17 @@
LOG_ALWAYS_FATAL("gralloc-mapper is missing");
}
+void GraphicBufferMapper::dumpBuffer(buffer_handle_t bufferHandle, std::string& result,
+ bool less) const {
+ result.append(mMapper->dumpBuffer(bufferHandle, less));
+}
+
+void GraphicBufferMapper::dumpBufferToSystemLog(buffer_handle_t bufferHandle, bool less) {
+ std::string s;
+ GraphicBufferMapper::getInstance().dumpBuffer(bufferHandle, s, less);
+ ALOGD("%s", s.c_str());
+}
+
status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle,
uint32_t width, uint32_t height, uint32_t layerCount,
PixelFormat format, uint64_t usage, uint32_t stride,
@@ -177,5 +188,182 @@
uint64_t usage, bool* outSupported) {
return mMapper->isSupported(width, height, format, layerCount, usage, outSupported);
}
+
+status_t GraphicBufferMapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) {
+ return mMapper->getBufferId(bufferHandle, outBufferId);
+}
+
+status_t GraphicBufferMapper::getName(buffer_handle_t bufferHandle, std::string* outName) {
+ return mMapper->getName(bufferHandle, outName);
+}
+
+status_t GraphicBufferMapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) {
+ return mMapper->getWidth(bufferHandle, outWidth);
+}
+
+status_t GraphicBufferMapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) {
+ return mMapper->getHeight(bufferHandle, outHeight);
+}
+
+status_t GraphicBufferMapper::getLayerCount(buffer_handle_t bufferHandle, uint64_t* outLayerCount) {
+ return mMapper->getLayerCount(bufferHandle, outLayerCount);
+}
+
+status_t GraphicBufferMapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
+ ui::PixelFormat* outPixelFormatRequested) {
+ return mMapper->getPixelFormatRequested(bufferHandle, outPixelFormatRequested);
+}
+
+status_t GraphicBufferMapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
+ uint32_t* outPixelFormatFourCC) {
+ return mMapper->getPixelFormatFourCC(bufferHandle, outPixelFormatFourCC);
+}
+
+status_t GraphicBufferMapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
+ uint64_t* outPixelFormatModifier) {
+ return mMapper->getPixelFormatModifier(bufferHandle, outPixelFormatModifier);
+}
+
+status_t GraphicBufferMapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) {
+ return mMapper->getUsage(bufferHandle, outUsage);
+}
+
+status_t GraphicBufferMapper::getAllocationSize(buffer_handle_t bufferHandle,
+ uint64_t* outAllocationSize) {
+ return mMapper->getAllocationSize(bufferHandle, outAllocationSize);
+}
+
+status_t GraphicBufferMapper::getProtectedContent(buffer_handle_t bufferHandle,
+ uint64_t* outProtectedContent) {
+ return mMapper->getProtectedContent(bufferHandle, outProtectedContent);
+}
+
+status_t GraphicBufferMapper::getCompression(
+ buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType* outCompression) {
+ return mMapper->getCompression(bufferHandle, outCompression);
+}
+
+status_t GraphicBufferMapper::getCompression(buffer_handle_t bufferHandle,
+ ui::Compression* outCompression) {
+ return mMapper->getCompression(bufferHandle, outCompression);
+}
+
+status_t GraphicBufferMapper::getInterlaced(
+ buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType* outInterlaced) {
+ return mMapper->getInterlaced(bufferHandle, outInterlaced);
+}
+
+status_t GraphicBufferMapper::getInterlaced(buffer_handle_t bufferHandle,
+ ui::Interlaced* outInterlaced) {
+ return mMapper->getInterlaced(bufferHandle, outInterlaced);
+}
+
+status_t GraphicBufferMapper::getChromaSiting(
+ buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType* outChromaSiting) {
+ return mMapper->getChromaSiting(bufferHandle, outChromaSiting);
+}
+
+status_t GraphicBufferMapper::getChromaSiting(buffer_handle_t bufferHandle,
+ ui::ChromaSiting* outChromaSiting) {
+ return mMapper->getChromaSiting(bufferHandle, outChromaSiting);
+}
+
+status_t GraphicBufferMapper::getPlaneLayouts(buffer_handle_t bufferHandle,
+ std::vector<ui::PlaneLayout>* outPlaneLayouts) {
+ return mMapper->getPlaneLayouts(bufferHandle, outPlaneLayouts);
+}
+
+status_t GraphicBufferMapper::getDataspace(buffer_handle_t bufferHandle,
+ ui::Dataspace* outDataspace) {
+ return mMapper->getDataspace(bufferHandle, outDataspace);
+}
+
+status_t GraphicBufferMapper::getBlendMode(buffer_handle_t bufferHandle,
+ ui::BlendMode* outBlendMode) {
+ return mMapper->getBlendMode(bufferHandle, outBlendMode);
+}
+
+status_t GraphicBufferMapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint32_t* outPixelFormatFourCC) {
+ return mMapper->getDefaultPixelFormatFourCC(width, height, format, layerCount, usage,
+ outPixelFormatFourCC);
+}
+
+status_t GraphicBufferMapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint64_t* outPixelFormatModifier) {
+ return mMapper->getDefaultPixelFormatModifier(width, height, format, layerCount, usage,
+ outPixelFormatModifier);
+}
+
+status_t GraphicBufferMapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint64_t* outAllocationSize) {
+ return mMapper->getDefaultAllocationSize(width, height, format, layerCount, usage,
+ outAllocationSize);
+}
+
+status_t GraphicBufferMapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ uint64_t* outProtectedContent) {
+ return mMapper->getDefaultProtectedContent(width, height, format, layerCount, usage,
+ outProtectedContent);
+}
+
+status_t GraphicBufferMapper::getDefaultCompression(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType* outCompression) {
+ return mMapper->getDefaultCompression(width, height, format, layerCount, usage, outCompression);
+}
+
+status_t GraphicBufferMapper::getDefaultCompression(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ ui::Compression* outCompression) {
+ return mMapper->getDefaultCompression(width, height, format, layerCount, usage, outCompression);
+}
+
+status_t GraphicBufferMapper::getDefaultInterlaced(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType* outInterlaced) {
+ return mMapper->getDefaultInterlaced(width, height, format, layerCount, usage, outInterlaced);
+}
+
+status_t GraphicBufferMapper::getDefaultInterlaced(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage, ui::Interlaced* outInterlaced) {
+ return mMapper->getDefaultInterlaced(width, height, format, layerCount, usage, outInterlaced);
+}
+
+status_t GraphicBufferMapper::getDefaultChromaSiting(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType* outChromaSiting) {
+ return mMapper->getDefaultChromaSiting(width, height, format, layerCount, usage,
+ outChromaSiting);
+}
+
+status_t GraphicBufferMapper::getDefaultChromaSiting(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ ui::ChromaSiting* outChromaSiting) {
+ return mMapper->getDefaultChromaSiting(width, height, format, layerCount, usage,
+ outChromaSiting);
+}
+
+status_t GraphicBufferMapper::getDefaultPlaneLayouts(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
+ std::vector<ui::PlaneLayout>* outPlaneLayouts) {
+ return mMapper->getDefaultPlaneLayouts(width, height, format, layerCount, usage,
+ outPlaneLayouts);
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/libs/ui/include/ui/Gralloc.h b/libs/ui/include/ui/Gralloc.h
index c28f7a5..fcd959c 100644
--- a/libs/ui/include/ui/Gralloc.h
+++ b/libs/ui/include/ui/Gralloc.h
@@ -17,13 +17,15 @@
#ifndef ANDROID_UI_GRALLOC_H
#define ANDROID_UI_GRALLOC_H
-#include <string>
-
+#include <gralloctypes/Gralloc4.h>
#include <hidl/HidlSupport.h>
+#include <ui/GraphicTypes.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <utils/StrongPointer.h>
+#include <string>
+
namespace android {
// A wrapper to IMapper
@@ -33,6 +35,10 @@
virtual bool isLoaded() const = 0;
+ virtual std::string dumpBuffer(buffer_handle_t /*bufferHandle*/, bool /*less*/) const {
+ return "";
+ }
+
virtual status_t createDescriptor(void* bufferDescriptorInfo,
void* outBufferDescriptor) const = 0;
@@ -74,8 +80,163 @@
// allocated if resources are available. If false, a buffer with the given specifications will
// never successfully allocate on this device. Note that this function is not guaranteed to be
// supported on all devices, in which case a status_t of INVALID_OPERATION will be returned.
- virtual status_t isSupported(uint32_t width, uint32_t height, android::PixelFormat format,
- uint32_t layerCount, uint64_t usage, bool* outSupported) const = 0;
+ virtual status_t isSupported(uint32_t /*width*/, uint32_t /*height*/,
+ android::PixelFormat /*format*/, uint32_t /*layerCount*/,
+ uint64_t /*usage*/, bool* /*outSupported*/) const {
+ return INVALID_OPERATION;
+ }
+
+ virtual status_t getBufferId(buffer_handle_t /*bufferHandle*/,
+ uint64_t* /*outBufferId*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getName(buffer_handle_t /*bufferHandle*/, std::string* /*outName*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getWidth(buffer_handle_t /*bufferHandle*/, uint64_t* /*outWidth*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getHeight(buffer_handle_t /*bufferHandle*/, uint64_t* /*outHeight*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getLayerCount(buffer_handle_t /*bufferHandle*/,
+ uint64_t* /*outLayerCount*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getPixelFormatRequested(buffer_handle_t /*bufferHandle*/,
+ ui::PixelFormat* /*outPixelFormatRequested*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getPixelFormatFourCC(buffer_handle_t /*bufferHandle*/,
+ uint32_t* /*outPixelFormatFourCC*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getPixelFormatModifier(buffer_handle_t /*bufferHandle*/,
+ uint64_t* /*outPixelFormatModifier*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getUsage(buffer_handle_t /*bufferHandle*/, uint64_t* /*outUsage*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getAllocationSize(buffer_handle_t /*bufferHandle*/,
+ uint64_t* /*outAllocationSize*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getProtectedContent(buffer_handle_t /*bufferHandle*/,
+ uint64_t* /*outProtectedContent*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getCompression(
+ buffer_handle_t /*bufferHandle*/,
+ aidl::android::hardware::graphics::common::ExtendableType* /*outCompression*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getCompression(buffer_handle_t /*bufferHandle*/,
+ ui::Compression* /*outCompression*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getInterlaced(
+ buffer_handle_t /*bufferHandle*/,
+ aidl::android::hardware::graphics::common::ExtendableType* /*outInterlaced*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getInterlaced(buffer_handle_t /*bufferHandle*/,
+ ui::Interlaced* /*outInterlaced*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getChromaSiting(
+ buffer_handle_t /*bufferHandle*/,
+ aidl::android::hardware::graphics::common::ExtendableType* /*outChromaSiting*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getChromaSiting(buffer_handle_t /*bufferHandle*/,
+ ui::ChromaSiting* /*outChromaSiting*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getPlaneLayouts(buffer_handle_t /*bufferHandle*/,
+ std::vector<ui::PlaneLayout>* /*outPlaneLayouts*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDataspace(buffer_handle_t /*bufferHandle*/,
+ ui::Dataspace* /*outDataspace*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getBlendMode(buffer_handle_t /*bufferHandle*/,
+ ui::BlendMode* /*outBlendMode*/) const {
+ return INVALID_OPERATION;
+ }
+
+ virtual status_t getDefaultPixelFormatFourCC(uint32_t /*width*/, uint32_t /*height*/,
+ PixelFormat /*format*/, uint32_t /*layerCount*/,
+ uint64_t /*usage*/,
+ uint32_t* /*outPixelFormatFourCC*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultPixelFormatModifier(uint32_t /*width*/, uint32_t /*height*/,
+ PixelFormat /*format*/, uint32_t /*layerCount*/,
+ uint64_t /*usage*/,
+ uint64_t* /*outPixelFormatModifier*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultAllocationSize(uint32_t /*width*/, uint32_t /*height*/,
+ PixelFormat /*format*/, uint32_t /*layerCount*/,
+ uint64_t /*usage*/,
+ uint64_t* /*outAllocationSize*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultProtectedContent(uint32_t /*width*/, uint32_t /*height*/,
+ PixelFormat /*format*/, uint32_t /*layerCount*/,
+ uint64_t /*usage*/,
+ uint64_t* /*outProtectedContent*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultCompression(
+ uint32_t /*width*/, uint32_t /*height*/, PixelFormat /*format*/,
+ uint32_t /*layerCount*/, uint64_t /*usage*/,
+ aidl::android::hardware::graphics::common::ExtendableType* /*outCompression*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultCompression(uint32_t /*width*/, uint32_t /*height*/,
+ PixelFormat /*format*/, uint32_t /*layerCount*/,
+ uint64_t /*usage*/,
+ ui::Compression* /*outCompression*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultInterlaced(
+ uint32_t /*width*/, uint32_t /*height*/, PixelFormat /*format*/,
+ uint32_t /*layerCount*/, uint64_t /*usage*/,
+ aidl::android::hardware::graphics::common::ExtendableType* /*outInterlaced*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultInterlaced(uint32_t /*width*/, uint32_t /*height*/,
+ PixelFormat /*format*/, uint32_t /*layerCount*/,
+ uint64_t /*usage*/,
+ ui::Interlaced* /*outInterlaced*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultChromaSiting(
+ uint32_t /*width*/, uint32_t /*height*/, PixelFormat /*format*/,
+ uint32_t /*layerCount*/, uint64_t /*usage*/,
+ aidl::android::hardware::graphics::common::ExtendableType* /*outChromaSiting*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultChromaSiting(uint32_t /*width*/, uint32_t /*height*/,
+ PixelFormat /*format*/, uint32_t /*layerCount*/,
+ uint64_t /*usage*/,
+ ui::ChromaSiting* /*outChromaSiting*/) const {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getDefaultPlaneLayouts(
+ uint32_t /*width*/, uint32_t /*height*/, PixelFormat /*format*/,
+ uint32_t /*layerCount*/, uint64_t /*usage*/,
+ std::vector<ui::PlaneLayout>* /*outPlaneLayouts*/) const {
+ return INVALID_OPERATION;
+ }
+
+ virtual std::vector<android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription>
+ listSupportedMetadataTypes() const {
+ return {};
+ }
};
// A wrapper to IAllocator
@@ -85,16 +246,17 @@
virtual bool isLoaded() const = 0;
- virtual std::string dumpDebugInfo() const = 0;
+ virtual std::string dumpDebugInfo(bool less = true) const = 0;
/*
* The returned buffers are already imported and must not be imported
* again. outBufferHandles must point to a space that can contain at
* least "bufferCount" buffer_handle_t.
*/
- virtual status_t allocate(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
- uint32_t* outStride, buffer_handle_t* outBufferHandles,
+ virtual status_t allocate(std::string requestorName, uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount, uint64_t usage,
+ uint32_t bufferCount, uint32_t* outStride,
+ buffer_handle_t* outBufferHandles,
bool importBuffers = true) const = 0;
};
diff --git a/libs/ui/include/ui/Gralloc2.h b/libs/ui/include/ui/Gralloc2.h
index 12c772a..f570c42 100644
--- a/libs/ui/include/ui/Gralloc2.h
+++ b/libs/ui/include/ui/Gralloc2.h
@@ -61,9 +61,6 @@
int unlock(buffer_handle_t bufferHandle) const override;
- status_t isSupported(uint32_t width, uint32_t height, android::PixelFormat format,
- uint32_t layerCount, uint64_t usage, bool* outSupported) const override;
-
private:
// Determines whether the passed info is compatible with the mapper.
status_t validateBufferDescriptorInfo(
@@ -81,11 +78,12 @@
bool isLoaded() const override;
- std::string dumpDebugInfo() const override;
+ std::string dumpDebugInfo(bool less = true) const override;
- status_t allocate(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
- buffer_handle_t* outBufferHandles, bool importBuffers = true) const override;
+ status_t allocate(std::string requestorName, uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles,
+ bool importBuffers = true) const override;
private:
const Gralloc2Mapper& mMapper;
diff --git a/libs/ui/include/ui/Gralloc3.h b/libs/ui/include/ui/Gralloc3.h
index bfbc2aa..93a5077 100644
--- a/libs/ui/include/ui/Gralloc3.h
+++ b/libs/ui/include/ui/Gralloc3.h
@@ -79,11 +79,12 @@
bool isLoaded() const override;
- std::string dumpDebugInfo() const override;
+ std::string dumpDebugInfo(bool less = true) const override;
- status_t allocate(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
- buffer_handle_t* outBufferHandles, bool importBuffers = true) const override;
+ status_t allocate(std::string requestorName, uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles,
+ bool importBuffers = true) const override;
private:
const Gralloc3Mapper& mMapper;
diff --git a/libs/ui/include/ui/Gralloc4.h b/libs/ui/include/ui/Gralloc4.h
index 60115f9..af7c076 100644
--- a/libs/ui/include/ui/Gralloc4.h
+++ b/libs/ui/include/ui/Gralloc4.h
@@ -17,16 +17,17 @@
#ifndef ANDROID_UI_GRALLOC4_H
#define ANDROID_UI_GRALLOC4_H
-#include <string>
-
#include <android/hardware/graphics/allocator/4.0/IAllocator.h>
#include <android/hardware/graphics/common/1.1/types.h>
#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <gralloctypes/Gralloc4.h>
#include <ui/Gralloc.h>
-#include <ui/PixelFormat.h>
+#include <ui/GraphicTypes.h>
#include <ui/Rect.h>
#include <utils/StrongPointer.h>
+#include <string>
+
namespace android {
class Gralloc4Mapper : public GrallocMapper {
@@ -37,6 +38,9 @@
bool isLoaded() const override;
+ std::string dumpBuffer(buffer_handle_t bufferHandle, bool less = true) const override;
+ std::string dumpBuffers(bool less = true) const;
+
status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const override;
status_t importBuffer(const hardware::hidl_handle& rawHandle,
@@ -45,7 +49,7 @@
void freeBuffer(buffer_handle_t bufferHandle) const override;
status_t validateBufferSize(buffer_handle_t bufferHandle, uint32_t width, uint32_t height,
- android::PixelFormat format, uint32_t layerCount, uint64_t usage,
+ PixelFormat format, uint32_t layerCount, uint64_t usage,
uint32_t stride) const override;
void getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
@@ -60,14 +64,117 @@
int unlock(buffer_handle_t bufferHandle) const override;
- status_t isSupported(uint32_t width, uint32_t height, android::PixelFormat format,
- uint32_t layerCount, uint64_t usage, bool* outSupported) const override;
+ status_t isSupported(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage, bool* outSupported) const override;
+
+ status_t getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const override;
+ status_t getName(buffer_handle_t bufferHandle, std::string* outName) const override;
+ status_t getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const override;
+ status_t getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const override;
+ status_t getLayerCount(buffer_handle_t bufferHandle, uint64_t* outLayerCount) const override;
+ status_t getPixelFormatRequested(buffer_handle_t bufferHandle,
+ ui::PixelFormat* outPixelFormatRequested) const override;
+ status_t getPixelFormatFourCC(buffer_handle_t bufferHandle,
+ uint32_t* outPixelFormatFourCC) const override;
+ status_t getPixelFormatModifier(buffer_handle_t bufferHandle,
+ uint64_t* outPixelFormatModifier) const override;
+ status_t getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const override;
+ status_t getAllocationSize(buffer_handle_t bufferHandle,
+ uint64_t* outAllocationSize) const override;
+ status_t getProtectedContent(buffer_handle_t bufferHandle,
+ uint64_t* outProtectedContent) const override;
+ status_t getCompression(buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType*
+ outCompression) const override;
+ status_t getCompression(buffer_handle_t bufferHandle,
+ ui::Compression* outCompression) const override;
+ status_t getInterlaced(buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType* outInterlaced)
+ const override;
+ status_t getInterlaced(buffer_handle_t bufferHandle,
+ ui::Interlaced* outInterlaced) const override;
+ status_t getChromaSiting(buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType*
+ outChromaSiting) const override;
+ status_t getChromaSiting(buffer_handle_t bufferHandle,
+ ui::ChromaSiting* outChromaSiting) const override;
+ status_t getPlaneLayouts(buffer_handle_t bufferHandle,
+ std::vector<ui::PlaneLayout>* outPlaneLayouts) const override;
+ status_t getDataspace(buffer_handle_t bufferHandle, ui::Dataspace* outDataspace) const override;
+ status_t getBlendMode(buffer_handle_t bufferHandle, ui::BlendMode* outBlendMode) const override;
+
+ status_t getDefaultPixelFormatFourCC(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint32_t* outPixelFormatFourCC) const override;
+ status_t getDefaultPixelFormatModifier(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint64_t* outPixelFormatModifier) const override;
+ status_t getDefaultAllocationSize(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint64_t* outAllocationSize) const override;
+ status_t getDefaultProtectedContent(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint64_t* outProtectedContent) const override;
+ status_t getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType*
+ outCompression) const override;
+ status_t getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::Compression* outCompression) const override;
+ status_t getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType*
+ outInterlaced) const override;
+ status_t getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::Interlaced* outInterlaced) const override;
+ status_t getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType*
+ outChromaSiting) const override;
+ status_t getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::ChromaSiting* outChromaSiting) const override;
+ status_t getDefaultPlaneLayouts(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ std::vector<ui::PlaneLayout>* outPlaneLayouts) const override;
+
+ std::vector<android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription>
+ listSupportedMetadataTypes() const;
private:
+ friend class GraphicBufferAllocator;
+
// Determines whether the passed info is compatible with the mapper.
status_t validateBufferDescriptorInfo(
hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo* descriptorInfo) const;
+ template <class T>
+ using DecodeFunction = status_t (*)(const hardware::hidl_vec<uint8_t>& input, T* output);
+
+ template <class T>
+ status_t get(
+ buffer_handle_t bufferHandle,
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ DecodeFunction<T> decodeFunction, T* outMetadata) const;
+
+ template <class T>
+ status_t getDefault(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ DecodeFunction<T> decodeFunction, T* outMetadata) const;
+
+ template <class T>
+ status_t metadataDumpHelper(
+ const android::hardware::graphics::mapper::V4_0::IMapper::BufferDump& bufferDump,
+ aidl::android::hardware::graphics::common::StandardMetadataType metadataType,
+ DecodeFunction<T> decodeFunction, T* outT) const;
+ status_t bufferDumpHelper(
+ const android::hardware::graphics::mapper::V4_0::IMapper::BufferDump& bufferDump,
+ std::ostringstream* outDump, uint64_t* outAllocationSize, bool less) const;
+
sp<hardware::graphics::mapper::V4_0::IMapper> mMapper;
};
@@ -79,11 +186,12 @@
bool isLoaded() const override;
- std::string dumpDebugInfo() const override;
+ std::string dumpDebugInfo(bool less = true) const override;
- status_t allocate(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
- buffer_handle_t* outBufferHandles, bool importBuffers = true) const override;
+ status_t allocate(std::string requestorName, uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles,
+ bool importBuffers = true) const override;
private:
const Gralloc4Mapper& mMapper;
diff --git a/libs/ui/include/ui/GraphicBufferAllocator.h b/libs/ui/include/ui/GraphicBufferAllocator.h
index a182104..3ed988c 100644
--- a/libs/ui/include/ui/GraphicBufferAllocator.h
+++ b/libs/ui/include/ui/GraphicBufferAllocator.h
@@ -1,19 +1,19 @@
/*
-**
-** Copyright 2009, 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.
-*/
+ *
+ * Copyright 2009, 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 ANDROID_BUFFER_ALLOCATOR_H
#define ANDROID_BUFFER_ALLOCATOR_H
@@ -74,8 +74,8 @@
uint64_t getTotalSize() const;
- void dump(std::string& res) const;
- static void dumpToSystemLog();
+ void dump(std::string& res, bool less = true) const;
+ static void dumpToSystemLog(bool less = true);
protected:
struct alloc_rec_t {
diff --git a/libs/ui/include/ui/GraphicBufferMapper.h b/libs/ui/include/ui/GraphicBufferMapper.h
index 83fb144..77c00ae 100644
--- a/libs/ui/include/ui/GraphicBufferMapper.h
+++ b/libs/ui/include/ui/GraphicBufferMapper.h
@@ -22,11 +22,11 @@
#include <memory>
+#include <ui/GraphicTypes.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <utils/Singleton.h>
-
// Needed by code that still uses the GRALLOC_USAGE_* constants.
// when/if we get rid of gralloc, we should provide aliases or fix call sites.
#include <hardware/gralloc.h>
@@ -49,6 +49,9 @@
static void preloadHal();
static inline GraphicBufferMapper& get() { return getInstance(); }
+ void dumpBuffer(buffer_handle_t bufferHandle, std::string& result, bool less = true) const;
+ static void dumpBufferToSystemLog(buffer_handle_t bufferHandle, bool less = true);
+
// The imported outHandle must be freed with freeBuffer when no longer
// needed. rawHandle is owned by the caller.
status_t importBuffer(buffer_handle_t rawHandle,
@@ -86,6 +89,82 @@
status_t isSupported(uint32_t width, uint32_t height, android::PixelFormat format,
uint32_t layerCount, uint64_t usage, bool* outSupported);
+ /**
+ * Gets the gralloc metadata associated with the buffer.
+ *
+ * These functions are supported by gralloc 4.0+.
+ */
+ status_t getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId);
+ status_t getName(buffer_handle_t bufferHandle, std::string* outName);
+ status_t getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth);
+ status_t getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight);
+ status_t getLayerCount(buffer_handle_t bufferHandle, uint64_t* outLayerCount);
+ status_t getPixelFormatRequested(buffer_handle_t bufferHandle,
+ ui::PixelFormat* outPixelFormatRequested);
+ status_t getPixelFormatFourCC(buffer_handle_t bufferHandle, uint32_t* outPixelFormatFourCC);
+ status_t getPixelFormatModifier(buffer_handle_t bufferHandle, uint64_t* outPixelFormatModifier);
+ status_t getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage);
+ status_t getAllocationSize(buffer_handle_t bufferHandle, uint64_t* outAllocationSize);
+ status_t getProtectedContent(buffer_handle_t bufferHandle, uint64_t* outProtectedContent);
+ status_t getCompression(
+ buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType* outCompression);
+ status_t getCompression(buffer_handle_t bufferHandle, ui::Compression* outCompression);
+ status_t getInterlaced(
+ buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType* outInterlaced);
+ status_t getInterlaced(buffer_handle_t bufferHandle, ui::Interlaced* outInterlaced);
+ status_t getChromaSiting(
+ buffer_handle_t bufferHandle,
+ aidl::android::hardware::graphics::common::ExtendableType* outChromaSiting);
+ status_t getChromaSiting(buffer_handle_t bufferHandle, ui::ChromaSiting* outChromaSiting);
+ status_t getPlaneLayouts(buffer_handle_t bufferHandle,
+ std::vector<ui::PlaneLayout>* outPlaneLayouts);
+ status_t getDataspace(buffer_handle_t bufferHandle, ui::Dataspace* outDataspace);
+ status_t getBlendMode(buffer_handle_t bufferHandle, ui::BlendMode* outBlendMode);
+
+ /**
+ * Gets the default metadata for a gralloc buffer allocated with the given parameters.
+ *
+ * These functions are supported by gralloc 4.0+.
+ */
+ status_t getDefaultPixelFormatFourCC(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint32_t* outPixelFormatFourCC);
+ status_t getDefaultPixelFormatModifier(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint64_t* outPixelFormatModifier);
+ status_t getDefaultAllocationSize(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint64_t* outAllocationSize);
+ status_t getDefaultProtectedContent(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint64_t* outProtectedContent);
+ status_t getDefaultCompression(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType* outCompression);
+ status_t getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::Compression* outCompression);
+ status_t getDefaultInterlaced(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType* outInterlaced);
+ status_t getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::Interlaced* outInterlaced);
+ status_t getDefaultChromaSiting(
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ aidl::android::hardware::graphics::common::ExtendableType* outChromaSiting);
+ status_t getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ ui::ChromaSiting* outChromaSiting);
+ status_t getDefaultPlaneLayouts(uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ std::vector<ui::PlaneLayout>* outPlaneLayouts);
+
const GrallocMapper& getGrallocMapper() const {
return reinterpret_cast<const GrallocMapper&>(*mMapper);
}
diff --git a/libs/ui/include/ui/GraphicTypes.h b/libs/ui/include/ui/GraphicTypes.h
index d7411ea..ad5ee80 100644
--- a/libs/ui/include/ui/GraphicTypes.h
+++ b/libs/ui/include/ui/GraphicTypes.h
@@ -16,21 +16,47 @@
#pragma once
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/ChromaSiting.h>
+#include <aidl/android/hardware/graphics/common/Compression.h>
+#include <aidl/android/hardware/graphics/common/Interlaced.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayout.h>
#include <android/hardware/graphics/common/1.1/types.h>
#include <android/hardware/graphics/common/1.2/types.h>
#include <system/graphics.h>
namespace android {
-// android::ui::* in this header file will alias different types as
-// the HIDL interface is updated.
+/**
+ * android::ui::* in this header file will alias different types as
+ * the HIDL and stable AIDL interfaces are updated.
+ */
namespace ui {
+/**
+ * The following HIDL types should be moved to their stable AIDL
+ * equivalents when composer moves to stable AIDL.
+ */
using android::hardware::graphics::common::V1_1::RenderIntent;
using android::hardware::graphics::common::V1_2::ColorMode;
using android::hardware::graphics::common::V1_2::Dataspace;
using android::hardware::graphics::common::V1_2::Hdr;
using android::hardware::graphics::common::V1_2::PixelFormat;
+/**
+ * Stable AIDL types
+ */
+using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::PlaneLayout;
+
+/**
+ * The following stable AIDL types below have standard platform definitions
+ * that can be extended by vendors. The extensions are not defined here
+ * because they cannot be understood by the framework.
+ */
+using ChromaSiting = aidl::android::hardware::graphics::common::ChromaSiting;
+using Compression = aidl::android::hardware::graphics::common::Compression;
+using Interlaced = aidl::android::hardware::graphics::common::Interlaced;
+
} // namespace ui
} // namespace android
diff --git a/libs/ui/include_vndk/ui/Gralloc2.h b/libs/ui/include_vndk/ui/Gralloc2.h
deleted file mode 120000
index 66098c4..0000000
--- a/libs/ui/include_vndk/ui/Gralloc2.h
+++ /dev/null
@@ -1 +0,0 @@
-../../include/ui/Gralloc2.h
\ No newline at end of file
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index d2ad242..ff55bc2 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -38,8 +38,9 @@
"libgmock",
],
shared_libs: [
+ "libhidlbase",
"liblog",
- "libui",
+ "libui",
],
srcs: [
"GraphicBufferAllocator_test.cpp",
diff --git a/libs/ui/tests/GraphicBufferAllocator_test.cpp b/libs/ui/tests/GraphicBufferAllocator_test.cpp
index efca083..f4c0afa 100644
--- a/libs/ui/tests/GraphicBufferAllocator_test.cpp
+++ b/libs/ui/tests/GraphicBufferAllocator_test.cpp
@@ -51,7 +51,7 @@
std::cout << "Setting expected stride to " << stride << std::endl;
EXPECT_CALL(*(reinterpret_cast<const mock::MockGrallocAllocator*>(mAllocator.get())),
allocate)
- .WillOnce(DoAll(SetArgPointee<6>(stride), Return(err)));
+ .WillOnce(DoAll(SetArgPointee<7>(stride), Return(err)));
}
std::unique_ptr<const GrallocAllocator>& getAllocator() { return mAllocator; }
};
diff --git a/libs/ui/tests/mock/MockGrallocAllocator.h b/libs/ui/tests/mock/MockGrallocAllocator.h
index 7660e9f..d62e3e2 100644
--- a/libs/ui/tests/mock/MockGrallocAllocator.h
+++ b/libs/ui/tests/mock/MockGrallocAllocator.h
@@ -32,10 +32,10 @@
~MockGrallocAllocator() override;
MOCK_METHOD(bool, isLoaded, (), (const, override));
- MOCK_METHOD(std::string, dumpDebugInfo, (), (const, override));
+ MOCK_METHOD(std::string, dumpDebugInfo, (bool less), (const, override));
MOCK_METHOD(status_t, allocate,
- (uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
- uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
+ (std::string requestorName, uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t layerCount, uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
buffer_handle_t* outBufferHandles, bool less),
(const, override));
};
diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen
index da9bb49..41fcf1b 100755
--- a/opengl/tools/glgen/gen
+++ b/opengl/tools/glgen/gen
@@ -91,8 +91,8 @@
rm src/*.class
# Add UnsupportedAppUsage.java to known sources.
-mkdir -p out/android/annotation
-cp ../../../../base/core/java/android/annotation/UnsupportedAppUsage.java out/android/annotation
+mkdir -p out/android/compat/annotation
+cp ../../../../../tools/platform-compat/annotation/src/java/android/compat/annotation/UnsupportedAppUsage.java out/android/compat/annotation
pushd out > /dev/null
mkdir classes
@@ -114,7 +114,7 @@
android/opengl/GLES31.java \
android/opengl/GLES31Ext.java \
android/opengl/GLES32.java \
- android/annotation/UnsupportedAppUsage.java
+ android/compat/annotation/UnsupportedAppUsage.java
popd > /dev/null
JAVA_RESULT=$?
if [ $JAVA_RESULT -ne 0 ]; then
diff --git a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
index 12728f5..9932556 100644
--- a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
+++ b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
@@ -18,7 +18,7 @@
package android.opengl;
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.SurfaceTexture;
import android.view.Surface;
import android.view.SurfaceView;
diff --git a/opengl/tools/glgen/stubs/gles11/GLES20Header.java-if b/opengl/tools/glgen/stubs/gles11/GLES20Header.java-if
index c2711aa..7db1101 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES20Header.java-if
+++ b/opengl/tools/glgen/stubs/gles11/GLES20Header.java-if
@@ -19,7 +19,7 @@
package android.opengl;
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
/** OpenGL ES 2.0
*/
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index dcb3ebc..5a49b5e 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4115,7 +4115,9 @@
options.displayId = displayId;
for (const TouchedWindow& window : state.windows) {
sp<InputChannel> channel = getInputChannelLocked(window.windowHandle->getToken());
- synthesizeCancelationEventsForInputChannelLocked(channel, options);
+ if (channel != nullptr) {
+ synthesizeCancelationEventsForInputChannelLocked(channel, options);
+ }
}
// Then clear the current touch state so we stop dispatching to them as well.
state.filterNonMonitors();
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index f51d4a0..348a7ad 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -183,6 +183,9 @@
mParameters.handlesKeyRepeat = false;
config.tryGetProperty(String8("keyboard.handlesKeyRepeat"), mParameters.handlesKeyRepeat);
+
+ mParameters.doNotWakeByDefault = false;
+ config.tryGetProperty(String8("keyboard.doNotWakeByDefault"), mParameters.doNotWakeByDefault);
}
void KeyboardInputMapper::dumpParameters(std::string& dump) {
@@ -331,10 +334,12 @@
// Key down on external an keyboard should wake the device.
// We don't do this for internal keyboards to prevent them from waking up in your pocket.
- // For internal keyboards, the key layout file should specify the policy flags for
- // each wake key individually.
+ // For internal keyboards and devices for which the default wake behavior is explicitly
+ // prevented (e.g. TV remotes), the key layout file should specify the policy flags for each
+ // wake key individually.
// TODO: Use the input device configuration to control this behavior more finely.
- if (down && getDevice()->isExternal() && !isMediaKey(keyCode)) {
+ if (down && getDevice()->isExternal() && !mParameters.doNotWakeByDefault &&
+ !isMediaKey(keyCode)) {
policyFlags |= POLICY_FLAG_WAKE;
}
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
index de2a377..badbcb2 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
@@ -73,6 +73,7 @@
struct Parameters {
bool orientationAware;
bool handlesKeyRepeat;
+ bool doNotWakeByDefault;
} mParameters;
void configureParameters();
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index d861a5f..0701f3b 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -488,6 +488,11 @@
expectedFlags);
}
+ void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
+ consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
+ expectedFlags);
+ }
+
void assertNoEvents() {
InputEvent* event = consume();
ASSERT_EQ(nullptr, event)
@@ -639,6 +644,11 @@
return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, x, y);
}
+static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
+ int32_t displayId, int32_t x = 100, int32_t y = 200) {
+ return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, x, y);
+}
+
static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
// Define a valid key event.
@@ -847,6 +857,81 @@
0 /*expectedFlags*/);
}
+class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
+public:
+ FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
+ int32_t displayId, bool isGestureMonitor = false)
+ : FakeInputReceiver(dispatcher, name, displayId) {
+ mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
+ }
+
+ sp<IBinder> getToken() { return mServerChannel->getConnectionToken(); }
+};
+
+// Tests for gesture monitors
+TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) {
+ sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+ sp<FakeWindowHandle> window =
+ new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+
+ sp<FakeMonitorReceiver> monitor =
+ new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
+ true /*isGestureMonitor*/);
+
+ ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
+ << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
+ monitor->consumeMotionDown(ADISPLAY_ID_DEFAULT);
+}
+
+TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) {
+ sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+ sp<FakeWindowHandle> window =
+ new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
+
+ mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
+ window->setFocus();
+
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+
+ sp<FakeMonitorReceiver> monitor =
+ new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
+ true /*isGestureMonitor*/);
+
+ ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
+ << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
+ monitor->assertNoEvents();
+}
+
+TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) {
+ sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+ sp<FakeWindowHandle> window =
+ new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+
+ sp<FakeMonitorReceiver> monitor =
+ new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
+ true /*isGestureMonitor*/);
+
+ ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
+ << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
+ monitor->consumeMotionDown(ADISPLAY_ID_DEFAULT);
+
+ window->releaseChannel();
+
+ mDispatcher->pilferPointers(monitor->getToken());
+
+ ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
+ << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ monitor->consumeMotionUp(ADISPLAY_ID_DEFAULT);
+}
+
/* Test InputDispatcher for MultiDisplay */
class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
public:
@@ -934,15 +1019,6 @@
windowInSecondary->assertNoEvents();
}
-class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
-public:
- FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
- int32_t displayId, bool isGestureMonitor = false)
- : FakeInputReceiver(dispatcher, name, displayId) {
- mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
- }
-};
-
// Test per-display input monitors for motion event.
TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
sp<FakeMonitorReceiver> monitorInPrimary =
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index d6624c9..1fc8217 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -2580,6 +2580,84 @@
AKEYCODE_DPAD_LEFT, newDisplayId));
}
+TEST_F(KeyboardInputMapperTest, ExternalDevice_WakeBehavior) {
+ // For external devices, non-media keys will trigger wake on key down. Media keys need to be
+ // marked as WAKE in the keylayout file to trigger wake.
+ mDevice->setExternal(true);
+
+ mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, 0);
+ mFakeEventHub->addKey(DEVICE_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0);
+ mFakeEventHub->addKey(DEVICE_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE, POLICY_FLAG_WAKE);
+
+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD,
+ AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+ addMapperAndConfigure(mapper);
+
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_HOME, 1);
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(uint32_t(0), args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_PLAY, 1);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(uint32_t(0), args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_PLAY, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(uint32_t(0), args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_PLAYPAUSE, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
+}
+
+TEST_F(KeyboardInputMapperTest, ExternalDevice_DoNotWakeByDefaultBehavior) {
+ // Tv Remote key's wake behavior is prescribed by the keylayout file.
+ mDevice->setExternal(true);
+
+ mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
+ mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
+ mFakeEventHub->addKey(DEVICE_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
+
+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD,
+ AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+ addConfigurationProperty("keyboard.doNotWakeByDefault", "1");
+ addMapperAndConfigure(mapper);
+
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_HOME, 1);
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_DOWN, 1);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(uint32_t(0), args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_DOWN, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(uint32_t(0), args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_PLAY, 1);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
+
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_PLAY, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
+}
+
// --- CursorInputMapperTest ---
class CursorInputMapperTest : public InputMapperTest {
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index 0a70165..e432b1c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -17,6 +17,7 @@
#pragma once
#include <optional>
+#include <ostream>
#include <unordered_set>
#include <renderengine/LayerSettings.h>
@@ -115,5 +116,29 @@
using LayerFESet = std::unordered_set<sp<LayerFE>, LayerFESpHash>;
+static inline bool operator==(const LayerFE::ClientCompositionTargetSettings& lhs,
+ const LayerFE::ClientCompositionTargetSettings& rhs) {
+ return lhs.clip.hasSameRects(rhs.clip) &&
+ lhs.useIdentityTransform == rhs.useIdentityTransform &&
+ lhs.needsFiltering == rhs.needsFiltering && lhs.isSecure == rhs.isSecure &&
+ lhs.supportsProtectedContent == rhs.supportsProtectedContent &&
+ lhs.clearRegion.hasSameRects(rhs.clearRegion);
+}
+
+// Defining PrintTo helps with Google Tests.
+static inline void PrintTo(const LayerFE::ClientCompositionTargetSettings& settings,
+ ::std::ostream* os) {
+ *os << "ClientCompositionTargetSettings{";
+ *os << "\n .clip = \n";
+ PrintTo(settings.clip, os);
+ *os << "\n .useIdentityTransform = " << settings.useIdentityTransform;
+ *os << "\n .needsFiltering = " << settings.needsFiltering;
+ *os << "\n .isSecure = " << settings.isSecure;
+ *os << "\n .supportsProtectedContent = " << settings.supportsProtectedContent;
+ *os << "\n .clearRegion = ";
+ PrintTo(settings.clearRegion, os);
+ *os << "\n}";
+}
+
} // namespace compositionengine
} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index d87389f..87beb0d 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -41,6 +41,7 @@
using testing::_;
using testing::ByMove;
+using testing::ByRef;
using testing::DoAll;
using testing::ElementsAreArray;
using testing::Eq;
@@ -3101,7 +3102,26 @@
}
};
+ struct Layer {
+ Layer() {
+ EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
+ EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
+ EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(mLayer));
+ EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
+ EXPECT_CALL(mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
+ }
+
+ StrictMock<mock::OutputLayer> mOutputLayer;
+ StrictMock<mock::Layer> mLayer;
+ StrictMock<mock::LayerFE> mLayerFE;
+ LayerFECompositionState mLayerFEState;
+ impl::OutputLayerCompositionState mOutputLayerState;
+ renderengine::LayerSettings mRELayerSettings;
+ };
+
GenerateClientCompositionRequestsTest() {
+ mOutput.mState.needsFiltering = false;
+
mOutput.setDisplayColorProfileForTest(
std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
@@ -3112,222 +3132,507 @@
StrictMock<OutputPartialMock> mOutput;
};
-// TODO(b/121291683): Add more unit test coverage for generateClientCompositionRequests
+struct GenerateClientCompositionRequestsTest_ThreeLayers
+ : public GenerateClientCompositionRequestsTest {
+ GenerateClientCompositionRequestsTest_ThreeLayers() {
+ mOutput.mState.frame = kDisplayFrame;
+ mOutput.mState.viewport = kDisplayViewport;
+ mOutput.mState.scissor = kDisplayScissor;
+ mOutput.mState.transform = ui::Transform{kDisplayOrientation};
+ mOutput.mState.orientation = kDisplayOrientation;
+ mOutput.mState.needsFiltering = false;
+ mOutput.mState.isSecure = false;
-TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) {
- // In split-screen landscape mode, the screen is rotated 90 degrees, with
- // one layer on the left covering the left side of the output, and one layer
- // on the right covering that side of the output.
+ for (size_t i = 0; i < mLayers.size(); i++) {
+ mLayers[i].mOutputLayerState.clearClientTarget = false;
+ mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
+ mLayers[i].mLayerFEState.isOpaque = true;
+ mLayers[i].mRELayerSettings.geometry.boundaries =
+ FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
+ mLayers[i].mRELayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
+ mLayers[i].mRELayerSettings.alpha = 1.0f;
+ mLayers[i].mRELayerSettings.disableBlending = false;
- StrictMock<mock::OutputLayer> leftOutputLayer;
- StrictMock<mock::OutputLayer> rightOutputLayer;
+ EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
+ .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
+ EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
+ }
- StrictMock<mock::Layer> leftLayer;
- StrictMock<mock::LayerFE> leftLayerFE;
- StrictMock<mock::Layer> rightLayer;
- StrictMock<mock::LayerFE> rightLayerFE;
+ EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
+ }
- impl::OutputLayerCompositionState leftOutputLayerState;
- leftOutputLayerState.clearClientTarget = false;
- leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
+ static constexpr uint32_t kDisplayOrientation = TR_IDENT;
+ static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
- LayerFECompositionState leftLayerFEState;
- leftLayerFEState.isOpaque = true;
+ static const Rect kDisplayFrame;
+ static const Rect kDisplayViewport;
+ static const Rect kDisplayScissor;
- const half3 leftLayerColor{1.f, 0.f, 0.f};
- renderengine::LayerSettings leftLayerRESettings;
- leftLayerRESettings.source.solidColor = leftLayerColor;
+ std::array<Layer, 3> mLayers;
+};
- impl::OutputLayerCompositionState rightOutputLayerState;
- rightOutputLayerState.clearClientTarget = false;
- rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
+const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
+const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
+const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayScissor(0, 0, 102, 202);
- LayerFECompositionState rightLayerFEState;
- rightLayerFEState.isOpaque = true;
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
+ EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
+ EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
+ EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
- const half3 rightLayerColor{0.f, 1.f, 0.f};
- renderengine::LayerSettings rightLayerRESettings;
- rightLayerRESettings.source.solidColor = rightLayerColor;
-
- EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
- EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
- EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
- EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
- EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
- EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
- EXPECT_CALL(leftLayerFE, prepareClientComposition(_)).WillOnce(Return(leftLayerRESettings));
- EXPECT_CALL(leftLayerFE, prepareShadowClientComposition(_, _, _))
- .WillOnce(Return(std::optional<renderengine::LayerSettings>()));
- EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
-
- EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
- EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
- EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
- EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
- EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
- EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
- EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
- EXPECT_CALL(rightLayerFE, prepareShadowClientComposition(_, _, _))
- .WillOnce(Return(std::optional<renderengine::LayerSettings>()));
- EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
-
- EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
- EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
- .WillRepeatedly(Return(&leftOutputLayer));
- EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
- .WillRepeatedly(Return(&rightOutputLayer));
-
- const Rect kPortraitFrame(0, 0, 1000, 2000);
- const Rect kPortraitViewport(0, 0, 2000, 1000);
- const Rect kPortraitScissor(0, 0, 1000, 2000);
- const uint32_t kPortraitOrientation = TR_ROT_90;
-
- mOutput.editState().frame = kPortraitFrame;
- mOutput.editState().viewport = kPortraitViewport;
- mOutput.editState().scissor = kPortraitScissor;
- mOutput.editState().transform = ui::Transform{kPortraitOrientation};
- mOutput.editState().orientation = kPortraitOrientation;
- mOutput.editState().needsFiltering = true;
- mOutput.editState().isSecure = false;
-
- constexpr bool supportsProtectedContent = false;
- Region clearRegion;
- auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion,
- mOutput.getState().targetDataspace);
-
- ASSERT_EQ(2u, requests.size());
- EXPECT_EQ(leftLayerColor, requests[0].source.solidColor);
- EXPECT_EQ(rightLayerColor, requests[1].source.solidColor);
-}
-
-TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWithViewport) {
- // Layers whose visible region does not intersect with the viewport will be
- // skipped when generating client composition request state.
-
- StrictMock<mock::OutputLayer> outputLayer;
- StrictMock<mock::Layer> layer;
- StrictMock<mock::LayerFE> layerFE;
-
- impl::OutputLayerCompositionState outputLayerState;
- outputLayerState.clearClientTarget = false;
- outputLayerState.visibleRegion = Region{Rect{3000, 0, 4000, 1000}};
-
- LayerFECompositionState layerFEState;
- layerFEState.isOpaque = true;
-
- EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
- EXPECT_CALL(outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer));
- EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
- EXPECT_CALL(outputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
- EXPECT_CALL(outputLayer, needsFiltering()).WillRepeatedly(Return(false));
- EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
- EXPECT_CALL(layerFE, prepareClientComposition(_)).Times(0);
- EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
-
- EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
- EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)).WillRepeatedly(Return(&outputLayer));
-
- const Rect kPortraitFrame(0, 0, 1000, 2000);
- const Rect kPortraitViewport(0, 0, 2000, 1000);
- const Rect kPortraitScissor(0, 0, 1000, 2000);
- const uint32_t kPortraitOrientation = TR_ROT_90;
-
- mOutput.editState().frame = kPortraitFrame;
- mOutput.editState().viewport = kPortraitViewport;
- mOutput.editState().scissor = kPortraitScissor;
- mOutput.editState().transform = ui::Transform{kPortraitOrientation};
- mOutput.editState().orientation = kPortraitOrientation;
- mOutput.editState().needsFiltering = true;
- mOutput.editState().isSecure = false;
-
- constexpr bool supportsProtectedContent = false;
- Region clearRegion;
- auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion,
- mOutput.getState().targetDataspace);
-
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+ auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace);
EXPECT_EQ(0u, requests.size());
+ EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
}
-TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) {
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
+ mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
+ mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
+ mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
+
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+ auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace);
+ EXPECT_EQ(0u, requests.size());
+ EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
+}
+
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
+ renderengine::LayerSettings mREShadowSettings;
+ mREShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
+
+ EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(_)).WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(_))
+ .WillOnce(Return(mLayers[1].mRELayerSettings));
+ EXPECT_CALL(mLayers[1].mLayerFE,
+ prepareShadowClientComposition(mLayers[1].mRELayerSettings, kDisplayViewport,
+ kDisplayDataspace))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
+ .WillOnce(Return(mLayers[2].mRELayerSettings));
+ EXPECT_CALL(mLayers[2].mLayerFE,
+ prepareShadowClientComposition(mLayers[2].mRELayerSettings, kDisplayViewport,
+ kDisplayDataspace))
+ .WillOnce(Return(mREShadowSettings));
+
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+ auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace);
+ ASSERT_EQ(3u, requests.size());
+ EXPECT_EQ(mLayers[1].mRELayerSettings, requests[0]);
+ EXPECT_EQ(mREShadowSettings, requests[1]);
+ EXPECT_EQ(mLayers[2].mRELayerSettings, requests[2]);
+
+ EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
+
+ // Check that a timestamp was set for the layers that generated requests
+ EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
+ EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
+ EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
+}
+
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
+ onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
+ EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
+ EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
+ EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
+
+ mLayers[0].mOutputLayerState.clearClientTarget = false;
+ mLayers[1].mOutputLayerState.clearClientTarget = false;
+ mLayers[2].mOutputLayerState.clearClientTarget = false;
+
+ mLayers[0].mLayerFEState.isOpaque = true;
+ mLayers[1].mLayerFEState.isOpaque = true;
+ mLayers[2].mLayerFEState.isOpaque = true;
+
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
+ .WillOnce(Return(mLayers[2].mRELayerSettings));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareShadowClientComposition(_, _, _))
+ .WillOnce(Return(std::nullopt));
+
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+ auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace);
+ ASSERT_EQ(1u, requests.size());
+ EXPECT_EQ(mLayers[2].mRELayerSettings, requests[0]);
+
+ EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
+}
+
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
+ onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
+ EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
+ EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
+ EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
+
+ mLayers[0].mOutputLayerState.clearClientTarget = true;
+ mLayers[1].mOutputLayerState.clearClientTarget = true;
+ mLayers[2].mOutputLayerState.clearClientTarget = true;
+
+ mLayers[0].mLayerFEState.isOpaque = false;
+ mLayers[1].mLayerFEState.isOpaque = false;
+ mLayers[2].mLayerFEState.isOpaque = false;
+
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
+ .WillOnce(Return(mLayers[2].mRELayerSettings));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareShadowClientComposition(_, _, _))
+ .WillOnce(Return(std::nullopt));
+
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+ auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace);
+ ASSERT_EQ(1u, requests.size());
+ EXPECT_EQ(mLayers[2].mRELayerSettings, requests[0]);
+
+ EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
+}
+
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
// If client composition is performed with some layers set to use device
// composition, device layers after the first layer (device or client) will
// clear the frame buffer if they are opaque and if that layer has a flag
// set to do so. The first layer is skipped as the frame buffer is already
// expected to be clear.
- StrictMock<mock::OutputLayer> leftOutputLayer;
- StrictMock<mock::OutputLayer> rightOutputLayer;
+ EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
+ EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
+ EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
- StrictMock<mock::Layer> leftLayer;
- StrictMock<mock::LayerFE> leftLayerFE;
- StrictMock<mock::Layer> rightLayer;
- StrictMock<mock::LayerFE> rightLayerFE;
+ mLayers[0].mOutputLayerState.clearClientTarget = true;
+ mLayers[1].mOutputLayerState.clearClientTarget = true;
+ mLayers[2].mOutputLayerState.clearClientTarget = true;
- impl::OutputLayerCompositionState leftOutputLayerState;
- leftOutputLayerState.clearClientTarget = true;
- leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
+ mLayers[0].mLayerFEState.isOpaque = true;
+ mLayers[1].mLayerFEState.isOpaque = true;
+ mLayers[2].mLayerFEState.isOpaque = true;
- LayerFECompositionState leftLayerFEState;
- leftLayerFEState.isOpaque = true;
+ EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(_))
+ .WillOnce(Return(mLayers[1].mRELayerSettings));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
+ .WillOnce(Return(mLayers[2].mRELayerSettings));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareShadowClientComposition(_, _, _))
+ .WillOnce(Return(std::nullopt));
- impl::OutputLayerCompositionState rightOutputLayerState;
- rightOutputLayerState.clearClientTarget = true;
- rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+ auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace);
+ ASSERT_EQ(2u, requests.size());
- LayerFECompositionState rightLayerFEState;
- rightLayerFEState.isOpaque = true;
+ // The second layer is expected to be rendered as alpha=0 black with no blending
+ EXPECT_EQ(mLayers[1].mRELayerSettings.geometry.boundaries, requests[0].geometry.boundaries);
+ EXPECT_FALSE(requests[0].source.buffer.buffer);
+ EXPECT_EQ((half3{0.f, 0.f, 0.f}), requests[0].source.solidColor);
+ EXPECT_EQ(half{0.f}, requests[0].alpha);
+ EXPECT_EQ(true, requests[0].disableBlending);
- const half3 rightLayerColor{0.f, 1.f, 0.f};
- renderengine::LayerSettings rightLayerRESettings;
- rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0};
- rightLayerRESettings.source.solidColor = rightLayerColor;
+ EXPECT_EQ(mLayers[2].mRELayerSettings, requests[1]);
- EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
- EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
- EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
- EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
- EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
- EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
- EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
+ EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
+}
- EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
- EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
- EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
- EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
- EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
- EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
- EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
- EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
+ clippedVisibleRegionUsedToGenerateRequest) {
+ mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
+ mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
+ mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
- EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
- EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
- .WillRepeatedly(Return(&leftOutputLayer));
- EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
- .WillRepeatedly(Return(&rightOutputLayer));
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
+ Region(Rect(10, 10, 20, 20)),
+ false, /* identity transform */
+ false, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
+ Region(Rect(0, 0, 30, 30)),
+ false, /* identity transform */
+ false, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
+ Region(Rect(0, 0, 40, 201)),
+ false, /* identity transform */
+ false, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+
+ EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+
+ static_cast<void>(
+ mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace));
+}
+
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
+ perLayerNeedsFilteringUsedToGenerateRequests) {
+ mOutput.mState.needsFiltering = false;
+ EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
+
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ true, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ false, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ false, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+
+ EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+
+ static_cast<void>(
+ mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace));
+}
+
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
+ wholeOutputNeedsFilteringUsedToGenerateRequests) {
+ mOutput.mState.needsFiltering = true;
+ EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
+
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ true, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ true, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ true, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+
+ EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+
+ static_cast<void>(
+ mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace));
+}
+
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
+ wholeOutputSecurityUsedToGenerateRequests) {
+ mOutput.mState.isSecure = true;
+
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ false, /* needs filtering */
+ true, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ false, /* needs filtering */
+ true, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ false, /* needs filtering */
+ true, /* secure */
+ false, /* supports protected content */
+ accumClearRegion,
+ };
+
+ EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+
+ static_cast<void>(
+ mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
+ accumClearRegion, kDisplayDataspace));
+}
+
+TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
+ protectedContentSupportUsedToGenerateRequests) {
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ false, /* needs filtering */
+ false, /* secure */
+ true, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ false, /* needs filtering */
+ false, /* secure */
+ true, /* supports protected content */
+ accumClearRegion,
+ };
+ compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
+ Region(kDisplayFrame),
+ false, /* identity transform */
+ false, /* needs filtering */
+ false, /* secure */
+ true, /* supports protected content */
+ accumClearRegion,
+ };
+
+ EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+ EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
+ .WillOnce(Return(std::nullopt));
+
+ static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
+ accumClearRegion,
+ kDisplayDataspace));
+}
+
+TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
+ // In split-screen landscape mode, the screen is rotated 90 degrees, with
+ // one layer on the left covering the left side of the output, and one layer
+ // on the right covering that side of the output.
const Rect kPortraitFrame(0, 0, 1000, 2000);
const Rect kPortraitViewport(0, 0, 2000, 1000);
const Rect kPortraitScissor(0, 0, 1000, 2000);
const uint32_t kPortraitOrientation = TR_ROT_90;
+ constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
- mOutput.editState().frame = kPortraitFrame;
- mOutput.editState().viewport = kPortraitViewport;
- mOutput.editState().scissor = kPortraitScissor;
- mOutput.editState().transform = ui::Transform{kPortraitOrientation};
- mOutput.editState().orientation = kPortraitOrientation;
- mOutput.editState().needsFiltering = true;
- mOutput.editState().isSecure = false;
+ mOutput.mState.frame = kPortraitFrame;
+ mOutput.mState.viewport = kPortraitViewport;
+ mOutput.mState.scissor = kPortraitScissor;
+ mOutput.mState.transform = ui::Transform{kPortraitOrientation};
+ mOutput.mState.orientation = kPortraitOrientation;
+ mOutput.mState.needsFiltering = false;
+ mOutput.mState.isSecure = true;
- constexpr bool supportsProtectedContent = false;
- Region clearRegion;
- auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion,
- mOutput.getState().targetDataspace);
+ Layer leftLayer;
+ Layer rightLayer;
- const half3 clearColor{0.f, 0.f, 0.f};
+ leftLayer.mOutputLayerState.clearClientTarget = false;
+ leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
+ leftLayer.mLayerFEState.isOpaque = true;
+ leftLayer.mRELayerSettings.source.solidColor = {1.f, 0.f, 0.f};
- ASSERT_EQ(1u, requests.size());
- EXPECT_EQ(456.f, requests[0].geometry.boundaries.left);
- EXPECT_EQ(clearColor, requests[0].source.solidColor);
+ rightLayer.mOutputLayerState.clearClientTarget = false;
+ rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
+ rightLayer.mLayerFEState.isOpaque = true;
+ rightLayer.mRELayerSettings.source.solidColor = {0.f, 1.f, 0.f};
+
+ EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
+ EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
+ .WillRepeatedly(Return(&leftLayer.mOutputLayer));
+ EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
+ .WillRepeatedly(Return(&rightLayer.mOutputLayer));
+
+ Region accumClearRegion(Rect(10, 11, 12, 13));
+
+ compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
+ Region(Rect(0, 0, 1000, 1000)),
+ false, /* identity transform */
+ false, /* needs filtering */
+ true, /* secure */
+ true, /* supports protected content */
+ accumClearRegion,
+ };
+
+ EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
+ EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
+ EXPECT_CALL(leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
+ .WillOnce(Return(leftLayer.mRELayerSettings));
+ EXPECT_CALL(leftLayer.mLayerFE,
+ prepareShadowClientComposition(leftLayer.mRELayerSettings, kPortraitViewport,
+ kOutputDataspace))
+ .WillOnce(Return(std::nullopt));
+
+ compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
+ Region(Rect(1000, 0, 2000, 1000)),
+ false, /* identity transform */
+ false, /* needs filtering */
+ true, /* secure */
+ true, /* supports protected content */
+ accumClearRegion,
+ };
+
+ EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
+ EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
+ EXPECT_CALL(rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
+ .WillOnce(Return(rightLayer.mRELayerSettings));
+ EXPECT_CALL(rightLayer.mLayerFE,
+ prepareShadowClientComposition(rightLayer.mRELayerSettings, kPortraitViewport,
+ kOutputDataspace))
+ .WillOnce(Return(std::nullopt));
+
+ constexpr bool supportsProtectedContent = true;
+ auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
+ accumClearRegion, kOutputDataspace);
+ ASSERT_EQ(2u, requests.size());
+ EXPECT_EQ(leftLayer.mRELayerSettings, requests[0]);
+ EXPECT_EQ(rightLayer.mRELayerSettings, requests[1]);
}
} // namespace
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8e94529..9d5081c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2029,6 +2029,7 @@
// Even though ATRACE_INT64 already checks if tracing is enabled, it doesn't prevent the
// side-effect of getTotalSize(), so we check that again here
if (ATRACE_ENABLED()) {
+ // getTotalSize returns the total number of buffers that were allocated by SurfaceFlinger
ATRACE_INT64("Total Buffer Size", GraphicBufferAllocator::get().getTotalSize());
}
}
@@ -5662,7 +5663,10 @@
}
sp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) {
- BBinder *b = handle->localBinder();
+ BBinder* b = nullptr;
+ if (handle) {
+ b = handle->localBinder();
+ }
if (b == nullptr) {
return nullptr;
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index facf142..f057c98 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -393,6 +393,11 @@
auto& mutableInternalHwcDisplayId() { return getHwComposer().mInternalHwcDisplayId; }
auto& mutableExternalHwcDisplayId() { return getHwComposer().mExternalHwcDisplayId; }
+ auto fromHandle(const sp<IBinder>& handle) {
+ Mutex::Autolock _l(mFlinger->mStateLock);
+ return mFlinger->fromHandle(handle);
+ }
+
~TestableSurfaceFlinger() {
// All these pointer and container clears help ensure that GMock does
// not report a leaked object, since the SurfaceFlinger instance may
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index a465388..994a509 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -315,4 +315,9 @@
BlockedByPriorTransaction(/*flags*/ 0, /*syncInputWindows*/ true);
}
+TEST_F(TransactionApplicationTest, FromHandle) {
+ sp<IBinder> badHandle;
+ auto ret = mFlinger.fromHandle(badHandle);
+ EXPECT_EQ(nullptr, ret.get());
+}
} // namespace android