drm_hwcomposer: Add adjustments for cursor plane commits
This change adds special handling for buffers that may be committed to the
cursor plane. Some drivers may enforce size constraints on cursor plane
commits, which can be satisfied by padding the buffer beyond its nominal
width and height. This change adds behavior to extract that padding
(i.e. the aligned dimensions) by analyzing the buffer pitch, size, and
format.
When the cursor usage flag is set on a buffer, the aligned dimensions
should be used in place of the nominal dimensions for creating the
framebuffer, checking compatibility to the cursor plane, and for setting
the display and crop rects during commit.
Change-Id: I1cc2aa2f9cd23173cae87ae6e486c3b140b78ad5
Signed-off-by: Andrew Wolfers <aswolfers@google.com>
diff --git a/bufferinfo/BufferInfoMapperMetadata.cpp b/bufferinfo/BufferInfoMapperMetadata.cpp
index dc1b906..125c5c8 100644
--- a/bufferinfo/BufferInfoMapperMetadata.cpp
+++ b/bufferinfo/BufferInfoMapperMetadata.cpp
@@ -31,6 +31,23 @@
namespace android {
+namespace {
+
+std::optional<std::pair<uint32_t, uint32_t>> GetAlignedDimensions(
+ const ui::PlaneLayout &layout) {
+ if (layout.sampleIncrementInBits == 0 || layout.strideInBytes == 0) {
+ ALOGW("Invalid plane layout");
+ return std::nullopt;
+ }
+
+ constexpr uint32_t kBitsPerByte = 8;
+ return std::pair{layout.strideInBytes * kBitsPerByte /
+ layout.sampleIncrementInBits,
+ layout.totalSizeInBytes / layout.strideInBytes};
+}
+
+} // namespace
+
BufferInfoGetter *BufferInfoMapperMetadata::CreateInstance() {
if (GraphicBufferMapper::getInstance().getMapperVersion() <
GraphicBufferMapper::GRALLOC_4)
@@ -136,6 +153,25 @@
bi.sizes[i] = layouts[i].totalSizeInBytes;
}
+ uint64_t usage = 0;
+ err = mapper.getUsage(handle, &usage);
+ if (err != 0) {
+ ALOGE("Failed to get Usage err=%d", err);
+ return {};
+ }
+
+ if ((usage & GRALLOC_USAGE_CURSOR) != 0) {
+ if (layouts.size() > 1) {
+ ALOGW("Multiplanar format buffer alignment not supported");
+ } else {
+ auto aligned = GetAlignedDimensions(layouts[0]);
+ if (aligned.has_value()) {
+ bi.width = aligned->first;
+ bi.height = aligned->second;
+ }
+ }
+ }
+
err = GetFds(handle, &bi);
if (err != 0) {
ALOGE("Failed to get fds (err=%d)", err);