From 28dbde32c2fa4a19a8bf3875e1756fb2a787695c Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Mon, 2 Mar 2015 22:12:37 -0800 Subject: [PATCH 1/2] Surface: Permit an IProducerListener on connect This change allows clients of Surface to provide an IProducerListener callback object to Surface::connect, which will be passed down to the underlying IGraphicBufferProducer Change-Id: I5ea5229bf3a329bf02c6bd20e7247039c75d136b --- include/gui/Surface.h | 1 + libs/gui/Surface.cpp | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/gui/Surface.h b/include/gui/Surface.h index f2cf018a9..5e752b50f 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -157,6 +157,7 @@ protected: virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); + virtual int connect(int api, const sp& listener); virtual int connect(int api); virtual int disconnect(int api); virtual int setBufferCount(int bufferCount); diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 0e2baa28f..9bd0d0dd5 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -546,9 +546,13 @@ int Surface::dispatchSetSidebandStream(va_list args) { } int Surface::connect(int api) { + static sp listener = new DummyProducerListener(); + return connect(api, listener); +} + +int Surface::connect(int api, const sp& listener) { ATRACE_CALL(); ALOGV("Surface::connect"); - static sp listener = new DummyProducerListener(); Mutex::Autolock lock(mMutex); IGraphicBufferProducer::QueueBufferOutput output; int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); From 63e8376d0baf494f9dd7e866d8dedb26ffab2a6b Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Thu, 19 Feb 2015 16:10:43 -0800 Subject: [PATCH 2/2] Add dataSpace to buffer queues; remove old format enums. - Wire up new dataSpace parameter through buffer queue stack - Update tests to include the parameter - Switch eglApi to using dataSpace to indicate sRGB gamma/linear difference - Remove RAW_SENSOR in favor of RAW16 - Remove use of sRGB format enums - Add default dataspace to buffer queue core - Add query for default dataspace Change-Id: I070bd2e7c56506055c419004c29e2e3feac725df --- include/gui/BufferItem.h | 5 ++++ include/gui/BufferItemConsumer.h | 6 ++++ include/gui/BufferQueueConsumer.h | 7 +++++ include/gui/BufferQueueCore.h | 5 ++++ include/gui/CpuConsumer.h | 7 +++++ include/gui/GLConsumer.h | 1 + include/gui/IGraphicBufferConsumer.h | 13 ++++++++ include/gui/IGraphicBufferProducer.h | 20 ++++++++----- include/gui/Surface.h | 7 +++++ include/ui/PixelFormat.h | 2 -- libs/gui/BufferItem.cpp | 5 ++++ libs/gui/BufferItemConsumer.cpp | 6 ++++ libs/gui/BufferQueueConsumer.cpp | 9 ++++++ libs/gui/BufferQueueCore.cpp | 1 + libs/gui/BufferQueueProducer.cpp | 18 ++++++++--- libs/gui/CpuConsumer.cpp | 12 ++++++-- libs/gui/GLConsumer.cpp | 6 ++++ libs/gui/IGraphicBufferConsumer.cpp | 28 ++++++++++++++++- libs/gui/IGraphicBufferProducer.cpp | 4 +++ libs/gui/StreamSplitter.cpp | 1 + libs/gui/Surface.cpp | 22 ++++++++++++-- libs/gui/tests/BufferQueue_test.cpp | 15 ++++++---- libs/gui/tests/CpuConsumer_test.cpp | 24 +++++++-------- .../gui/tests/IGraphicBufferProducer_test.cpp | 9 ++++++ libs/gui/tests/SRGB_test.cpp | 15 ++++++---- libs/gui/tests/StreamSplitter_test.cpp | 3 ++ libs/gui/tests/Surface_test.cpp | 22 ++++++++++++++ libs/ui/PixelFormat.cpp | 3 -- opengl/libs/EGL/eglApi.cpp | 30 +++++++++++-------- .../DisplayHardware/HWComposer.cpp | 2 -- .../DisplayHardware/VirtualDisplaySurface.cpp | 6 ++-- services/surfaceflinger/Layer.cpp | 1 - 32 files changed, 254 insertions(+), 61 deletions(-) diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h index 01b6ff4b5..c7a8bc927 100644 --- a/include/gui/BufferItem.h +++ b/include/gui/BufferItem.h @@ -78,6 +78,11 @@ class BufferItem : public Flattenable { // automatically when the buffer was queued. bool mIsAutoTimestamp; + // mDataSpace is the current dataSpace value for this buffer slot. This gets + // set by queueBuffer each time this slot is queued. The meaning of the + // dataSpace is format-dependent. + android_dataspace mDataSpace; + // mFrameNumber is the number of the queued frame for this slot. uint64_t mFrameNumber; diff --git a/include/gui/BufferItemConsumer.h b/include/gui/BufferItemConsumer.h index 5494ff1f3..9afb9550c 100644 --- a/include/gui/BufferItemConsumer.h +++ b/include/gui/BufferItemConsumer.h @@ -96,6 +96,12 @@ class BufferItemConsumer: public ConsumerBase // GraphicBuffers of a defaultFormat if no format is specified // in dequeueBuffer status_t setDefaultBufferFormat(uint32_t defaultFormat); + + // setDefaultBufferDataSpace allows the BufferQueue to create + // GraphicBuffers of a defaultDataSpace if no data space is specified + // in queueBuffer. + // The initial default is HAL_DATASPACE_UNKNOWN + status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace); }; } // namespace android diff --git a/include/gui/BufferQueueConsumer.h b/include/gui/BufferQueueConsumer.h index 1912ed03d..a78e54936 100644 --- a/include/gui/BufferQueueConsumer.h +++ b/include/gui/BufferQueueConsumer.h @@ -129,6 +129,13 @@ public: // initial default is HAL_PIXEL_FORMAT_RGBA_8888. virtual status_t setDefaultBufferFormat(uint32_t defaultFormat); + // setDefaultBufferDataSpace allows the BufferQueue to create + // GraphicBuffers of a defaultDataSpace if no data space is specified + // in queueBuffer. + // The initial default is HAL_DATASPACE_UNKNOWN + virtual status_t setDefaultBufferDataSpace( + android_dataspace defaultDataSpace); + // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer. // These are merged with the bits passed to dequeueBuffer. The values are // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0. diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h index 1050e3b6c..afacaa074 100644 --- a/include/gui/BufferQueueCore.h +++ b/include/gui/BufferQueueCore.h @@ -209,6 +209,11 @@ private: // in dequeueBuffer if a width and height of 0 are specified. int mDefaultHeight; + // mDefaultBufferDataSpace holds the default dataSpace of queued buffers. + // It is used in queueBuffer if a dataspace of 0 (HAL_DATASPACE_UNKNOWN) + // is specified. + android_dataspace mDefaultBufferDataSpace; + // mDefaultMaxBufferCount is the default limit on the number of buffers that // will be allocated at one time. This default limit is set by the consumer. // The limit (as opposed to the default limit) may be overriden by the diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h index 4c6822a09..12b8cf03e 100644 --- a/include/gui/CpuConsumer.h +++ b/include/gui/CpuConsumer.h @@ -53,6 +53,7 @@ class CpuConsumer : public ConsumerBase uint32_t transform; uint32_t scalingMode; int64_t timestamp; + android_dataspace dataSpace; uint64_t frameNumber; // this is the same as format, except for formats that are compatible with // a flexible format (e.g. HAL_PIXEL_FORMAT_YCbCr_420_888). In the latter @@ -91,6 +92,12 @@ class CpuConsumer : public ConsumerBase // HAL_PIXEL_FORMAT_RGBA_8888. status_t setDefaultBufferFormat(uint32_t defaultFormat); + // setDefaultBufferDataSpace allows the BufferQueue to create + // GraphicBuffers of a defaultDataSpace if no data space is specified + // in queueBuffer. + // The initial default is HAL_DATASPACE_UNKNOWN + status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace); + // Gets the next graphics buffer from the producer and locks it for CPU use, // filling out the passed-in locked buffer structure with the native pointer // and metadata. Returns BAD_VALUE if no new buffer is available, and diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h index f91fe46d9..578583381 100644 --- a/include/gui/GLConsumer.h +++ b/include/gui/GLConsumer.h @@ -198,6 +198,7 @@ public: // These functions call the corresponding BufferQueue implementation // so the refactoring can proceed smoothly status_t setDefaultBufferFormat(uint32_t defaultFormat); + status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace); status_t setConsumerUsageBits(uint32_t usage); status_t setTransformHint(uint32_t hint); diff --git a/include/gui/IGraphicBufferConsumer.h b/include/gui/IGraphicBufferConsumer.h index 15f51fe8c..04f25436c 100644 --- a/include/gui/IGraphicBufferConsumer.h +++ b/include/gui/IGraphicBufferConsumer.h @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -85,6 +86,10 @@ public: // automatically when the buffer was queued. bool mIsAutoTimestamp; + // mDataSpace is the current dataSpace for this buffer slot. This gets + // set by queueBuffer each time this slot is queued. + android_dataspace mDataSpace; + // mFrameNumber is the number of the queued frame for this slot. uint64_t mFrameNumber; @@ -286,6 +291,14 @@ public: // Return of a value other than NO_ERROR means an unknown error has occurred. virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) = 0; + // setDefaultBufferDataSpace is a request to the producer to provide buffers + // of the indicated dataSpace. The producer may ignore this request. + // The initial default is HAL_DATASPACE_UNKNOWN. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) = 0; + // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer. // These are merged with the bits passed to dequeueBuffer. The values are // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0. diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h index 4e9e81070..9d2813240 100644 --- a/include/gui/IGraphicBufferProducer.h +++ b/include/gui/IGraphicBufferProducer.h @@ -267,6 +267,7 @@ public: inline QueueBufferInput(const Parcel& parcel); // timestamp - a monotonically increasing value in nanoseconds // isAutoTimestamp - if the timestamp was synthesized at queue time + // dataSpace - description of the contents, interpretation depends on format // crop - a crop rectangle that's used as a hint to the consumer // scalingMode - a set of flags from NATIVE_WINDOW_SCALING_* in // transform - a set of flags from NATIVE_WINDOW_TRANSFORM_* in @@ -276,17 +277,21 @@ public: // sticky - the sticky transform set in Surface (only used by the LEGACY // camera mode). inline QueueBufferInput(int64_t timestamp, bool isAutoTimestamp, - const Rect& crop, int scalingMode, uint32_t transform, bool async, - const sp& fence, uint32_t sticky = 0) - : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp), crop(crop), - scalingMode(scalingMode), transform(transform), stickyTransform(sticky), - async(async), fence(fence) { } + android_dataspace dataSpace, const Rect& crop, int scalingMode, + uint32_t transform, bool async, const sp& fence, + uint32_t sticky = 0) + : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp), + dataSpace(dataSpace), crop(crop), scalingMode(scalingMode), + transform(transform), stickyTransform(sticky), + async(async), fence(fence) { } inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp, - Rect* outCrop, int* outScalingMode, uint32_t* outTransform, - bool* outAsync, sp* outFence, + android_dataspace* outDataSpace, + Rect* outCrop, int* outScalingMode, + uint32_t* outTransform, bool* outAsync, sp* outFence, uint32_t* outStickyTransform = NULL) const { *outTimestamp = timestamp; *outIsAutoTimestamp = bool(isAutoTimestamp); + *outDataSpace = dataSpace; *outCrop = crop; *outScalingMode = scalingMode; *outTransform = transform; @@ -306,6 +311,7 @@ public: private: int64_t timestamp; int isAutoTimestamp; + android_dataspace dataSpace; Rect crop; int scalingMode; uint32_t transform; diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 5e752b50f..f49f6da6c 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -146,6 +146,7 @@ private: int dispatchLock(va_list args); int dispatchUnlockAndPost(va_list args); int dispatchSetSidebandStream(va_list args); + int dispatchSetBuffersDataSpace(va_list args); protected: virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); @@ -168,6 +169,7 @@ protected: virtual int setBuffersTransform(int transform); virtual int setBuffersStickyTransform(int transform); virtual int setBuffersTimestamp(int64_t timestamp); + virtual int setBuffersDataSpace(android_dataspace dataSpace); virtual int setCrop(Rect const* rect); virtual int setUsage(uint32_t reqUsage); @@ -223,6 +225,11 @@ private: // a timestamp is auto-generated when queueBuffer is called. int64_t mTimestamp; + // mDataSpace is the buffer dataSpace that will be used for the next buffer + // queue operation. It defaults to HAL_DATASPACE_UNKNOWN, which + // means that the buffer contains some type of color data. + android_dataspace mDataSpace; + // mCrop is the crop rectangle that will be used for the next buffer // that gets queued. It is set by calling setCrop. Rect mCrop; diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h index 7e469453f..f998b3444 100644 --- a/include/ui/PixelFormat.h +++ b/include/ui/PixelFormat.h @@ -63,8 +63,6 @@ enum { PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit ARGB PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit ARGB - PIXEL_FORMAT_sRGB_A_8888 = HAL_PIXEL_FORMAT_sRGB_A_8888, // 4x8-bit sRGB + A - PIXEL_FORMAT_sRGB_X_8888 = HAL_PIXEL_FORMAT_sRGB_X_8888, // 4x8-bit sRGB, no A }; typedef int32_t PixelFormat; diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp index e6fc79119..f3a37cae9 100644 --- a/libs/gui/BufferItem.cpp +++ b/libs/gui/BufferItem.cpp @@ -28,6 +28,7 @@ BufferItem::BufferItem() : mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mTimestamp(0), mIsAutoTimestamp(false), + mDataSpace(HAL_DATASPACE_UNKNOWN), mFrameNumber(0), mSlot(INVALID_BUFFER_SLOT), mIsDroppable(false), @@ -47,6 +48,7 @@ BufferItem::operator IGraphicBufferConsumer::BufferItem() const { bufferItem.mScalingMode = mScalingMode; bufferItem.mTimestamp = mTimestamp; bufferItem.mIsAutoTimestamp = mIsAutoTimestamp; + bufferItem.mDataSpace = mDataSpace; bufferItem.mFrameNumber = mFrameNumber; bufferItem.mBuf = mSlot; bufferItem.mIsDroppable = mIsDroppable; @@ -61,6 +63,7 @@ size_t BufferItem::getPodSize() const { sizeof(mScalingMode) + sizeof(mTimestamp) + sizeof(mIsAutoTimestamp) + + sizeof(mDataSpace) + sizeof(mFrameNumber) + sizeof(mSlot) + sizeof(mIsDroppable) + @@ -131,6 +134,7 @@ status_t BufferItem::flatten( FlattenableUtils::write(buffer, size, mScalingMode); FlattenableUtils::write(buffer, size, mTimestamp); FlattenableUtils::write(buffer, size, mIsAutoTimestamp); + FlattenableUtils::write(buffer, size, mDataSpace); FlattenableUtils::write(buffer, size, mFrameNumber); FlattenableUtils::write(buffer, size, mSlot); FlattenableUtils::write(buffer, size, mIsDroppable); @@ -173,6 +177,7 @@ status_t BufferItem::unflatten( FlattenableUtils::read(buffer, size, mScalingMode); FlattenableUtils::read(buffer, size, mTimestamp); FlattenableUtils::read(buffer, size, mIsAutoTimestamp); + FlattenableUtils::read(buffer, size, mDataSpace); FlattenableUtils::read(buffer, size, mFrameNumber); FlattenableUtils::read(buffer, size, mSlot); FlattenableUtils::read(buffer, size, mIsDroppable); diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp index fe50c55f5..9a4119598 100644 --- a/libs/gui/BufferItemConsumer.cpp +++ b/libs/gui/BufferItemConsumer.cpp @@ -110,4 +110,10 @@ status_t BufferItemConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { return mConsumer->setDefaultBufferFormat(defaultFormat); } +status_t BufferItemConsumer::setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) { + Mutex::Autolock _l(mMutex); + return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); +} + } // namespace android diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index 36e3c06a5..541643020 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -496,6 +496,15 @@ status_t BufferQueueConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { return NO_ERROR; } +status_t BufferQueueConsumer::setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) { + ATRACE_CALL(); + BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace); + Mutex::Autolock lock(mCore->mMutex); + mCore->mDefaultBufferDataSpace = defaultDataSpace; + return NO_ERROR; +} + status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) { ATRACE_CALL(); BQ_LOGV("setConsumerUsageBits: %#x", usage); diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp index ec1e63112..edebc4553 100644 --- a/libs/gui/BufferQueueCore.cpp +++ b/libs/gui/BufferQueueCore.cpp @@ -60,6 +60,7 @@ BufferQueueCore::BufferQueueCore(const sp& allocator) : mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888), mDefaultWidth(1), mDefaultHeight(1), + mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN), mDefaultMaxBufferCount(2), mMaxAcquiredBufferCount(1), mBufferHasBeenQueued(false), diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 16b974741..8dc3d0bb5 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -516,14 +516,15 @@ status_t BufferQueueProducer::queueBuffer(int slot, int64_t timestamp; bool isAutoTimestamp; + android_dataspace dataSpace; Rect crop; int scalingMode; uint32_t transform; uint32_t stickyTransform; bool async; sp fence; - input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, &transform, - &async, &fence, &stickyTransform); + input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode, + &transform, &async, &fence, &stickyTransform); if (fence == NULL) { BQ_LOGE("queueBuffer: fence is NULL"); @@ -579,9 +580,9 @@ status_t BufferQueueProducer::queueBuffer(int slot, return BAD_VALUE; } - BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 + BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d" " crop=[%d,%d,%d,%d] transform=%#x scale=%s", - slot, mCore->mFrameCounter + 1, timestamp, + slot, mCore->mFrameCounter + 1, timestamp, dataSpace, crop.left, crop.top, crop.right, crop.bottom, transform, BufferItem::scalingModeName(scalingMode)); @@ -595,6 +596,11 @@ status_t BufferQueueProducer::queueBuffer(int slot, return BAD_VALUE; } + // Override UNKNOWN dataspace with consumer default + if (dataSpace == HAL_DATASPACE_UNKNOWN) { + dataSpace = mCore->mDefaultBufferDataSpace; + } + mSlots[slot].mFence = fence; mSlots[slot].mBufferState = BufferSlot::QUEUED; ++mCore->mFrameCounter; @@ -609,6 +615,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, item.mScalingMode = scalingMode; item.mTimestamp = timestamp; item.mIsAutoTimestamp = isAutoTimestamp; + item.mDataSpace = dataSpace; item.mFrameNumber = mCore->mFrameCounter; item.mSlot = slot; item.mFence = fence; @@ -756,6 +763,9 @@ int BufferQueueProducer::query(int what, int *outValue) { case NATIVE_WINDOW_CONSUMER_USAGE_BITS: value = mCore->mConsumerUsageBits; break; + case NATIVE_WINDOW_DEFAULT_DATASPACE: + value = static_cast(mCore->mDefaultBufferDataSpace); + break; default: return BAD_VALUE; } diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp index c541ff4a7..abf2523f5 100644 --- a/libs/gui/CpuConsumer.cpp +++ b/libs/gui/CpuConsumer.cpp @@ -67,6 +67,13 @@ status_t CpuConsumer::setDefaultBufferFormat(uint32_t defaultFormat) return mConsumer->setDefaultBufferFormat(defaultFormat); } +status_t CpuConsumer::setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) +{ + Mutex::Autolock _l(mMutex); + return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); +} + static bool isPossiblyYUV(PixelFormat format) { switch ((int)format) { case HAL_PIXEL_FORMAT_RGBA_8888: @@ -74,11 +81,9 @@ static bool isPossiblyYUV(PixelFormat format) { case HAL_PIXEL_FORMAT_RGB_888: case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_sRGB_A_8888: - case HAL_PIXEL_FORMAT_sRGB_X_8888: case HAL_PIXEL_FORMAT_Y8: case HAL_PIXEL_FORMAT_Y16: - case HAL_PIXEL_FORMAT_RAW16: // same as HAL_PIXEL_FORMAT_RAW_SENSOR + case HAL_PIXEL_FORMAT_RAW16: case HAL_PIXEL_FORMAT_RAW10: case HAL_PIXEL_FORMAT_RAW_OPAQUE: case HAL_PIXEL_FORMAT_BLOB: @@ -200,6 +205,7 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { nativeBuffer->transform = b.mTransform; nativeBuffer->scalingMode = b.mScalingMode; nativeBuffer->timestamp = b.mTimestamp; + nativeBuffer->dataSpace = b.mDataSpace; nativeBuffer->frameNumber = b.mFrameNumber; nativeBuffer->dataCb = reinterpret_cast(ycbcr.cb); diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index 318c08788..99e57dd18 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -1009,6 +1009,12 @@ status_t GLConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { return mConsumer->setDefaultBufferFormat(defaultFormat); } +status_t GLConsumer::setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) { + Mutex::Autolock lock(mMutex); + return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); +} + status_t GLConsumer::setConsumerUsageBits(uint32_t usage) { Mutex::Autolock lock(mMutex); usage |= DEFAULT_USAGE_FLAGS; diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp index f6d087d3b..e498a15b9 100644 --- a/libs/gui/IGraphicBufferConsumer.cpp +++ b/libs/gui/IGraphicBufferConsumer.cpp @@ -39,6 +39,7 @@ IGraphicBufferConsumer::BufferItem::BufferItem() : mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mTimestamp(0), mIsAutoTimestamp(false), + mDataSpace(HAL_DATASPACE_UNKNOWN), mFrameNumber(0), mBuf(INVALID_BUFFER_SLOT), mIsDroppable(false), @@ -53,6 +54,7 @@ size_t IGraphicBufferConsumer::BufferItem::getPodSize() const { sizeof(mScalingMode) + sizeof(mTimestamp) + sizeof(mIsAutoTimestamp) + + sizeof(mDataSpace) + sizeof(mFrameNumber) + sizeof(mBuf) + sizeof(mIsDroppable) + @@ -133,6 +135,7 @@ status_t IGraphicBufferConsumer::BufferItem::flatten( FlattenableUtils::write(buffer, size, mScalingMode); FlattenableUtils::write(buffer, size, mTimestamp); writeBoolAsInt(buffer, size, mIsAutoTimestamp); + FlattenableUtils::write(buffer, size, mDataSpace); FlattenableUtils::write(buffer, size, mFrameNumber); FlattenableUtils::write(buffer, size, mBuf); writeBoolAsInt(buffer, size, mIsDroppable); @@ -175,6 +178,7 @@ status_t IGraphicBufferConsumer::BufferItem::unflatten( FlattenableUtils::read(buffer, size, mScalingMode); FlattenableUtils::read(buffer, size, mTimestamp); mIsAutoTimestamp = readBoolFromInt(buffer, size); + FlattenableUtils::read(buffer, size, mDataSpace); FlattenableUtils::read(buffer, size, mFrameNumber); FlattenableUtils::read(buffer, size, mBuf); mIsDroppable = readBoolFromInt(buffer, size); @@ -200,6 +204,7 @@ enum { SET_MAX_ACQUIRED_BUFFER_COUNT, SET_CONSUMER_NAME, SET_DEFAULT_BUFFER_FORMAT, + SET_DEFAULT_BUFFER_DATA_SPACE, SET_CONSUMER_USAGE_BITS, SET_TRANSFORM_HINT, GET_SIDEBAND_STREAM, @@ -369,6 +374,19 @@ public: return reply.readInt32(); } + virtual status_t setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) { + Parcel data, reply; + data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); + data.writeInt32(static_cast(defaultDataSpace)); + status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE, + data, &reply); + if (result != NO_ERROR) { + return result; + } + return reply.readInt32(); + } + virtual status_t setConsumerUsageBits(uint32_t usage) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); @@ -523,7 +541,15 @@ status_t BnGraphicBufferConsumer::onTransact( status_t result = setDefaultBufferFormat(defaultFormat); reply->writeInt32(result); return NO_ERROR; - } break; + } + case SET_DEFAULT_BUFFER_DATA_SPACE: { + CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); + android_dataspace defaultDataSpace = + static_cast(data.readInt32()); + status_t result = setDefaultBufferDataSpace(defaultDataSpace); + reply->writeInt32(result); + return NO_ERROR; + } case SET_CONSUMER_USAGE_BITS: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); uint32_t usage = data.readInt32(); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 1e28f9bb8..4cfbaae5a 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -432,6 +432,7 @@ IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const { return sizeof(timestamp) + sizeof(isAutoTimestamp) + + sizeof(dataSpace) + sizeof(crop) + sizeof(scalingMode) + sizeof(transform) @@ -452,6 +453,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten( } FlattenableUtils::write(buffer, size, timestamp); FlattenableUtils::write(buffer, size, isAutoTimestamp); + FlattenableUtils::write(buffer, size, dataSpace); FlattenableUtils::write(buffer, size, crop); FlattenableUtils::write(buffer, size, scalingMode); FlattenableUtils::write(buffer, size, transform); @@ -466,6 +468,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten( size_t minNeeded = sizeof(timestamp) + sizeof(isAutoTimestamp) + + sizeof(dataSpace) + sizeof(crop) + sizeof(scalingMode) + sizeof(transform) @@ -478,6 +481,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten( FlattenableUtils::read(buffer, size, timestamp); FlattenableUtils::read(buffer, size, isAutoTimestamp); + FlattenableUtils::read(buffer, size, dataSpace); FlattenableUtils::read(buffer, size, crop); FlattenableUtils::read(buffer, size, scalingMode); FlattenableUtils::read(buffer, size, transform); diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp index 5f39905e5..80e611d72 100644 --- a/libs/gui/StreamSplitter.cpp +++ b/libs/gui/StreamSplitter.cpp @@ -141,6 +141,7 @@ void StreamSplitter::onFrameAvailable(const BufferItem& /* item */) { IGraphicBufferProducer::QueueBufferInput queueInput( bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp, + bufferItem.mDataSpace, bufferItem.mCrop, bufferItem.mScalingMode, bufferItem.mTransform, bufferItem.mIsDroppable, bufferItem.mFence); diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 9bd0d0dd5..4bd42c976 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -64,6 +64,7 @@ Surface::Surface( mReqFormat = 0; mReqUsage = 0; mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; + mDataSpace = HAL_DATASPACE_UNKNOWN; mCrop.clear(); mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; mTransform = 0; @@ -318,8 +319,8 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { sp fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); IGraphicBufferProducer::QueueBufferOutput output; IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, - crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero, - fence, mStickyTransform); + mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform, + mSwapIntervalZero, fence, mStickyTransform); status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); if (err != OK) { ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); @@ -448,6 +449,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_SIDEBAND_STREAM: res = dispatchSetSidebandStream(args); break; + case NATIVE_WINDOW_SET_BUFFERS_DATASPACE: + res = dispatchSetBuffersDataSpace(args); + break; default: res = NAME_NOT_FOUND; break; @@ -545,6 +549,12 @@ int Surface::dispatchSetSidebandStream(va_list args) { return OK; } +int Surface::dispatchSetBuffersDataSpace(va_list args) { + android_dataspace dataspace = + static_cast(va_arg(args, int)); + return setBuffersDataSpace(dataspace); +} + int Surface::connect(int api) { static sp listener = new DummyProducerListener(); return connect(api, listener); @@ -735,6 +745,14 @@ int Surface::setBuffersTimestamp(int64_t timestamp) return NO_ERROR; } +int Surface::setBuffersDataSpace(android_dataspace dataSpace) +{ + ALOGV("Surface::setBuffersDataSpace"); + Mutex::Autolock lock(mMutex); + mDataSpace = dataSpace; + return NO_ERROR; +} + void Surface::freeAllBuffers() { for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { mSlots[i].buffer = 0; diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 96de11f20..8db923d7a 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -124,7 +124,8 @@ TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) { *dataIn = 0x12345678; ASSERT_EQ(OK, buffer->unlock()); - IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput input(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); @@ -150,7 +151,8 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { int slot; sp fence; sp buf; - IGraphicBufferProducer::QueueBufferInput qbi(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput qbi(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); BufferQueue::BufferItem item; @@ -244,7 +246,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL)); ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer)); - IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput input(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output)); @@ -273,7 +276,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput input(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); @@ -338,7 +342,8 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { *dataIn = 0x12345678; ASSERT_EQ(OK, buffer->unlock()); - IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), + IGraphicBufferProducer::QueueBufferInput input(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp index abd372449..0beca92de 100644 --- a/libs/gui/tests/CpuConsumer_test.cpp +++ b/libs/gui/tests/CpuConsumer_test.cpp @@ -166,7 +166,7 @@ void checkPixel(const CpuConsumer::LockedBuffer &buf, uint32_t x, uint32_t y, uint32_t r, uint32_t g=0, uint32_t b=0) { // Ignores components that don't exist for given pixel switch(buf.format) { - case HAL_PIXEL_FORMAT_RAW_SENSOR: { + case HAL_PIXEL_FORMAT_RAW16: { String8 msg; uint16_t *bPtr = (uint16_t*)buf.data; bPtr += y * buf.stride + x; @@ -429,7 +429,7 @@ void checkBayerRawBuffer(const CpuConsumer::LockedBuffer &buf) { void checkAnyBuffer(const CpuConsumer::LockedBuffer &buf, int format) { switch (format) { - case HAL_PIXEL_FORMAT_RAW_SENSOR: + case HAL_PIXEL_FORMAT_RAW16: checkBayerRawBuffer(buf); break; case HAL_PIXEL_FORMAT_Y8: @@ -505,7 +505,7 @@ void produceOneFrame(const sp& anw, case HAL_PIXEL_FORMAT_YV12: fillYV12Buffer(img, params.width, params.height, *stride); break; - case HAL_PIXEL_FORMAT_RAW_SENSOR: + case HAL_PIXEL_FORMAT_RAW16: fillBayerRawBuffer(img, params.width, params.height, buf->getStride()); break; case HAL_PIXEL_FORMAT_Y8: @@ -537,7 +537,7 @@ void produceOneFrame(const sp& anw, ASSERT_NO_ERROR(err, "queueBuffer error:"); }; -// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not +// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not // supported on all devices. TEST_P(CpuConsumerTest, FromCpuSingle) { status_t err; @@ -571,7 +571,7 @@ TEST_P(CpuConsumerTest, FromCpuSingle) { mCC->unlockBuffer(b); } -// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not +// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not // supported on all devices. TEST_P(CpuConsumerTest, FromCpuManyInQueue) { status_t err; @@ -614,7 +614,7 @@ TEST_P(CpuConsumerTest, FromCpuManyInQueue) { } } -// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not +// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not // supported on all devices. TEST_P(CpuConsumerTest, FromCpuLockMax) { status_t err; @@ -710,12 +710,12 @@ CpuConsumerTestParams y16TestSets[] = { }; CpuConsumerTestParams rawTestSets[] = { - { 512, 512, 1, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 512, 512, 3, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 100, 100, 1, HAL_PIXEL_FORMAT_RAW_SENSOR}, - { 100, 100, 3, HAL_PIXEL_FORMAT_RAW_SENSOR}, + { 512, 512, 1, HAL_PIXEL_FORMAT_RAW16}, + { 512, 512, 3, HAL_PIXEL_FORMAT_RAW16}, + { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW16}, + { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW16}, + { 100, 100, 1, HAL_PIXEL_FORMAT_RAW16}, + { 100, 100, 3, HAL_PIXEL_FORMAT_RAW16}, }; CpuConsumerTestParams rgba8888TestSets[] = { diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp index 8d5fd8f58..c904a6bd4 100644 --- a/libs/gui/tests/IGraphicBufferProducer_test.cpp +++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp @@ -57,6 +57,7 @@ namespace { // Parameters for a generic "valid" input for queueBuffer. const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611; const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false; +const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN; const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT); const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0; const int QUEUE_BUFFER_INPUT_TRANSFORM = 0; @@ -126,6 +127,7 @@ protected: QueueBufferInputBuilder() { timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP; isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP; + dataSpace = QUEUE_BUFFER_INPUT_DATASPACE; crop = QUEUE_BUFFER_INPUT_RECT; scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE; transform = QUEUE_BUFFER_INPUT_TRANSFORM; @@ -137,6 +139,7 @@ protected: return IGraphicBufferProducer::QueueBufferInput( timestamp, isAutoTimestamp, + dataSpace, crop, scalingMode, transform, @@ -154,6 +157,11 @@ protected: return *this; } + QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) { + this->dataSpace = dataSpace; + return *this; + } + QueueBufferInputBuilder& setCrop(Rect crop) { this->crop = crop; return *this; @@ -182,6 +190,7 @@ protected: private: int64_t timestamp; bool isAutoTimestamp; + android_dataspace dataSpace; Rect crop; int scalingMode; uint32_t transform; diff --git a/libs/gui/tests/SRGB_test.cpp b/libs/gui/tests/SRGB_test.cpp index 2d5b8aaf2..c7d851dba 100644 --- a/libs/gui/tests/SRGB_test.cpp +++ b/libs/gui/tests/SRGB_test.cpp @@ -212,10 +212,11 @@ protected: ASSERT_EQ(GL_NO_ERROR, glGetError()); } - void checkLockedBuffer(PixelFormat format) { + void checkLockedBuffer(PixelFormat format, android_dataspace dataSpace) { ASSERT_EQ(mLockedBuffer.format, format); ASSERT_EQ(mLockedBuffer.width, DISPLAY_WIDTH); ASSERT_EQ(mLockedBuffer.height, DISPLAY_HEIGHT); + ASSERT_EQ(mLockedBuffer.dataSpace, dataSpace); } static bool withinTolerance(int a, int b) { @@ -333,7 +334,8 @@ private: if (mLockedBuffer.format == outBuffer.format) { memcpy(outBuffer.bits, mLockedBuffer.data, bufferSize); } else { - ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_sRGB_A_8888); + ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_RGBA_8888); + ASSERT_EQ(mLockedBuffer.dataSpace, HAL_DATASPACE_SRGB); ASSERT_EQ(outBuffer.format, PIXEL_FORMAT_RGBA_8888); uint8_t* outPointer = reinterpret_cast(outBuffer.bits); for (int y = 0; y < outBuffer.height; ++y) { @@ -378,7 +380,8 @@ TEST_F(SRGBTest, GLRenderFromSRGBTexture) { // Lock ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer)); - ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888)); + ASSERT_NO_FATAL_FAILURE( + checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN)); // Compare a pixel in the middle of each texture int midSRGBOffset = (DISPLAY_HEIGHT / 4) * mLockedBuffer.stride * @@ -409,7 +412,8 @@ TEST_F(SRGBTest, RenderToSRGBSurface) { // Lock ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer)); - ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888)); + ASSERT_NO_FATAL_FAILURE( + checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN)); // Save the values of the middle pixel for later comparison against SRGB uint8_t values[PIXEL_SIZE] = {}; @@ -458,7 +462,8 @@ TEST_F(SRGBTest, RenderToSRGBSurface) { ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer)); // Make sure we actually got the SRGB buffer on the consumer side - ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_sRGB_A_8888)); + ASSERT_NO_FATAL_FAILURE( + checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_SRGB)); // Verify that the stored value is the same, accounting for RGB/SRGB for (int c = 0; c < PIXEL_SIZE; ++c) { diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp index 4e63a6f4d..429ab6cf6 100644 --- a/libs/gui/tests/StreamSplitter_test.cpp +++ b/libs/gui/tests/StreamSplitter_test.cpp @@ -111,6 +111,7 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) { ASSERT_EQ(OK, buffer->unlock()); IGraphicBufferProducer::QueueBufferInput qbInput(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput)); @@ -177,6 +178,7 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { ASSERT_EQ(OK, buffer->unlock()); IGraphicBufferProducer::QueueBufferInput qbInput(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput)); @@ -234,6 +236,7 @@ TEST_F(StreamSplitterTest, OutputAbandonment) { outputConsumer->consumerDisconnect(); IGraphicBufferProducer::QueueBufferInput qbInput(0, false, + HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput)); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 5e6aeef35..4f878244b 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -155,4 +155,26 @@ TEST_F(SurfaceTest, QueryConsumerUsage) { ASSERT_EQ(TEST_USAGE_FLAGS, flags); } +TEST_F(SurfaceTest, QueryDefaultBuffersDataSpace) { + const android_dataspace TEST_DATASPACE = HAL_DATASPACE_SRGB; + sp producer; + sp consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + sp cpuConsumer = new CpuConsumer(consumer, 1); + + cpuConsumer->setDefaultBufferDataSpace(TEST_DATASPACE); + + sp s = new Surface(producer); + + sp anw(s); + + android_dataspace dataSpace; + + int err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, + reinterpret_cast(&dataSpace)); + + ASSERT_EQ(NO_ERROR, err); + ASSERT_EQ(TEST_DATASPACE, dataSpace); +} + } diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp index 5ce7fba54..93149c0ea 100644 --- a/libs/ui/PixelFormat.cpp +++ b/libs/ui/PixelFormat.cpp @@ -26,8 +26,6 @@ ssize_t bytesPerPixel(PixelFormat format) { case PIXEL_FORMAT_RGBA_8888: case PIXEL_FORMAT_RGBX_8888: case PIXEL_FORMAT_BGRA_8888: - case PIXEL_FORMAT_sRGB_A_8888: - case PIXEL_FORMAT_sRGB_X_8888: return 4; case PIXEL_FORMAT_RGB_888: return 3; @@ -58,4 +56,3 @@ ssize_t bitsPerPixel(PixelFormat format) { // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- - diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 6e77e457b..9d8d5d390 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -381,20 +381,15 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, // Turn linear formats into corresponding sRGB formats when colorspace is // EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear // formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where -// the modification isn't possible, the original format is returned. -static int modifyFormatColorspace(int fmt, EGLint colorspace) { +// the modification isn't possible, the original dataSpace is returned. +static android_dataspace modifyBufferDataspace( android_dataspace dataSpace, + EGLint colorspace) { if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) { - switch (fmt) { - case HAL_PIXEL_FORMAT_sRGB_A_8888: return HAL_PIXEL_FORMAT_RGBA_8888; - case HAL_PIXEL_FORMAT_sRGB_X_8888: return HAL_PIXEL_FORMAT_RGBX_8888; - } + return HAL_DATASPACE_SRGB_LINEAR; } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) { - switch (fmt) { - case HAL_PIXEL_FORMAT_RGBA_8888: return HAL_PIXEL_FORMAT_sRGB_A_8888; - case HAL_PIXEL_FORMAT_RGBX_8888: return HAL_PIXEL_FORMAT_sRGB_X_8888; - } + return HAL_DATASPACE_SRGB; } - return fmt; + return dataSpace; } EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, @@ -452,6 +447,7 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, #else // by default, just pick RGBA_8888 EGLint format = HAL_PIXEL_FORMAT_RGBA_8888; + android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; EGLint a = 0; cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a); @@ -477,7 +473,7 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) { if (*attr == EGL_GL_COLORSPACE_KHR) { if (ENABLE_EGL_KHR_GL_COLORSPACE) { - format = modifyFormatColorspace(format, *(attr+1)); + dataSpace = modifyBufferDataspace(dataSpace, *(attr+1)); } else { // Normally we'd pass through unhandled attributes to // the driver. But in case the driver implements this @@ -501,6 +497,16 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, } } + if (dataSpace != 0) { + int err = native_window_set_buffers_data_space(window, dataSpace); + if (err != 0) { + ALOGE("error setting native window pixel dataSpace: %s (%d)", + strerror(-err), err); + native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); + return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); + } + } + // the EGL spec requires that a new EGLSurface default to swap interval // 1, so explicitly set that on the window here. ANativeWindow* anw = reinterpret_cast(window); diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index edfed491b..77a9a19b3 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -1105,8 +1105,6 @@ static String8 getFormatStr(PixelFormat format) { case PIXEL_FORMAT_RGB_888: return String8("RGB_888"); case PIXEL_FORMAT_RGB_565: return String8("RGB_565"); case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888"); - case PIXEL_FORMAT_sRGB_A_8888: return String8("sRGB_A_8888"); - case PIXEL_FORMAT_sRGB_X_8888: return String8("sRGB_x_8888"); case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: return String8("ImplDef"); default: diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index c3d45ee09..3f603fc7b 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -234,6 +234,7 @@ void VirtualDisplaySurface::onFrameCommitted() { status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot, QueueBufferInput( systemTime(), false /* isAutoTimestamp */, + HAL_DATASPACE_UNKNOWN, Rect(mSinkBufferWidth, mSinkBufferHeight), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */, true /* async*/, @@ -453,12 +454,13 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot, // Extract the GLES release fence for HWC to acquire int64_t timestamp; bool isAutoTimestamp; + android_dataspace dataSpace; Rect crop; int scalingMode; uint32_t transform; bool async; - input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, - &transform, &async, &mFbFence); + input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, + &scalingMode, &transform, &async, &mFbFence); mFbProducerSlot = pslot; mOutputFence = mFbFence; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 5e3dfabb3..fb38524b2 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -766,7 +766,6 @@ bool Layer::getOpacityForFormat(uint32_t format) { switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_sRGB_A_8888: return false; } // in all other case, we have no blending (also for unknown formats)