Merge changes I20e4aa1a,I00370f05
* changes:
SF: Introduce LayerCompositionState
SF: Introduce OutputLayerCompositionState
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index db8848a..61745b5 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1464,6 +1464,12 @@
// Run iotop as root to show top 100 IO threads
RunCommand("IOTOP", {"iotop", "-n", "1", "-m", "100"});
+ // Gather shared memory buffer info if the product implements it
+ struct stat st;
+ if (!stat("/product/bin/dmabuf_dump", &st)) {
+ RunCommand("Dmabuf dump", {"/product/bin/dmabuf_dump"});
+ }
+
if (!DropRootUser()) {
return false;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 46b9128..bf2a03d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -383,6 +383,7 @@
other.mListenerCallbacks.clear();
mInputWindowCommands.merge(other.mInputWindowCommands);
+ other.mInputWindowCommands.clear();
return *this;
}
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 8ef4896..994e953 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -122,6 +122,54 @@
return gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence);
}
+int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage,
+ int32_t fence, const ARect* rect, AHardwareBuffer_Planes* outPlanes) {
+ if (!buffer || !outPlanes) return BAD_VALUE;
+
+ if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) {
+ ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only "
+ " AHARDWAREBUFFER_USAGE_CPU_* flags are allowed");
+ return BAD_VALUE;
+ }
+
+ usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
+ GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+ Rect bounds;
+ if (!rect) {
+ bounds.set(Rect(gBuffer->getWidth(), gBuffer->getHeight()));
+ } else {
+ bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom));
+ }
+ int format = AHardwareBuffer_convertFromPixelFormat(uint32_t(gBuffer->getPixelFormat()));
+ memset(outPlanes->planes, 0, sizeof(outPlanes->planes));
+ if (AHardwareBuffer_formatIsYuv(format)) {
+ android_ycbcr yuvData;
+ int result = gBuffer->lockAsyncYCbCr(usage, bounds, &yuvData, fence);
+ if (result == 0) {
+ outPlanes->planeCount = 3;
+ outPlanes->planes[0].data = yuvData.y;
+ outPlanes->planes[0].pixelStride = 1;
+ outPlanes->planes[0].rowStride = yuvData.ystride;
+ outPlanes->planes[1].data = yuvData.cb;
+ outPlanes->planes[1].pixelStride = yuvData.chroma_step;
+ outPlanes->planes[1].rowStride = yuvData.cstride;
+ outPlanes->planes[2].data = yuvData.cr;
+ outPlanes->planes[2].pixelStride = yuvData.chroma_step;
+ outPlanes->planes[2].rowStride = yuvData.cstride;
+ } else {
+ outPlanes->planeCount = 0;
+ }
+ return result;
+ } else {
+ const uint32_t pixelStride = AHardwareBuffer_bytesPerPixel(format);
+ outPlanes->planeCount = 1;
+ outPlanes->planes[0].pixelStride = pixelStride;
+ outPlanes->planes[0].rowStride = gBuffer->getStride() * pixelStride;
+ return gBuffer->lockAsync(usage, usage, bounds, &outPlanes->planes[0].data, fence);
+ }
+}
+
int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) {
if (!buffer) return BAD_VALUE;
@@ -375,6 +423,19 @@
ALOGE_IF(log, "AHARDWAREBUFFER_FORMAT_BLOB cannot be encoded as video");
return false;
}
+ } else if (AHardwareBuffer_formatIsYuv(desc->format)) {
+ if (desc->layers != 1) {
+ ALOGE_IF(log, "Layers must be 1 for YUV formats.");
+ return false;
+ }
+ const uint64_t yuvInvalidGpuMask =
+ AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE |
+ AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
+ if (desc->usage & yuvInvalidGpuMask) {
+ ALOGE_IF(log, "Invalid usage flags specified for YUV format; "
+ "mip-mapping and cube-mapping are not allowed.");
+ return false;
+ }
} else {
if (desc->usage & AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA) {
ALOGE_IF(log, "AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA requires AHARDWAREBUFFER_FORMAT_BLOB");
@@ -474,6 +535,7 @@
case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
case AHARDWAREBUFFER_FORMAT_S8_UINT:
+ case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
// VNDK formats only -- unfortunately we can't differentiate from where we're called
case AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM:
case AHARDWAREBUFFER_FORMAT_YV12:
@@ -484,7 +546,6 @@
case AHARDWAREBUFFER_FORMAT_RAW12:
case AHARDWAREBUFFER_FORMAT_RAW_OPAQUE:
case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
- case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
case AHARDWAREBUFFER_FORMAT_YCbCr_422_SP:
case AHARDWAREBUFFER_FORMAT_YCrCb_420_SP:
case AHARDWAREBUFFER_FORMAT_YCbCr_422_I:
@@ -495,6 +556,40 @@
}
}
+bool AHardwareBuffer_formatIsYuv(uint32_t format) {
+ switch (format) {
+ case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
+ case AHARDWAREBUFFER_FORMAT_YV12:
+ case AHARDWAREBUFFER_FORMAT_Y8:
+ case AHARDWAREBUFFER_FORMAT_Y16:
+ case AHARDWAREBUFFER_FORMAT_YCbCr_422_SP:
+ case AHARDWAREBUFFER_FORMAT_YCrCb_420_SP:
+ case AHARDWAREBUFFER_FORMAT_YCbCr_422_I:
+ return true;
+ default:
+ return false;
+ }
+}
+
+uint32_t AHardwareBuffer_bytesPerPixel(uint32_t format) {
+ switch (format) {
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+ case AHARDWAREBUFFER_FORMAT_D16_UNORM:
+ return 2;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM:
+ return 3;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+ case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t hal_format) {
return hal_format;
}
diff --git a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
index bf688f8..ddfd1d1 100644
--- a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
+++ b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
@@ -40,6 +40,12 @@
// whether this AHardwareBuffer format is valid
bool AHardwareBuffer_isValidPixelFormat(uint32_t ahardwarebuffer_format);
+// whether this is a YUV type format
+bool AHardwareBuffer_formatIsYuv(uint32_t format);
+
+// number of bytes per pixel or 0 if unknown or multi-planar
+uint32_t AHardwareBuffer_bytesPerPixel(uint32_t format);
+
// convert AHardwareBuffer format to HAL format (note: this is a no-op)
uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format);
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 2796c75..02c7c1b 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -150,6 +150,14 @@
* OpenGL ES: GL_STENCIL_INDEX8
*/
AHARDWAREBUFFER_FORMAT_S8_UINT = 0x35,
+
+ /**
+ * YUV 420 888 format.
+ * Must have an even width and height. Can be accessed in OpenGL
+ * shaders through an external sampler. Does not support mip-maps
+ * cube-maps or multi-layered textures.
+ */
+ AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23,
};
/**
@@ -302,6 +310,24 @@
} AHardwareBuffer_Desc;
/**
+ * Holds data for a single image plane.
+ */
+typedef struct AHardwareBuffer_Plane {
+ void* data; ///< Points to first byte in plane
+ uint32_t pixelStride; ///< Distance in bytes from the color channel of one pixel to the next
+ uint32_t rowStride; ///< Distance in bytes from the first value of one row of the image to
+ /// the first value of the next row.
+} AHardwareBuffer_Plane;
+
+/**
+ * Holds all image planes that contain the pixel data.
+ */
+typedef struct AHardwareBuffer_Planes {
+ uint32_t planeCount; ///< Number of distinct planes
+ AHardwareBuffer_Plane planes[4]; ///< Array of image planes
+} AHardwareBuffer_Planes;
+
+/**
* Opaque handle for a native hardware buffer.
*/
typedef struct AHardwareBuffer AHardwareBuffer;
@@ -323,7 +349,7 @@
AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
/**
* Acquire a reference on the given AHardwareBuffer object.
- *
+ *
* This prevents the object from being deleted until the last reference
* is removed.
*/
@@ -396,6 +422,34 @@
int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
/**
+ * Lock a potentially multi-planar AHardwareBuffer for direct CPU access.
+ *
+ * This function is similar to AHardwareBuffer_lock, but can lock multi-planar
+ * formats. The locked planes are returned in the \a outPlanes argument. Note,
+ * that multi-planar should not be confused with multi-layer images, which this
+ * locking function does not support.
+ *
+ * YUV formats are always represented by three separate planes of data, one for
+ * each color plane. The order of planes in the array is guaranteed such that
+ * plane #0 is always Y, plane #1 is always U (Cb), and plane #2 is always V
+ * (Cr). All other formats are represented by a single plane.
+ *
+ * Additional information always accompanies the buffers, describing the row
+ * stride and the pixel stride for each plane.
+ *
+ * In case the buffer cannot be locked, \a outPlanes will contain zero planes.
+ *
+ * See the AHardwareBuffer_lock documentation for all other locking semantics.
+ *
+ * \return 0 on success. -EINVAL if \a buffer is NULL, the usage flags
+ * are not a combination of AHARDWAREBUFFER_USAGE_CPU_*, or the buffer
+ * has more than one layer. Error number if the lock fails for any other
+ * reason.
+ */
+int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage,
+ int32_t fence, const ARect* rect, AHardwareBuffer_Planes* outPlanes) __INTRODUCED_IN(29);
+
+/**
* Unlock the AHardwareBuffer from direct CPU access.
*
* Must be called after all changes to the buffer are completed by the
diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h
index 6c9ec34..3392d7f 100644
--- a/libs/nativewindow/include/vndk/hardware_buffer.h
+++ b/libs/nativewindow/include/vndk/hardware_buffer.h
@@ -73,8 +73,6 @@
AHARDWAREBUFFER_FORMAT_RAW_OPAQUE = 0x24,
/* same as HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED */
AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED = 0x22,
- /* same as HAL_PIXEL_FORMAT_YCBCR_420_888 */
- AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23,
/* same as HAL_PIXEL_FORMAT_YCBCR_422_SP */
AHARDWAREBUFFER_FORMAT_YCbCr_422_SP = 0x10,
/* same as HAL_PIXEL_FORMAT_YCRCB_420_SP */
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
index 604665b..da91a97 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -78,15 +78,14 @@
BufferHubStatus ret;
sp<IBufferClient> client;
BufferTraits bufferTraits;
- IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& status, const auto& outClient,
- const auto& outTraits) {
+ IBufferHub::allocateBuffer_cb allocCb = [&](const auto& status, const auto& outClient,
+ const auto& outTraits) {
ret = status;
client = std::move(outClient);
bufferTraits = std::move(outTraits);
};
- if (!bufferhub->allocateBuffer(desc, static_cast<uint32_t>(userMetadataSize), alloc_cb)
- .isOk()) {
+ if (!bufferhub->allocateBuffer(desc, static_cast<uint32_t>(userMetadataSize), allocCb).isOk()) {
ALOGE("%s: allocateBuffer transaction failed!", __FUNCTION__);
return;
} else if (ret != BufferHubStatus::NO_ERROR) {
@@ -115,8 +114,8 @@
BufferHubStatus ret;
sp<IBufferClient> client;
BufferTraits bufferTraits;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& status, const auto& outClient,
- const auto& outTraits) {
+ IBufferHub::importBuffer_cb importCb = [&](const auto& status, const auto& outClient,
+ const auto& outTraits) {
ret = status;
client = std::move(outClient);
bufferTraits = std::move(outTraits);
@@ -124,7 +123,7 @@
// hidl_handle(native_handle_t*) simply creates a raw pointer reference withouth ownership
// transfer.
- if (!bufferhub->importBuffer(hidl_handle(token.get()->handle()), import_cb).isOk()) {
+ if (!bufferhub->importBuffer(hidl_handle(token.get()->handle()), importCb).isOk()) {
ALOGE("%s: importBuffer transaction failed!", __FUNCTION__);
return;
} else if (ret != BufferHubStatus::NO_ERROR) {
@@ -210,9 +209,9 @@
// Populate shortcuts to the atomics in metadata.
auto metadataHeader = mMetadata.metadataHeader();
- mBufferState = &metadataHeader->buffer_state;
- mFenceState = &metadataHeader->fence_state;
- mActiveClientsBitMask = &metadataHeader->active_clients_bit_mask;
+ mBufferState = &metadataHeader->bufferState;
+ mFenceState = &metadataHeader->fenceState;
+ mActiveClientsBitMask = &metadataHeader->activeClientsBitMask;
// The C++ standard recommends (but does not require) that lock-free atomic operations are
// also address-free, that is, suitable for communication between processes using shared
// memory.
@@ -230,7 +229,7 @@
mClientStateMask = clientBitMask;
// TODO(b/112012161) Set up shared fences.
- ALOGD("%s: id=%d, buffer_state=%" PRIx32 ".", __FUNCTION__, mId,
+ ALOGD("%s: id=%d, mBufferState=%" PRIx32 ".", __FUNCTION__, mId,
mBufferState->load(std::memory_order_acquire));
return 0;
}
@@ -336,12 +335,12 @@
hidl_handle token;
BufferHubStatus ret;
- IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
+ IBufferClient::duplicate_cb dupCb = [&](const auto& outToken, const auto& status) {
token = std::move(outToken);
ret = status;
};
- if (!mBufferClient->duplicate(dup_cb).isOk()) {
+ if (!mBufferClient->duplicate(dupCb).isOk()) {
ALOGE("%s: duplicate transaction failed!", __FUNCTION__);
return nullptr;
} else if (ret != BufferHubStatus::NO_ERROR) {
diff --git a/libs/ui/include/ui/BufferHubBuffer.h b/libs/ui/include/ui/BufferHubBuffer.h
index 5c09032..5ba189c 100644
--- a/libs/ui/include/ui/BufferHubBuffer.h
+++ b/libs/ui/include/ui/BufferHubBuffer.h
@@ -57,7 +57,7 @@
const BufferHubEventFd& eventFd() const { return mEventFd; }
- // Returns the current value of MetadataHeader::buffer_state.
+ // Returns the current value of MetadataHeader::bufferState.
uint32_t bufferState() const { return mBufferState->load(std::memory_order_acquire); }
// A state mask which is unique to a buffer hub client among all its siblings sharing the same
diff --git a/libs/ui/include/ui/BufferHubDefs.h b/libs/ui/include/ui/BufferHubDefs.h
index 722a060..10f274f 100644
--- a/libs/ui/include/ui/BufferHubDefs.h
+++ b/libs/ui/include/ui/BufferHubDefs.h
@@ -32,7 +32,7 @@
// Single buffer clients (up to 16) ownership signal.
// 32-bit atomic unsigned int.
// Each client takes 2 bits. The first bit locates in the first 16 bits of
-// buffer_state; the second bit locates in the last 16 bits of buffer_state.
+// bufferState; the second bit locates in the last 16 bits of bufferState.
// Client states:
// Gained state 11. Exclusive write state.
// Posted state 10.
@@ -64,9 +64,9 @@
// Returns true if any of the client is in gained state.
static inline bool isAnyClientGained(uint32_t state) {
- uint32_t high_bits = state >> kMaxNumberOfClients;
- uint32_t low_bits = state & kLowbitsMask;
- return high_bits == low_bits && low_bits != 0U;
+ uint32_t highBits = state >> kMaxNumberOfClients;
+ uint32_t lowBits = state & kLowbitsMask;
+ return highBits == lowBits && lowBits != 0U;
}
// Returns true if the input client is in gained state.
@@ -76,34 +76,34 @@
// Returns true if any of the client is in posted state.
static inline bool isAnyClientPosted(uint32_t state) {
- uint32_t high_bits = state >> kMaxNumberOfClients;
- uint32_t low_bits = state & kLowbitsMask;
- uint32_t posted_or_acquired = high_bits ^ low_bits;
- return posted_or_acquired & high_bits;
+ uint32_t highBits = state >> kMaxNumberOfClients;
+ uint32_t lowBits = state & kLowbitsMask;
+ uint32_t postedOrAcquired = highBits ^ lowBits;
+ return postedOrAcquired & highBits;
}
// Returns true if the input client is in posted state.
static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
- uint32_t client_bits = state & client_bit_mask;
- if (client_bits == 0U) return false;
- uint32_t low_bits = client_bits & kLowbitsMask;
- return low_bits == 0U;
+ uint32_t clientBits = state & client_bit_mask;
+ if (clientBits == 0U) return false;
+ uint32_t lowBits = clientBits & kLowbitsMask;
+ return lowBits == 0U;
}
// Return true if any of the client is in acquired state.
static inline bool isAnyClientAcquired(uint32_t state) {
- uint32_t high_bits = state >> kMaxNumberOfClients;
- uint32_t low_bits = state & kLowbitsMask;
- uint32_t posted_or_acquired = high_bits ^ low_bits;
- return posted_or_acquired & low_bits;
+ uint32_t highBits = state >> kMaxNumberOfClients;
+ uint32_t lowBits = state & kLowbitsMask;
+ uint32_t postedOrAcquired = highBits ^ lowBits;
+ return postedOrAcquired & lowBits;
}
// Return true if the input client is in acquired state.
static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
- uint32_t client_bits = state & client_bit_mask;
- if (client_bits == 0U) return false;
- uint32_t high_bits = client_bits & kHighBitsMask;
- return high_bits == 0U;
+ uint32_t clientBits = state & client_bit_mask;
+ if (clientBits == 0U) return false;
+ uint32_t highBits = clientBits & kHighBitsMask;
+ return highBits == 0U;
}
// Returns true if the input client is in released state.
@@ -114,12 +114,12 @@
// Returns the next available buffer client's client_state_masks.
// @params union_bits. Union of all existing clients' client_state_masks.
static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
- uint32_t low_union = union_bits & kLowbitsMask;
- if (low_union == kLowbitsMask) return 0U;
- uint32_t incremented = low_union + 1U;
- uint32_t difference = incremented ^ low_union;
- uint32_t new_low_bit = (difference + 1U) >> 1;
- return new_low_bit + (new_low_bit << kMaxNumberOfClients);
+ uint32_t lowUnion = union_bits & kLowbitsMask;
+ if (lowUnion == kLowbitsMask) return 0U;
+ uint32_t incremented = lowUnion + 1U;
+ uint32_t difference = incremented ^ lowUnion;
+ uint32_t newLowBit = (difference + 1U) >> 1;
+ return newLowBit + (newLowBit << kMaxNumberOfClients);
}
struct __attribute__((aligned(8))) MetadataHeader {
@@ -129,22 +129,22 @@
// platform (include Apps and vendor HAL).
// Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
- // buffer_state.
- std::atomic<uint32_t> buffer_state;
+ // bufferState.
+ std::atomic<uint32_t> bufferState;
- // Every client takes up one bit in fence_state. Only the lower 32 bits are valid. The upper 32
+ // Every client takes up one bit in fenceState. Only the lower 32 bits are valid. The upper 32
// bits are there for easier manipulation, but the value should be ignored.
- std::atomic<uint32_t> fence_state;
+ std::atomic<uint32_t> fenceState;
// Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
- // active_clients_bit_mask.
- std::atomic<uint32_t> active_clients_bit_mask;
+ // activeClientsBitMask.
+ std::atomic<uint32_t> activeClientsBitMask;
// Explicit padding 4 bytes.
uint32_t padding;
// The index of the buffer queue where the buffer belongs to.
- uint64_t queue_index;
+ uint64_t queueIndex;
// Public data format, which should be updated with caution. See more details in dvr_api.h
DvrNativeBufferMetadata metadata;
diff --git a/libs/ui/tests/BufferHubMetadata_test.cpp b/libs/ui/tests/BufferHubMetadata_test.cpp
index f02c4fc..eb978ca 100644
--- a/libs/ui/tests/BufferHubMetadata_test.cpp
+++ b/libs/ui/tests/BufferHubMetadata_test.cpp
@@ -51,7 +51,7 @@
// Check if the newly allocated buffer is initialized in released state (i.e.
// state equals to 0U).
- EXPECT_TRUE(mh1->buffer_state.load() == 0U);
+ EXPECT_TRUE(mh1->bufferState.load() == 0U);
EXPECT_TRUE(m2.isValid());
BufferHubDefs::MetadataHeader* mh2 = m2.metadataHeader();
@@ -59,7 +59,7 @@
// Check if the newly allocated buffer is initialized in released state (i.e.
// state equals to 0U).
- EXPECT_TRUE(mh2->buffer_state.load() == 0U);
+ EXPECT_TRUE(mh2->bufferState.load() == 0U);
}
TEST_F(BufferHubMetadataTest, MoveMetadataInvalidatesOldOne) {
diff --git a/libs/vr/libbufferhub/buffer_hub_base.cpp b/libs/vr/libbufferhub/buffer_hub_base.cpp
index b28d101..17930b4 100644
--- a/libs/vr/libbufferhub/buffer_hub_base.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_base.cpp
@@ -122,15 +122,15 @@
// are mapped from shared memory as an atomic object. The std::atomic's
// constructor will not be called so that the original value stored in the
// memory region will be preserved.
- buffer_state_ = &metadata_header_->buffer_state;
+ buffer_state_ = &metadata_header_->bufferState;
ALOGD_IF(TRACE,
"BufferHubBase::ImportBuffer: id=%d, buffer_state=%" PRIx32 ".",
id(), buffer_state_->load(std::memory_order_acquire));
- fence_state_ = &metadata_header_->fence_state;
+ fence_state_ = &metadata_header_->fenceState;
ALOGD_IF(TRACE,
"BufferHubBase::ImportBuffer: id=%d, fence_state=%" PRIx32 ".", id(),
fence_state_->load(std::memory_order_acquire));
- active_clients_bit_mask_ = &metadata_header_->active_clients_bit_mask;
+ active_clients_bit_mask_ = &metadata_header_->activeClientsBitMask;
ALOGD_IF(
TRACE,
"BufferHubBase::ImportBuffer: id=%d, active_clients_bit_mask=%" PRIx32
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
index fa39d08..8a490d9 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
@@ -97,8 +97,8 @@
uint32_t usage() const { return buffer_.usage(); }
uint32_t layer_count() const { return buffer_.layer_count(); }
- uint64_t GetQueueIndex() const { return metadata_header_->queue_index; }
- void SetQueueIndex(uint64_t index) { metadata_header_->queue_index = index; }
+ uint64_t GetQueueIndex() const { return metadata_header_->queueIndex; }
+ void SetQueueIndex(uint64_t index) { metadata_header_->queueIndex = index; }
protected:
explicit BufferHubBase(LocalChannelHandle channel);
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index ade08e7..7a3472f 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -241,8 +241,8 @@
MetadataHeader* metadataHeader =
const_cast<BufferHubMetadata*>(&node->metadata())->metadataHeader();
- const uint32_t state = metadataHeader->buffer_state.load(std::memory_order_acquire);
- const uint64_t index = metadataHeader->queue_index;
+ const uint32_t state = metadataHeader->bufferState.load(std::memory_order_acquire);
+ const uint64_t index = metadataHeader->queueIndex;
stream << std::right;
stream << std::setw(6) << /*Id=*/node->id();
diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp
index 1efb27e..04ca649 100644
--- a/services/bufferhub/BufferNode.cpp
+++ b/services/bufferhub/BufferNode.cpp
@@ -15,9 +15,9 @@
// Using placement new here to reuse shared memory instead of new allocation
// Initialize the atomic variables to zero.
BufferHubDefs::MetadataHeader* metadataHeader = mMetadata.metadataHeader();
- mBufferState = new (&metadataHeader->buffer_state) std::atomic<uint32_t>(0);
- mFenceState = new (&metadataHeader->fence_state) std::atomic<uint32_t>(0);
- mActiveClientsBitMask = new (&metadataHeader->active_clients_bit_mask) std::atomic<uint32_t>(0);
+ mBufferState = new (&metadataHeader->bufferState) std::atomic<uint32_t>(0);
+ mFenceState = new (&metadataHeader->fenceState) std::atomic<uint32_t>(0);
+ mActiveClientsBitMask = new (&metadataHeader->activeClientsBitMask) std::atomic<uint32_t>(0);
// The C++ standard recommends (but does not require) that lock-free atomic operations are
// also address-free, that is, suitable for communication between processes using shared
// memory.
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 9702fb2..7ff8b20 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -2673,7 +2673,7 @@
policyFlags |= POLICY_FLAG_TRUSTED;
android::base::Timer t;
- mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
+ mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
std::to_string(t.duration().count()).c_str());
@@ -2821,6 +2821,7 @@
size_t pointerCount = motionEvent->getPointerCount();
const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
int32_t actionButton = motionEvent->getActionButton();
+ int32_t displayId = motionEvent->getDisplayId();
if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
return INPUT_EVENT_INJECTION_FAILED;
}
@@ -2828,7 +2829,7 @@
if (!(policyFlags & POLICY_FLAG_FILTERED)) {
nsecs_t eventTime = motionEvent->getEventTime();
android::base::Timer t;
- mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
+ mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
std::to_string(t.duration().count()).c_str());
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 2d8df5c..595b01d 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -245,7 +245,8 @@
* This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
* should be dispatched to applications.
*/
- virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
+ virtual void interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
+ uint32_t& policyFlags) = 0;
/* Allows the policy a chance to intercept a key before dispatching. */
virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token,
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index f84aa34..1a1ae21 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -4550,7 +4550,8 @@
mPointerController->setButtonState(mCurrentRawState.buttonState);
mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex,
- mCurrentCookedState.cookedPointerData.touchingIdBits);
+ mCurrentCookedState.cookedPointerData.touchingIdBits,
+ mViewport.displayId);
}
if (!mCurrentMotionAborted) {
@@ -5314,7 +5315,8 @@
if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
mPointerController->setSpots(mPointerGesture.currentGestureCoords,
mPointerGesture.currentGestureIdToIndex,
- mPointerGesture.currentGestureIdBits);
+ mPointerGesture.currentGestureIdBits,
+ mPointerController->getDisplayId());
}
} else {
mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index bc0f1f9..0ff28e4 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -94,7 +94,7 @@
* pressed (not hovering).
*/
virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
- BitSet32 spotIdBits) = 0;
+ BitSet32 spotIdBits, int32_t displayId) = 0;
/* Removes all spots. */
virtual void clearSpots() = 0;
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 0f987c3..3b6fe52 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -138,7 +138,7 @@
virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
}
- virtual void interceptMotionBeforeQueueing(nsecs_t, uint32_t&) {
+ virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
}
virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 84c5ad6..fbacb9b 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -103,6 +103,10 @@
return mDisplayId;
}
+ const std::map<int32_t, std::vector<int32_t>>& getSpots() {
+ return mSpotsByDisplay;
+ }
+
private:
virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
*outMinX = mMinX;
@@ -130,11 +134,22 @@
virtual void setPresentation(Presentation) {
}
- virtual void setSpots(const PointerCoords*, const uint32_t*, BitSet32) {
+ virtual void setSpots(const PointerCoords*, const uint32_t*, BitSet32 spotIdBits,
+ int32_t displayId) {
+ std::vector<int32_t> newSpots;
+ // Add spots for fingers that are down.
+ for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
+ newSpots.push_back(id);
+ }
+
+ mSpotsByDisplay[displayId] = newSpots;
}
virtual void clearSpots() {
}
+
+ std::map<int32_t, std::vector<int32_t>> mSpotsByDisplay;
};
@@ -228,6 +243,10 @@
mConfig.pointerCapture = enabled;
}
+ void setShowTouches(bool enabled) {
+ mConfig.showTouches = enabled;
+ }
+
private:
DisplayViewport createDisplayViewport(int32_t displayId, int32_t width, int32_t height,
int32_t orientation, const std::string& uniqueId, std::optional<uint8_t> physicalPort,
@@ -6315,4 +6334,85 @@
ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
}
+TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
+ // Setup the first touch screen device.
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ prepareAxes(POSITION | ID | SLOT);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ addMapperAndConfigure(mapper);
+
+ // Create the second touch screen device, and enable multi fingers.
+ const std::string USB2 = "USB2";
+ const int32_t SECOND_DEVICE_ID = 2;
+ InputDeviceIdentifier identifier;
+ identifier.name = DEVICE_NAME;
+ identifier.location = USB2;
+ InputDevice* device2 = new InputDevice(mFakeContext, SECOND_DEVICE_ID, DEVICE_GENERATION,
+ DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
+ mFakeEventHub->addDevice(SECOND_DEVICE_ID, DEVICE_NAME, 0 /*classes*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->setAbsoluteAxisValue(SECOND_DEVICE_ID, ABS_MT_SLOT, 0 /*value*/);
+ mFakeEventHub->addConfigurationProperty(SECOND_DEVICE_ID, String8("touch.deviceType"),
+ String8("touchScreen"));
+
+ // Setup the second touch screen device.
+ MultiTouchInputMapper* mapper2 = new MultiTouchInputMapper(device2);
+ device2->addMapper(mapper2);
+ device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/);
+ device2->reset(ARBITRARY_TIME);
+
+ // Setup PointerController.
+ sp<FakePointerController> fakePointerController = new FakePointerController();
+ mFakePolicy->setPointerController(mDevice->getId(), fakePointerController);
+ mFakePolicy->setPointerController(SECOND_DEVICE_ID, fakePointerController);
+
+ // Setup policy for associated displays and show touches.
+ const uint8_t hdmi1 = 0;
+ const uint8_t hdmi2 = 1;
+ mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
+ mFakePolicy->addInputPortAssociation(USB2, hdmi2);
+ mFakePolicy->setShowTouches(true);
+
+ // Create displays.
+ prepareDisplay(DISPLAY_ORIENTATION_0, hdmi1);
+ prepareSecondaryDisplay(ViewportType::VIEWPORT_EXTERNAL, hdmi2);
+
+ // Default device will reconfigure above, need additional reconfiguration for another device.
+ device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
+ InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+
+ // Two fingers down at default display.
+ int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
+ processPosition(mapper, x1, y1);
+ processId(mapper, 1);
+ processSlot(mapper, 1);
+ processPosition(mapper, x2, y2);
+ processId(mapper, 2);
+ processSync(mapper);
+
+ std::map<int32_t, std::vector<int32_t>>::const_iterator iter =
+ fakePointerController->getSpots().find(DISPLAY_ID);
+ ASSERT_TRUE(iter != fakePointerController->getSpots().end());
+ ASSERT_EQ(size_t(2), iter->second.size());
+
+ // Two fingers down at second display.
+ processPosition(mapper2, x1, y1);
+ processId(mapper2, 1);
+ processSlot(mapper2, 1);
+ processPosition(mapper2, x2, y2);
+ processId(mapper2, 2);
+ processSync(mapper2);
+
+ iter = fakePointerController->getSpots().find(SECONDARY_DISPLAY_ID);
+ ASSERT_TRUE(iter != fakePointerController->getSpots().end());
+ ASSERT_EQ(size_t(2), iter->second.size());
+}
+
} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
index 6e6f3c0..130ab1d 100644
--- a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
@@ -303,7 +303,7 @@
}
// add all known HDR combinations
- for (auto intent : sHdrRenderIntents) {
+ for (auto intent : hdrRenderIntents) {
for (auto mode : sHdrColorModes) {
addColorMode(hwcColorModes, mode, intent);
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
index d20fdda..9215884 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
@@ -146,6 +146,8 @@
return ProfileFactory()
.setHasWideColorGamut(true)
.addHdrType(Hdr::HDR10)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE)
.addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, VendorRenderIntent)
.build();
}
@@ -154,6 +156,8 @@
return ProfileFactory()
.setHasWideColorGamut(true)
.addHdrType(Hdr::HDR10)
+ .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::COLORIMETRIC)
+ .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::ENHANCE)
.addColorModeRenderIntent(ColorMode::SRGB, VendorRenderIntent)
.build();
}
@@ -166,6 +170,16 @@
.build();
}
+ static impl::DisplayColorProfile createProfileWithDisplayP3ColorModeSupport() {
+ return ProfileFactory()
+ .setHasWideColorGamut(true)
+ .addHdrType(Hdr::HLG)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_P3, RenderIntent::ENHANCE)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_P3, VendorRenderIntent)
+ .build();
+ }
+
private:
bool mHasWideColorGamut = false;
std::vector<Hdr> mSupportedHdrTypes;
@@ -348,7 +362,7 @@
auto profile = ProfileFactory::createProfileWithBT2020ColorModeSupport();
EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
- EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
+ EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
@@ -358,7 +372,7 @@
auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
- EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
+ EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
EXPECT_TRUE(profile.hasRenderIntent(VendorRenderIntent));
@@ -414,47 +428,37 @@
void checkGetBestColorMode(
DisplayColorProfile& profile,
- const std::array<std::tuple<Dataspace, ColorMode, RenderIntent>, 25>& expected) {
+ const std::array<std::tuple<Dataspace, ColorMode, RenderIntent>, 15>& expected) {
using ArgsType = std::tuple<Dataspace, RenderIntent>;
// These are the combinations of dataspaces and render intents that could be
// passed to RenderSurface::getBestColorMode()
- const std::array<std::tuple<Dataspace, RenderIntent>, 25> kArgs = {
+ const std::array<std::tuple<Dataspace, RenderIntent>, 15> kArgs = {
/* clang-format off */
// Non-HDR combinations
/* 0 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
/* 1 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::ENHANCE},
- /* 2 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::TONE_MAP_COLORIMETRIC}, // Vendor explicit setting
- /* 3 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::TONE_MAP_ENHANCE}, // Vendor explicit setting
- /* 4 */ ArgsType{Dataspace::DISPLAY_BT2020, VendorRenderIntent}, // Vendor explicit setting
+ /* 2 */ ArgsType{Dataspace::DISPLAY_BT2020, VendorRenderIntent}, // Vendor explicit setting
- /* 5 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::COLORIMETRIC},
- /* 6 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::ENHANCE},
- /* 7 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::TONE_MAP_COLORIMETRIC}, // Vendor explicit setting
- /* 8 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::TONE_MAP_ENHANCE}, // Vendor explicit setting
- /* 9 */ ArgsType{Dataspace::DISPLAY_P3, VendorRenderIntent}, // Vendor explicit setting
+ /* 3 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 4 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::ENHANCE},
+ /* 5 */ ArgsType{Dataspace::DISPLAY_P3, VendorRenderIntent}, // Vendor explicit setting
- /* 10 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::COLORIMETRIC},
- /* 11 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::ENHANCE},
- /* 12 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::TONE_MAP_COLORIMETRIC}, // Vendor explicit setting
- /* 13 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::TONE_MAP_ENHANCE}, // Vendor explicit setting
- /* 14 */ ArgsType{Dataspace::V0_SRGB, VendorRenderIntent}, // Vendor explicit setting
+ /* 6 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::COLORIMETRIC},
+ /* 7 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::ENHANCE},
+ /* 8 */ ArgsType{Dataspace::V0_SRGB, VendorRenderIntent}, // Vendor explicit setting
// HDR combinations
- /* 15 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_COLORIMETRIC},
- /* 16 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_ENHANCE},
- /* 17 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::COLORIMETRIC}, // Vendor explicit setting
- /* 18 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::ENHANCE}, // Vendor explicit setting
- /* 19 */ ArgsType{Dataspace::BT2020_PQ, VendorRenderIntent}, // Vendor explicit setting
+ /* 9 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_COLORIMETRIC},
+ /* 10 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_ENHANCE},
+ /* 11 */ ArgsType{Dataspace::BT2020_PQ, VendorRenderIntent}, // Vendor explicit setting
- /* 20 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_COLORIMETRIC},
- /* 21 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_ENHANCE},
- /* 22 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::COLORIMETRIC}, // Vendor explicit setting
- /* 23 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::ENHANCE}, // Vendor explicit setting
- /* 24 */ ArgsType{Dataspace::BT2020_HLG, VendorRenderIntent}, // Vendor explicit setting
+ /* 12 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_COLORIMETRIC},
+ /* 13 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_ENHANCE},
+ /* 14 */ ArgsType{Dataspace::BT2020_HLG, VendorRenderIntent}, // Vendor explicit setting
/* clang-format on */
};
@@ -473,38 +477,28 @@
// Note: This table of expected values goes with the table of arguments
// used in checkGetBestColorMode.
using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
- std::array<Result, 25> expectedResults = {
+ std::array<Result, 15> expectedResults = {
/* clang-format off */
/* 0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
/* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 10 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 15 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 16 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
- /* 20 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 21 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
/* clang-format on */
};
@@ -517,37 +511,27 @@
// Note: This table of expected values goes with the table of arguments
// used in checkGetBestColorMode.
using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
- std::array<Result, 25> expectedResults = {
+ std::array<Result, 15> expectedResults = {
/* clang-format off */
/* 0 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 1 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+ /* 1 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
/* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 5 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+ /* 3 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+ /* 4 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
+ /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 6 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 7 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
/* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 9 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
/* 10 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 11 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 12 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+ /* 13 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
/* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
- /* 15 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 16 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
- /* 20 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 21 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* clang-format on */
};
@@ -560,37 +544,61 @@
// Note: This table of expected values goes with the table of arguments
// used in checkGetBestColorMode.
using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
- std::array<Result, 25> expectedResults = {
+ std::array<Result, 15> expectedResults = {
/* clang-format off */
/* 0 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+ /* 1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+ /* 2 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
- /* 5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 3 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+ /* 5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+
/* 6 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+ /* 7 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+ /* 8 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+ /* 9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
/* 10 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 11 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 14 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+ /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 15 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 16 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 12 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 13 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* clang-format on */
+ };
- /* 20 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 21 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ checkGetBestColorMode(profile, expectedResults);
+}
+
+TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasDisplayP3Support) {
+ auto profile = ProfileFactory::createProfileWithDisplayP3ColorModeSupport();
+
+ // Note: This table of expected values goes with the table of arguments
+ // used in checkGetBestColorMode.
+ using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
+ std::array<Result, 15> expectedResults = {
+ /* clang-format off */
+ /* 0 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 1 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
+ // TODO(b/124317977): There is bug here.
+ /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 3 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 4 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
+ /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 6 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 7 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
+ /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 9 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 10 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 12 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 13 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* clang-format on */
};
@@ -603,37 +611,27 @@
// Note: This table of expected values goes with the table of arguments
// used in checkGetBestColorMode.
using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
- std::array<Result, 25> expectedResults = {
+ std::array<Result, 15> expectedResults = {
/* clang-format off */
/* 0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
/* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 9 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+ /* 10 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+ /* 11 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
- /* 15 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
- /* 16 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
- /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
- /* 20 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
- /* 21 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
- /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 12 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+ /* 13 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+ /* 14 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
/* clang-format on */
};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b68f053..3abd6a7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -773,6 +773,9 @@
property_get("persist.sys.sf.native_mode", value, "0");
mDisplayColorSetting = static_cast<DisplayColorSetting>(atoi(value));
+
+ property_get("persist.sys.sf.color_mode", value, "0");
+ mForceColorMode = static_cast<ColorMode>(atoi(value));
}
void SurfaceFlinger::startBootAnim() {
@@ -2491,6 +2494,17 @@
auto* profile = display->getCompositionDisplay()->getDisplayColorProfile();
+ switch (mForceColorMode) {
+ case ColorMode::SRGB:
+ bestDataSpace = Dataspace::V0_SRGB;
+ break;
+ case ColorMode::DISPLAY_P3:
+ bestDataSpace = Dataspace::DISPLAY_P3;
+ break;
+ default:
+ break;
+ }
+
// respect hdrDataSpace only when there is no legacy HDR support
const bool isHdr =
hdrDataSpace != Dataspace::UNKNOWN && !profile->hasLegacyHdrSupport(hdrDataSpace);
@@ -3078,6 +3092,7 @@
});
}
+ commitInputWindowCommands();
commitTransaction();
}
@@ -3108,6 +3123,11 @@
mInputFlinger->setInputWindows(inputHandles);
}
+void SurfaceFlinger::commitInputWindowCommands() {
+ mInputWindowCommands.merge(mPendingInputWindowCommands);
+ mPendingInputWindowCommands.clear();
+}
+
void SurfaceFlinger::executeInputWindowCommands() {
for (const auto& transferTouchFocusCommand : mInputWindowCommands.transferTouchFocusCommands) {
if (transferTouchFocusCommand.fromToken != nullptr &&
@@ -3686,7 +3706,7 @@
if (!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
break;
}
- applyTransactionState(states, displays, flags, mInputWindowCommands);
+ applyTransactionState(states, displays, flags, mPendingInputWindowCommands);
transactionQueue.pop();
}
@@ -4154,7 +4174,7 @@
flags |= eTraversalNeeded;
}
- mInputWindowCommands.merge(inputWindowCommands);
+ mPendingInputWindowCommands.merge(inputWindowCommands);
return flags;
}
@@ -4370,7 +4390,7 @@
d.width = 0;
d.height = 0;
displays.add(d);
- setTransactionState(state, displays, 0, nullptr, mInputWindowCommands, -1);
+ setTransactionState(state, displays, 0, nullptr, mPendingInputWindowCommands, -1);
setPowerModeInternal(display, HWC_POWER_MODE_NORMAL);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4393077..728e8d3 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -534,10 +534,11 @@
void handleMessageRefresh();
void handleTransaction(uint32_t transactionFlags);
- void handleTransactionLocked(uint32_t transactionFlags);
+ void handleTransactionLocked(uint32_t transactionFlags) REQUIRES(mStateLock);
void updateInputFlinger();
void updateInputWindowInfo();
+ void commitInputWindowCommands() REQUIRES(mStateLock);
void executeInputWindowCommands();
void updateCursorAsync();
@@ -566,7 +567,8 @@
const Vector<ComposerState>& states);
uint32_t setClientStateLocked(const ComposerState& composerState);
uint32_t setDisplayStateLocked(const DisplayState& s);
- uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands);
+ uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands)
+ REQUIRES(mStateLock);
/* ------------------------------------------------------------------------
* Layer management
@@ -1088,6 +1090,15 @@
DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::ENHANCED;
+ // Color mode forced by setting persist.sys.sf.color_mode, it must:
+ // 1. not be NATIVE color mode, NATIVE color mode means no forced color mode;
+ // 2. be one of the supported color modes returned by hardware composer, otherwise
+ // it will not be respected.
+ // persist.sys.sf.color_mode will only take effect when persist.sys.sf.native_mode
+ // is not set to 1.
+ // This property can be used to force SurfaceFlinger to always pick a certain color mode.
+ ui::ColorMode mForceColorMode = ui::ColorMode::NATIVE;
+
ui::Dataspace mDefaultCompositionDataspace;
ui::Dataspace mWideColorGamutCompositionDataspace;
@@ -1134,6 +1145,8 @@
/* ------------------------------------------------------------------------ */
sp<IInputFlinger> mInputFlinger;
+ InputWindowCommands mPendingInputWindowCommands GUARDED_BY(mStateLock);
+ // Should only be accessed by the main thread.
InputWindowCommands mInputWindowCommands;
ui::DisplayPrimaries mInternalDisplayPrimaries;
diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc
index 5bec502..aea602b 100644
--- a/services/surfaceflinger/surfaceflinger.rc
+++ b/services/surfaceflinger/surfaceflinger.rc
@@ -2,7 +2,6 @@
class core animation
user system
group graphics drmrpc readproc
- updatable
onrestart restart zygote
writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 53b867f..959126e 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -248,6 +248,7 @@
}
auto handleTransactionLocked(uint32_t transactionFlags) {
+ Mutex::Autolock _l(mFlinger->mStateLock);
return mFlinger->handleTransactionLocked(transactionFlags);
}
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index f3e54a0..b49d894 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -91,11 +91,10 @@
// Using placement new here to reuse shared memory instead of new allocation
// and also initialize the value to zero.
- buffer_state_ =
- new (&metadata_header_->buffer_state) std::atomic<uint32_t>(0);
- fence_state_ = new (&metadata_header_->fence_state) std::atomic<uint32_t>(0);
+ buffer_state_ = new (&metadata_header_->bufferState) std::atomic<uint32_t>(0);
+ fence_state_ = new (&metadata_header_->fenceState) std::atomic<uint32_t>(0);
active_clients_bit_mask_ =
- new (&metadata_header_->active_clients_bit_mask) std::atomic<uint32_t>(0);
+ new (&metadata_header_->activeClientsBitMask) std::atomic<uint32_t>(0);
// Producer channel is never created after consumer channel, and one buffer
// only have one fixed producer for now. Thus, it is correct to assume
@@ -183,7 +182,7 @@
buffer_.height(), buffer_.layer_count(), buffer_.format(),
buffer_.usage(),
buffer_state_->load(std::memory_order_acquire),
- signaled_mask, metadata_header_->queue_index);
+ signaled_mask, metadata_header_->queueIndex);
}
void ProducerChannel::HandleImpulse(Message& message) {
@@ -547,7 +546,7 @@
"%s: orphaned buffer detected during the this acquire/release cycle: "
"id=%d orphaned=0x%" PRIx32 " queue_index=%" PRId64 ".",
__FUNCTION__, buffer_id(), orphaned_consumer_bit_mask_,
- metadata_header_->queue_index);
+ metadata_header_->queueIndex);
orphaned_consumer_bit_mask_ = 0;
}
}
@@ -581,7 +580,7 @@
"consumer_state_mask=%" PRIx32 " queue_index=%" PRId64
" buffer_state=%" PRIx32 " fence_state=%" PRIx32 ".",
__FUNCTION__, buffer_id(), consumer_state_mask,
- metadata_header_->queue_index,
+ metadata_header_->queueIndex,
buffer_state_->load(std::memory_order_acquire),
fence_state_->load(std::memory_order_acquire));
}
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index fed8481..206c8eb 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -84,8 +84,8 @@
"libutils",
"libcutils",
"libz",
- "libnativebridge",
- "libnativeloader",
+ "libnativebridge_lazy",
+ "libnativeloader_lazy",
"libnativewindow",
"android.hardware.graphics.common@1.0",
],