summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/gui/BufferItem.cpp6
-rw-r--r--libs/gui/BufferQueueProducer.cpp1
-rw-r--r--libs/gui/include/gui/BufferItem.h3
-rw-r--r--services/surfaceflinger/BufferLayer.cpp9
-rw-r--r--services/surfaceflinger/BufferLayerConsumer.cpp7
-rw-r--r--services/surfaceflinger/BufferLayerConsumer.h5
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp5
-rw-r--r--services/surfaceflinger/DisplayDevice.h4
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp39
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h3
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;