diff options
-rw-r--r-- | libs/gui/BufferItem.cpp | 6 | ||||
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 1 | ||||
-rw-r--r-- | libs/gui/include/gui/BufferItem.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/BufferLayerConsumer.cpp | 7 | ||||
-rw-r--r-- | services/surfaceflinger/BufferLayerConsumer.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 5 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 4 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 39 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 3 |
10 files changed, 74 insertions, 8 deletions
diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp index f7409dc344..f50379b3ed 100644 --- a/libs/gui/BufferItem.cpp +++ b/libs/gui/BufferItem.cpp @@ -55,7 +55,8 @@ BufferItem::BufferItem() : mSurfaceDamage(), mAutoRefresh(false), mQueuedBuffer(true), - mIsStale(false) { + mIsStale(false), + mApi(0) { } BufferItem::~BufferItem() {} @@ -84,6 +85,7 @@ size_t BufferItem::getPodSize() const { addAligned(size, mAutoRefresh); addAligned(size, mQueuedBuffer); addAligned(size, mIsStale); + addAligned(size, mApi); return size; } @@ -177,6 +179,7 @@ status_t BufferItem::flatten( writeAligned(buffer, size, mAutoRefresh); writeAligned(buffer, size, mQueuedBuffer); writeAligned(buffer, size, mIsStale); + writeAligned(buffer, size, mApi); return NO_ERROR; } @@ -247,6 +250,7 @@ status_t BufferItem::unflatten( readAligned(buffer, size, mAutoRefresh); readAligned(buffer, size, mQueuedBuffer); readAligned(buffer, size, mIsStale); + readAligned(buffer, size, mApi); return NO_ERROR; } diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index add857c350..e583b40632 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -878,6 +878,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, item.mSurfaceDamage = surfaceDamage; item.mQueuedBuffer = true; item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh; + item.mApi = mCore->mConnectedApi; mStickyTransform = stickyTransform; diff --git a/libs/gui/include/gui/BufferItem.h b/libs/gui/include/gui/BufferItem.h index 7740b9f095..218bb424fb 100644 --- a/libs/gui/include/gui/BufferItem.h +++ b/libs/gui/include/gui/BufferItem.h @@ -127,6 +127,9 @@ class BufferItem : public Flattenable<BufferItem> { // Indicates that this BufferItem contains a stale buffer which has already // been released by the BufferQueue. bool mIsStale; + + // Indicates the API (NATIVE_WINDOW_API_xxx) that queues the buffer. + int mApi; }; } // namespace android diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index d860f58509..ab6a559aad 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -821,8 +821,17 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */, getColor()); engine.setSourceDataSpace(mCurrentState.dataSpace); + + if (mCurrentState.dataSpace == HAL_DATASPACE_BT2020_PQ && + mConsumer->getCurrentApi() == NATIVE_WINDOW_API_MEDIA && + getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102) { + engine.setSourceY410BT2020(true); + } + engine.drawMesh(getBE().mMesh); engine.disableBlending(); + + engine.setSourceY410BT2020(false); } uint32_t BufferLayer::getProducerStickyTransform() const { diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index 8f5c9c740b..4d9b43f52e 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -68,6 +68,7 @@ BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, R mCurrentFrameNumber(0), mCurrentTransformToDisplayInverse(false), mCurrentSurfaceDamage(), + mCurrentApi(0), mDefaultWidth(1), mDefaultHeight(1), mFilteringEnabled(true), @@ -346,6 +347,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, mCurrentFrameNumber = item.mFrameNumber; mCurrentTransformToDisplayInverse = item.mTransformToDisplayInverse; mCurrentSurfaceDamage = item.mSurfaceDamage; + mCurrentApi = item.mApi; computeCurrentTransformMatrixLocked(); @@ -469,6 +471,11 @@ const Region& BufferLayerConsumer::getSurfaceDamage() const { return mCurrentSurfaceDamage; } +int BufferLayerConsumer::getCurrentApi() const { + Mutex::Autolock lock(mMutex); + return mCurrentApi; +} + sp<GraphicBuffer> BufferLayerConsumer::getCurrentBuffer(int* outSlot) const { Mutex::Autolock lock(mMutex); diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h index f473390ea7..a0272b3622 100644 --- a/services/surfaceflinger/BufferLayerConsumer.h +++ b/services/surfaceflinger/BufferLayerConsumer.h @@ -138,6 +138,9 @@ public: // must be called from SF main thread const Region& getSurfaceDamage() const; + // getCurrentApi retrieves the API which queues the current buffer. + int getCurrentApi() const; + // See GLConsumer::setDefaultBufferSize. status_t setDefaultBufferSize(uint32_t width, uint32_t height); @@ -337,6 +340,8 @@ private: // The portion of this surface that has changed since the previous frame Region mCurrentSurfaceDamage; + int mCurrentApi; + uint32_t mDefaultWidth, mDefaultHeight; // mFilteringEnabled indicates whether the transform matrix is computed for diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index d121a86ead..cf70529b53 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -76,7 +76,8 @@ DisplayDevice::DisplayDevice( const wp<IBinder>& displayToken, const sp<DisplaySurface>& displaySurface, const sp<IGraphicBufferProducer>& producer, - bool supportWideColor) + bool supportWideColor, + bool supportHdr) : lastCompositionHadVisibleLayers(false), mFlinger(flinger), mType(type), @@ -100,6 +101,8 @@ DisplayDevice::DisplayDevice( mActiveColorMode = HAL_COLOR_MODE_NATIVE; mDisplayHasWideColor = supportWideColor; + mDisplayHasHdr = supportHdr; + /* * Create our display's surface */ diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 499bf8e6a0..a4706701a8 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -78,7 +78,7 @@ public: const wp<IBinder>& displayToken, const sp<DisplaySurface>& displaySurface, const sp<IGraphicBufferProducer>& producer, - bool supportWideColor); + bool supportWideColor, bool supportHdr); // clang-format on ~DisplayDevice(); @@ -128,6 +128,7 @@ public: status_t beginFrame(bool mustRecompose) const; status_t prepareFrame(HWComposer& hwc); bool getWideColorSupport() const { return mDisplayHasWideColor; } + bool getHdrSupport() const { return mDisplayHasHdr; } void swapBuffers(HWComposer& hwc) const; @@ -235,6 +236,7 @@ private: // Initialized by SurfaceFlinger when the DisplayDevice is created. // Fed to RenderEngine during composition. bool mDisplayHasWideColor; + bool mDisplayHasHdr; }; struct DisplayDeviceState { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a91525d8d0..974a261278 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1041,7 +1041,19 @@ status_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display, std::unique_ptr<HdrCapabilities> capabilities = getBE().mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId()); if (capabilities) { - std::swap(*outCapabilities, *capabilities); + if (displayDevice->getWideColorSupport() && !displayDevice->getHdrSupport()) { + // insert HDR10 as we will force client composition for HDR10 + // layers + std::vector<int32_t> types = capabilities->getSupportedHdrTypes(); + types.push_back(HAL_HDR_HDR10); + + *outCapabilities = HdrCapabilities(types, + capabilities->getDesiredMaxLuminance(), + capabilities->getDesiredMaxAverageLuminance(), + capabilities->getDesiredMinLuminance()); + } else { + *outCapabilities = std::move(*capabilities); + } } else { return BAD_VALUE; } @@ -1793,7 +1805,7 @@ android_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) co } android_dataspace SurfaceFlinger::bestTargetDataSpace( - android_dataspace a, android_dataspace b) const { + android_dataspace a, android_dataspace b, bool hasHdr) const { // Only support sRGB and Display-P3 right now. if (a == HAL_DATASPACE_DISPLAY_P3 || b == HAL_DATASPACE_DISPLAY_P3) { return HAL_DATASPACE_DISPLAY_P3; @@ -1804,6 +1816,9 @@ android_dataspace SurfaceFlinger::bestTargetDataSpace( if (a == HAL_DATASPACE_V0_SCRGB || b == HAL_DATASPACE_V0_SCRGB) { return HAL_DATASPACE_DISPLAY_P3; } + if (!hasHdr && (a == HAL_DATASPACE_BT2020_PQ || b == HAL_DATASPACE_BT2020_PQ)) { + return HAL_DATASPACE_DISPLAY_P3; + } return HAL_DATASPACE_V0_SRGB; } @@ -1885,6 +1900,11 @@ void SurfaceFlinger::setUpHWComposer() { "display %zd: %d", displayId, result); } for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { + if (layer->getDataSpace() == HAL_DATASPACE_BT2020_PQ && + !displayDevice->getHdrSupport()) { + layer->forceClientComposition(hwcId); + } + if (layer->getForceClientComposition(hwcId)) { ALOGV("[%s] Requesting Client composition", layer->getName().string()); layer->setCompositionType(hwcId, HWC2::Composition::Client); @@ -1899,7 +1919,8 @@ void SurfaceFlinger::setUpHWComposer() { android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB; for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { - newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace); + newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace, + displayDevice->getHdrSupport()); ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)", layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(), layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace); @@ -2253,9 +2274,19 @@ void SurfaceFlinger::processDisplayChangesLocked() { useWideColorMode = hasWideColorModes && hasWideColorDisplay; } + bool hasHdrSupport = false; + std::unique_ptr<HdrCapabilities> hdrCapabilities = + getHwComposer().getHdrCapabilities(state.type); + if (hdrCapabilities) { + const std::vector<int32_t> types = hdrCapabilities->getSupportedHdrTypes(); + auto iter = std::find(types.cbegin(), types.cend(), HAL_HDR_HDR10); + hasHdrSupport = iter != types.cend(); + } + sp<DisplayDevice> hw = new DisplayDevice(this, state.type, hwcId, state.isSecure, display, - dispSurface, producer, useWideColorMode); + dispSurface, producer, useWideColorMode, + hasHdrSupport); android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE; if (useWideColorMode) { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 4da0803f67..1349becf13 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -607,7 +607,8 @@ private: // Given a dataSpace, returns the appropriate color_mode to use // to display that dataSpace. android_color_mode pickColorMode(android_dataspace dataSpace) const; - android_dataspace bestTargetDataSpace(android_dataspace a, android_dataspace b) const; + android_dataspace bestTargetDataSpace(android_dataspace a, android_dataspace b, + bool hasHdr) const; mat4 computeSaturationMatrix() const; |