summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-05-24 07:21:37 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-05-24 07:21:37 +0000
commit9ba99577d8abf5841e50d48220008b67ab64ebf5 (patch)
treec2c4f7c4282ad38025c6902024fa2c78ec3c6965
parentb6f150d67de27a6a62836c0799f7cecda70067f5 (diff)
parentdb83ea84ab10d097e692edfe32972eeea7312fd9 (diff)
downloadnative-9ba99577d8abf5841e50d48220008b67ab64ebf5.tar.gz
Snap for 4801384 from db83ea84ab10d097e692edfe32972eeea7312fd9 to pi-release
Change-Id: Iabb9257409efa3b4a240109ce91c13b6aa7350c4
-rw-r--r--cmds/atrace/atrace.cpp14
-rw-r--r--data/etc/aosp_excluded_hardware.xml21
-rw-r--r--libs/binder/BpBinder.cpp4
-rw-r--r--libs/binder/IPCThreadState.cpp38
-rw-r--r--libs/binder/include/binder/IPCThreadState.h8
-rw-r--r--services/surfaceflinger/Android.bp1
-rw-r--r--services/surfaceflinger/BufferLayer.cpp12
-rw-r--r--services/surfaceflinger/ColorLayer.cpp4
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp279
-rw-r--r--services/surfaceflinger/DisplayDevice.h54
-rw-r--r--services/surfaceflinger/Layer.cpp20
-rw-r--r--services/surfaceflinger/Layer.h5
-rw-r--r--services/surfaceflinger/RenderArea.cpp10
-rw-r--r--services/surfaceflinger/RenderArea.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp312
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h6
-rw-r--r--services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp5
17 files changed, 536 insertions, 259 deletions
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 90609379ff..fe9dd568fc 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -58,6 +58,7 @@ using std::string;
#define MAX_SYS_FILES 10
const char* k_traceTagsProperty = "debug.atrace.tags.enableflags";
+const char* k_userInitiatedTraceProperty = "debug.atrace.user_initiated";
const char* k_traceAppsNumberProperty = "debug.atrace.app_number";
const char* k_traceAppsPropertyTemplate = "debug.atrace.app_%d";
@@ -447,6 +448,16 @@ static bool setTraceOverwriteEnable(bool enable)
return setKernelOptionEnable(k_tracingOverwriteEnablePath, enable);
}
+// Set the user initiated trace property
+static bool setUserInitiatedTraceProperty(bool enable)
+{
+ if (!android::base::SetProperty(k_userInitiatedTraceProperty, enable ? "1" : "")) {
+ fprintf(stderr, "error setting user initiated strace system property\n");
+ return false;
+ }
+ return true;
+}
+
// Enable or disable kernel tracing.
static bool setTracingEnabled(bool enable)
{
@@ -840,6 +851,8 @@ static bool setUpKernelTracing()
{
bool ok = true;
+ ok &= setUserInitiatedTraceProperty(true);
+
// Set up the tracing options.
ok &= setCategoriesEnableFromFile(g_categoriesFile);
ok &= setTraceOverwriteEnable(g_traceOverwrite);
@@ -887,6 +900,7 @@ static void cleanUpKernelTracing()
setTraceBufferSizeKB(1);
setPrintTgidEnableIfPresent(false);
setKernelTraceFuncs(NULL);
+ setUserInitiatedTraceProperty(false);
}
// Enable tracing in the kernel.
diff --git a/data/etc/aosp_excluded_hardware.xml b/data/etc/aosp_excluded_hardware.xml
new file mode 100644
index 0000000000..013f278f34
--- /dev/null
+++ b/data/etc/aosp_excluded_hardware.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<permissions>
+ <!-- This should be used to exclude this feature from aosp targets. As aosp configurations
+ may or may not have a valid location provider -->
+ <unavailable-feature name="android.hardware.location.network" />
+</permissions>
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 289433b0bd..c8de373af2 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -150,7 +150,7 @@ BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
- IPCThreadState::self()->incWeakHandle(handle);
+ IPCThreadState::self()->incWeakHandle(handle, this);
}
bool BpBinder::isDescriptorCached() const {
@@ -412,7 +412,7 @@ void BpBinder::onFirstRef()
{
ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
IPCThreadState* ipc = IPCThreadState::self();
- if (ipc) ipc->incStrongHandle(mHandle);
+ if (ipc) ipc->incStrongHandle(mHandle, this);
}
void BpBinder::onLastStrongRef(const void* /*id*/)
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index ba9bf61f8c..fd552b4f4d 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -409,6 +409,15 @@ void IPCThreadState::flushCommands()
if (mProcess->mDriverFD <= 0)
return;
talkWithDriver(false);
+ // The flush could have caused post-write refcount decrements to have
+ // been executed, which in turn could result in BC_RELEASE/BC_DECREFS
+ // being queued in mOut. So flush again, if we need to.
+ if (mOut.dataSize() > 0) {
+ talkWithDriver(false);
+ }
+ if (mOut.dataSize() > 0) {
+ ALOGW("mOut.dataSize() > 0 after flushCommands()");
+ }
}
void IPCThreadState::blockUntilThreadAvailable()
@@ -501,6 +510,21 @@ void IPCThreadState::processPendingDerefs()
}
}
+void IPCThreadState::processPostWriteDerefs()
+{
+ for (size_t i = 0; i < mPostWriteWeakDerefs.size(); i++) {
+ RefBase::weakref_type* refs = mPostWriteWeakDerefs[i];
+ refs->decWeak(mProcess.get());
+ }
+ mPostWriteWeakDerefs.clear();
+
+ for (size_t i = 0; i < mPostWriteStrongDerefs.size(); i++) {
+ RefBase* obj = mPostWriteStrongDerefs[i];
+ obj->decStrong(mProcess.get());
+ }
+ mPostWriteStrongDerefs.clear();
+}
+
void IPCThreadState::joinThreadPool(bool isMain)
{
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
@@ -627,11 +651,14 @@ status_t IPCThreadState::transact(int32_t handle,
return err;
}
-void IPCThreadState::incStrongHandle(int32_t handle)
+void IPCThreadState::incStrongHandle(int32_t handle, BpBinder *proxy)
{
LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
mOut.writeInt32(BC_ACQUIRE);
mOut.writeInt32(handle);
+ // Create a temp reference until the driver has handled this command.
+ proxy->incStrong(mProcess.get());
+ mPostWriteStrongDerefs.push(proxy);
}
void IPCThreadState::decStrongHandle(int32_t handle)
@@ -641,11 +668,14 @@ void IPCThreadState::decStrongHandle(int32_t handle)
mOut.writeInt32(handle);
}
-void IPCThreadState::incWeakHandle(int32_t handle)
+void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy)
{
LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
mOut.writeInt32(BC_INCREFS);
mOut.writeInt32(handle);
+ // Create a temp reference until the driver has handled this command.
+ proxy->getWeakRefs()->incWeak(mProcess.get());
+ mPostWriteWeakDerefs.push(proxy->getWeakRefs());
}
void IPCThreadState::decWeakHandle(int32_t handle)
@@ -897,8 +927,10 @@ status_t IPCThreadState::talkWithDriver(bool doReceive)
if (bwr.write_consumed > 0) {
if (bwr.write_consumed < mOut.dataSize())
mOut.remove(0, bwr.write_consumed);
- else
+ else {
mOut.setDataSize(0);
+ processPostWriteDerefs();
+ }
}
if (bwr.read_consumed > 0) {
mIn.setDataSize(bwr.read_consumed);
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index 245607e74e..c1d9a9a8f7 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -64,9 +64,9 @@ public:
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags);
- void incStrongHandle(int32_t handle);
+ void incStrongHandle(int32_t handle, BpBinder *proxy);
void decStrongHandle(int32_t handle);
- void incWeakHandle(int32_t handle);
+ void incWeakHandle(int32_t handle, BpBinder *proxy);
void decWeakHandle(int32_t handle);
status_t attemptIncStrongHandle(int32_t handle);
static void expungeHandle(int32_t handle, IBinder* binder);
@@ -106,6 +106,7 @@ private:
status_t getAndExecuteCommand();
status_t executeCommand(int32_t command);
void processPendingDerefs();
+ void processPostWriteDerefs();
void clearCaller();
@@ -118,7 +119,8 @@ private:
const sp<ProcessState> mProcess;
Vector<BBinder*> mPendingStrongDerefs;
Vector<RefBase::weakref_type*> mPendingWeakDerefs;
-
+ Vector<RefBase*> mPostWriteStrongDerefs;
+ Vector<RefBase::weakref_type*> mPostWriteWeakDerefs;
Parcel mIn;
Parcel mOut;
status_t mLastError;
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 6a69844d9f..c2bb6ad6b4 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -22,6 +22,7 @@ cc_defaults {
"android.frameworks.vr.composer@1.0",
"android.hardware.configstore-utils",
"android.hardware.configstore@1.0",
+ "android.hardware.configstore@1.1",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.composer@2.2",
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 6feec53257..17ed9aa00c 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -553,7 +553,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime
default:
break;
}
- setDataSpace(dataSpace);
+ mCurrentDataSpace = dataSpace;
Rect crop(mConsumer->getCurrentCrop());
const uint32_t transform(mConsumer->getCurrentTransform());
@@ -660,10 +660,10 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice)
setCompositionType(hwcId, HWC2::Composition::Device);
}
- ALOGV("setPerFrameData: dataspace = %d", mDrawingState.dataSpace);
- error = hwcLayer->setDataspace(mDrawingState.dataSpace);
+ ALOGV("setPerFrameData: dataspace = %d", mCurrentDataSpace);
+ error = hwcLayer->setDataspace(mCurrentDataSpace);
if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace,
+ ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace,
to_string(error).c_str(), static_cast<int32_t>(error));
}
@@ -866,9 +866,9 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT
auto& engine(mFlinger->getRenderEngine());
engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */,
getColor());
- engine.setSourceDataSpace(mCurrentState.dataSpace);
+ engine.setSourceDataSpace(mCurrentDataSpace);
- if (mCurrentState.dataSpace == ui::Dataspace::BT2020_ITU_PQ &&
+ if (mCurrentDataSpace == ui::Dataspace::BT2020_ITU_PQ &&
mConsumer->getCurrentApi() == NATIVE_WINDOW_API_MEDIA &&
getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102) {
engine.setSourceY410BT2020(true);
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index c87b66981d..512564c2db 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -77,9 +77,9 @@ void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
setCompositionType(hwcId, HWC2::Composition::SolidColor);
- error = hwcLayer->setDataspace(mDrawingState.dataSpace);
+ error = hwcLayer->setDataspace(mCurrentDataSpace);
if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace,
+ ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace,
to_string(error).c_str(), static_cast<int32_t>(error));
}
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 2b1e5775ba..e81df8ad53 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -18,6 +18,9 @@
#undef LOG_TAG
#define LOG_TAG "DisplayDevice"
+#include <array>
+#include <unordered_set>
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -55,6 +58,7 @@ namespace android {
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
using android::ui::ColorMode;
+using android::ui::Dataspace;
using android::ui::Hdr;
using android::ui::RenderIntent;
@@ -65,6 +69,147 @@ using android::ui::RenderIntent;
uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0;
+namespace {
+
+// ordered list of known SDR color modes
+const std::array<ColorMode, 2> sSdrColorModes = {
+ ColorMode::DISPLAY_P3,
+ ColorMode::SRGB,
+};
+
+// ordered list of known HDR color modes
+const std::array<ColorMode, 2> sHdrColorModes = {
+ ColorMode::BT2100_PQ,
+ ColorMode::BT2100_HLG,
+};
+
+// ordered list of known SDR render intents
+const std::array<RenderIntent, 2> sSdrRenderIntents = {
+ RenderIntent::ENHANCE,
+ RenderIntent::COLORIMETRIC,
+};
+
+// ordered list of known HDR render intents
+const std::array<RenderIntent, 2> sHdrRenderIntents = {
+ RenderIntent::TONE_MAP_ENHANCE,
+ RenderIntent::TONE_MAP_COLORIMETRIC,
+};
+
+// map known color mode to dataspace
+Dataspace colorModeToDataspace(ColorMode mode) {
+ switch (mode) {
+ case ColorMode::SRGB:
+ return Dataspace::SRGB;
+ case ColorMode::DISPLAY_P3:
+ return Dataspace::DISPLAY_P3;
+ case ColorMode::BT2100_HLG:
+ return Dataspace::BT2020_HLG;
+ case ColorMode::BT2100_PQ:
+ return Dataspace::BT2020_PQ;
+ default:
+ return Dataspace::UNKNOWN;
+ }
+}
+
+// Return a list of candidate color modes.
+std::vector<ColorMode> getColorModeCandidates(ColorMode mode) {
+ std::vector<ColorMode> candidates;
+
+ // add mode itself
+ candidates.push_back(mode);
+
+ // check if mode is HDR
+ bool isHdr = false;
+ for (auto hdrMode : sHdrColorModes) {
+ if (hdrMode == mode) {
+ isHdr = true;
+ break;
+ }
+ }
+
+ // add other HDR candidates when mode is HDR
+ if (isHdr) {
+ for (auto hdrMode : sHdrColorModes) {
+ if (hdrMode != mode) {
+ candidates.push_back(hdrMode);
+ }
+ }
+ }
+
+ // add other SDR candidates
+ for (auto sdrMode : sSdrColorModes) {
+ if (sdrMode != mode) {
+ candidates.push_back(sdrMode);
+ }
+ }
+
+ return candidates;
+}
+
+// Return a list of candidate render intents.
+std::vector<RenderIntent> getRenderIntentCandidates(RenderIntent intent) {
+ std::vector<RenderIntent> candidates;
+
+ // add intent itself
+ candidates.push_back(intent);
+
+ // check if intent is HDR
+ bool isHdr = false;
+ for (auto hdrIntent : sHdrRenderIntents) {
+ if (hdrIntent == intent) {
+ isHdr = true;
+ break;
+ }
+ }
+
+ // add other HDR candidates when intent is HDR
+ if (isHdr) {
+ for (auto hdrIntent : sHdrRenderIntents) {
+ if (hdrIntent != intent) {
+ candidates.push_back(hdrIntent);
+ }
+ }
+ }
+
+ // add COLORIMETRIC
+ if (intent != RenderIntent::COLORIMETRIC) {
+ candidates.push_back(RenderIntent::COLORIMETRIC);
+ }
+
+ return candidates;
+}
+
+// Return the best color mode supported by HWC.
+ColorMode getHwcColorMode(
+ const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes,
+ ColorMode mode) {
+ std::vector<ColorMode> candidates = getColorModeCandidates(mode);
+ for (auto candidate : candidates) {
+ auto iter = hwcColorModes.find(candidate);
+ if (iter != hwcColorModes.end()) {
+ return candidate;
+ }
+ }
+
+ return ColorMode::NATIVE;
+}
+
+// Return the best render intent supported by HWC.
+RenderIntent getHwcRenderIntent(const std::vector<RenderIntent>& hwcIntents, RenderIntent intent) {
+ std::vector<RenderIntent> candidates = getRenderIntentCandidates(intent);
+ for (auto candidate : candidates) {
+ for (auto hwcIntent : hwcIntents) {
+ if (candidate == hwcIntent) {
+ return candidate;
+ }
+ }
+ }
+
+ return RenderIntent::COLORIMETRIC;
+}
+
+} // anonymous namespace
+
// clang-format off
DisplayDevice::DisplayDevice(
const sp<SurfaceFlinger>& flinger,
@@ -80,7 +225,7 @@ DisplayDevice::DisplayDevice(
bool hasWideColorGamut,
const HdrCapabilities& hdrCapabilities,
const int32_t supportedPerFrameMetadata,
- const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hdrAndRenderIntents,
+ const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes,
int initialPowerMode)
: lastCompositionHadVisibleLayers(false),
mFlinger(flinger),
@@ -100,19 +245,16 @@ DisplayDevice::DisplayDevice(
mFrame(Rect::INVALID_RECT),
mPowerMode(initialPowerMode),
mActiveConfig(0),
- mActiveColorMode(ColorMode::NATIVE),
mColorTransform(HAL_COLOR_TRANSFORM_IDENTITY),
mHasWideColorGamut(hasWideColorGamut),
mHasHdr10(false),
mHasHLG(false),
mHasDolbyVision(false),
- mSupportedPerFrameMetadata(supportedPerFrameMetadata),
- mHasBT2100PQColorimetric(false),
- mHasBT2100PQEnhance(false),
- mHasBT2100HLGColorimetric(false),
- mHasBT2100HLGEnhance(false)
+ mSupportedPerFrameMetadata(supportedPerFrameMetadata)
{
// clang-format on
+ populateColorModes(hwcColorModes);
+
std::vector<Hdr> types = hdrCapabilities.getSupportedHdrTypes();
for (Hdr hdrType : types) {
switch (hdrType) {
@@ -150,18 +292,6 @@ DisplayDevice::DisplayDevice(
}
mHdrCapabilities = HdrCapabilities(types, maxLuminance, maxAverageLuminance, minLuminance);
- auto iter = hdrAndRenderIntents.find(ColorMode::BT2100_PQ);
- if (iter != hdrAndRenderIntents.end()) {
- hasToneMapping(iter->second,
- &mHasBT2100PQColorimetric, &mHasBT2100PQEnhance);
- }
-
- iter = hdrAndRenderIntents.find(ColorMode::BT2100_HLG);
- if (iter != hdrAndRenderIntents.end()) {
- hasToneMapping(iter->second,
- &mHasBT2100HLGColorimetric, &mHasBT2100HLGEnhance);
- }
-
// initialize the display orientation transform.
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
}
@@ -475,6 +605,15 @@ void DisplayDevice::setProjection(int orientation,
TL.set(-src_x, -src_y);
TP.set(dst_x, dst_y);
+ // need to take care of primary display rotation for mGlobalTransform
+ // for case if the panel is not installed aligned with device orientation
+ if (mType == DisplayType::DISPLAY_PRIMARY) {
+ int primaryDisplayOrientation = mFlinger->getPrimaryDisplayOrientation();
+ DisplayDevice::orientationToTransfrom(
+ (orientation + primaryDisplayOrientation) % (DisplayState::eOrientation270 + 1),
+ w, h, &R);
+ }
+
// The viewport and frame are both in the logical orientation.
// Apply the logical translation, scale to physical size, apply the
// physical translation and finally rotate to the physical orientation.
@@ -546,20 +685,98 @@ void DisplayDevice::dump(String8& result) const {
result.append(surfaceDump);
}
-void DisplayDevice::hasToneMapping(const std::vector<RenderIntent>& renderIntents,
- bool* outColorimetric, bool *outEnhance) {
- for (auto intent : renderIntents) {
- switch (intent) {
- case RenderIntent::TONE_MAP_COLORIMETRIC:
- *outColorimetric = true;
- break;
- case RenderIntent::TONE_MAP_ENHANCE:
- *outEnhance = true;
- break;
- default:
- break;
+// Map dataspace/intent to the best matched dataspace/colorMode/renderIntent
+// supported by HWC.
+void DisplayDevice::addColorMode(
+ const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes,
+ const ColorMode mode, const RenderIntent intent) {
+ // find the best color mode
+ const ColorMode hwcColorMode = getHwcColorMode(hwcColorModes, mode);
+
+ // find the best render intent
+ auto iter = hwcColorModes.find(hwcColorMode);
+ const auto& hwcIntents =
+ iter != hwcColorModes.end() ? iter->second : std::vector<RenderIntent>();
+ const RenderIntent hwcIntent = getHwcRenderIntent(hwcIntents, intent);
+
+ const Dataspace dataspace = colorModeToDataspace(mode);
+ const Dataspace hwcDataspace = colorModeToDataspace(hwcColorMode);
+
+ ALOGV("DisplayDevice %d/%d: map (%s, %s) to (%s, %s, %s)", mType, mHwcDisplayId,
+ dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
+ decodeRenderIntent(intent).c_str(),
+ dataspaceDetails(static_cast<android_dataspace_t>(hwcDataspace)).c_str(),
+ decodeColorMode(hwcColorMode).c_str(), decodeRenderIntent(hwcIntent).c_str());
+
+ mColorModes[getColorModeKey(dataspace, intent)] = {hwcDataspace, hwcColorMode, hwcIntent};
+}
+
+void DisplayDevice::populateColorModes(
+ const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes) {
+ if (!hasWideColorGamut()) {
+ return;
+ }
+
+ // collect all known SDR render intents
+ std::unordered_set<RenderIntent> sdrRenderIntents(sSdrRenderIntents.begin(),
+ sSdrRenderIntents.end());
+ auto iter = hwcColorModes.find(ColorMode::SRGB);
+ if (iter != hwcColorModes.end()) {
+ for (auto intent : iter->second) {
+ sdrRenderIntents.insert(intent);
+ }
+ }
+
+ // add known SDR combinations
+ for (auto intent : sdrRenderIntents) {
+ for (auto mode : sSdrColorModes) {
+ addColorMode(hwcColorModes, mode, intent);
}
}
+
+ // add known HDR combinations
+ for (auto intent : sHdrRenderIntents) {
+ for (auto mode : sHdrColorModes) {
+ addColorMode(hwcColorModes, mode, intent);
+ }
+ }
+}
+
+bool DisplayDevice::hasRenderIntent(RenderIntent intent) const {
+ // assume a render intent is supported when SRGB supports it; we should
+ // get rid of that assumption.
+ auto iter = mColorModes.find(getColorModeKey(Dataspace::SRGB, intent));
+ return iter != mColorModes.end() && iter->second.renderIntent == intent;
+}
+
+bool DisplayDevice::hasModernHdrSupport(Dataspace dataspace) const {
+ if ((dataspace == Dataspace::BT2020_PQ && hasHDR10Support()) ||
+ (dataspace == Dataspace::BT2020_HLG && hasHLGSupport())) {
+ auto iter =
+ mColorModes.find(getColorModeKey(dataspace, RenderIntent::TONE_MAP_COLORIMETRIC));
+ return iter != mColorModes.end() && iter->second.dataspace == dataspace;
+ }
+
+ return false;
+}
+
+void DisplayDevice::getBestColorMode(Dataspace dataspace, RenderIntent intent,
+ Dataspace* outDataspace, ColorMode* outMode,
+ RenderIntent* outIntent) const {
+ auto iter = mColorModes.find(getColorModeKey(dataspace, intent));
+ if (iter != mColorModes.end()) {
+ *outDataspace = iter->second.dataspace;
+ *outMode = iter->second.colorMode;
+ *outIntent = iter->second.renderIntent;
+ } else {
+ ALOGE("map unknown (%s)/(%s) to default color mode",
+ dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
+ decodeRenderIntent(intent).c_str());
+
+ *outDataspace = Dataspace::UNKNOWN;
+ *outMode = ColorMode::NATIVE;
+ *outIntent = RenderIntent::COLORIMETRIC;
+ }
}
std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1);
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index b4100ce976..b3859b6793 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -91,7 +91,7 @@ public:
bool hasWideColorGamut,
const HdrCapabilities& hdrCapabilities,
const int32_t supportedPerFrameMetadata,
- const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hdrAndRenderIntents,
+ const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hwcColorModes,
int initialPowerMode);
// clang-format on
@@ -143,11 +143,17 @@ public:
// machine happy without actually queueing a buffer if nothing has changed
status_t beginFrame(bool mustRecompose) const;
status_t prepareFrame(HWComposer& hwc);
+
bool hasWideColorGamut() const { return mHasWideColorGamut; }
// Whether h/w composer has native support for specific HDR type.
bool hasHDR10Support() const { return mHasHdr10; }
bool hasHLGSupport() const { return mHasHLG; }
bool hasDolbyVisionSupport() const { return mHasDolbyVision; }
+
+ // Return true if the corresponding color mode for the HDR dataspace is
+ // supported.
+ bool hasModernHdrSupport(ui::Dataspace dataspace) const;
+
// The returned HdrCapabilities is the combination of HDR capabilities from
// hardware composer and RenderEngine. When the DisplayDevice supports wide
// color gamut, RenderEngine is able to simulate HDR support in Display P3
@@ -156,13 +162,12 @@ public:
// respectively if hardware composer doesn't return meaningful values.
const HdrCapabilities& getHdrCapabilities() const { return mHdrCapabilities; }
- // Whether h/w composer has BT2100_PQ color mode.
- bool hasBT2100PQColorimetricSupport() const { return mHasBT2100PQColorimetric; }
- bool hasBT2100PQEnhanceSupport() const { return mHasBT2100PQEnhance; }
+ // Return true if intent is supported by the display.
+ bool hasRenderIntent(ui::RenderIntent intent) const;
- // Whether h/w composer has BT2100_HLG color mode.
- bool hasBT2100HLGColorimetricSupport() const { return mHasBT2100HLGColorimetric; }
- bool hasBT2100HLGEnhanceSupport() const { return mHasBT2100HLGEnhance; }
+ void getBestColorMode(ui::Dataspace dataspace, ui::RenderIntent intent,
+ ui::Dataspace* outDataspace, ui::ColorMode* outMode,
+ ui::RenderIntent* outIntent) const;
void swapBuffers(HWComposer& hwc) const;
@@ -214,9 +219,6 @@ public:
void dump(String8& result) const;
private:
- void hasToneMapping(const std::vector<ui::RenderIntent>& renderIntents,
- bool* outColorimetric, bool *outEnhance);
-
/*
* Constants, set during initialization
*/
@@ -272,10 +274,10 @@ private:
// Current active config
int mActiveConfig;
// current active color mode
- ui::ColorMode mActiveColorMode;
+ ui::ColorMode mActiveColorMode = ui::ColorMode::NATIVE;
// Current active render intent.
- ui::RenderIntent mActiveRenderIntent;
- ui::Dataspace mCompositionDataSpace;
+ ui::RenderIntent mActiveRenderIntent = ui::RenderIntent::COLORIMETRIC;
+ ui::Dataspace mCompositionDataSpace = ui::Dataspace::UNKNOWN;
// Current color transform
android_color_transform_t mColorTransform;
@@ -288,12 +290,26 @@ private:
bool mHasDolbyVision;
HdrCapabilities mHdrCapabilities;
const int32_t mSupportedPerFrameMetadata;
- // Whether h/w composer has BT2100_PQ and BT2100_HLG color mode with
- // colorimetrical tone mapping or enhanced tone mapping.
- bool mHasBT2100PQColorimetric;
- bool mHasBT2100PQEnhance;
- bool mHasBT2100HLGColorimetric;
- bool mHasBT2100HLGEnhance;
+
+ // Mappings from desired Dataspace/RenderIntent to the supported
+ // Dataspace/ColorMode/RenderIntent.
+ using ColorModeKey = uint64_t;
+ struct ColorModeValue {
+ ui::Dataspace dataspace;
+ ui::ColorMode colorMode;
+ ui::RenderIntent renderIntent;
+ };
+
+ static ColorModeKey getColorModeKey(ui::Dataspace dataspace, ui::RenderIntent intent) {
+ return (static_cast<uint64_t>(dataspace) << 32) | static_cast<uint32_t>(intent);
+ }
+ void populateColorModes(
+ const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hwcColorModes);
+ void addColorMode(
+ const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hwcColorModes,
+ const ui::ColorMode mode, const ui::RenderIntent intent);
+
+ std::unordered_map<ColorModeKey, ColorModeValue> mColorModes;
};
struct DisplayDeviceState {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2077598371..b94af77967 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -123,7 +123,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& n
mCurrentState.layerStack = 0;
mCurrentState.sequence = 0;
mCurrentState.requested = mCurrentState.active;
- mCurrentState.dataSpace = ui::Dataspace::UNKNOWN;
mCurrentState.appId = 0;
mCurrentState.type = 0;
@@ -1328,15 +1327,6 @@ bool Layer::setLayerStack(uint32_t layerStack) {
return true;
}
-bool Layer::setDataSpace(ui::Dataspace dataSpace) {
- if (mCurrentState.dataSpace == dataSpace) return false;
- mCurrentState.sequence++;
- mCurrentState.dataSpace = dataSpace;
- mCurrentState.modified = true;
- setTransactionFlags(eTransactionNeeded);
- return true;
-}
-
uint32_t Layer::getLayerStack() const {
auto p = mDrawingParent.promote();
if (p == nullptr) {
@@ -1429,7 +1419,7 @@ LayerDebugInfo Layer::getLayerDebugInfo() const {
info.mColor = ds.color;
info.mFlags = ds.flags;
info.mPixelFormat = getPixelFormat();
- info.mDataSpace = static_cast<android_dataspace>(ds.dataSpace);
+ info.mDataSpace = static_cast<android_dataspace>(mCurrentDataSpace);
info.mMatrix[0][0] = ds.active.transform[0][0];
info.mMatrix[0][1] = ds.active.transform[0][1];
info.mMatrix[1][0] = ds.active.transform[1][0];
@@ -1648,7 +1638,7 @@ bool Layer::detachChildren() {
bool Layer::isLegacyDataSpace() const {
// return true when no higher bits are set
- return !(mDrawingState.dataSpace & (ui::Dataspace::STANDARD_MASK |
+ return !(mCurrentDataSpace & (ui::Dataspace::STANDARD_MASK |
ui::Dataspace::TRANSFER_MASK | ui::Dataspace::RANGE_MASK));
}
@@ -1956,7 +1946,10 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet)
layerInfo->set_is_opaque(isOpaque(state));
layerInfo->set_invalidate(contentDirty);
- layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(state.dataSpace)));
+
+ // XXX (b/79210409) mCurrentDataSpace is not protected
+ layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(mCurrentDataSpace)));
+
layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat()));
LayerProtoHelper::writeToProto(getColor(), layerInfo->mutable_color());
LayerProtoHelper::writeToProto(state.color, layerInfo->mutable_requested_color());
@@ -1975,6 +1968,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet)
layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
}
+ // XXX getBE().compositionInfo.mBuffer is not protected
auto buffer = getBE().compositionInfo.mBuffer;
if (buffer != nullptr) {
LayerProtoHelper::writeToProto(buffer, layerInfo->mutable_active_buffer());
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 91eb15ae4a..7342c8b987 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -209,7 +209,6 @@ public:
// dependent.
Region activeTransparentRegion;
Region requestedTransparentRegion;
- ui::Dataspace dataSpace;
int32_t appId;
int32_t type;
@@ -287,7 +286,6 @@ public:
bool setTransparentRegionHint(const Region& transparent);
bool setFlags(uint8_t flags, uint8_t mask);
bool setLayerStack(uint32_t layerStack);
- bool setDataSpace(ui::Dataspace dataSpace);
uint32_t getLayerStack() const;
void deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t frameNumber);
void deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber);
@@ -298,6 +296,8 @@ public:
bool reparent(const sp<IBinder>& newParentHandle);
bool detachChildren();
+ ui::Dataspace getDataSpace() const { return mCurrentDataSpace; }
+
// Before color management is introduced, contents on Android have to be
// desaturated in order to match what they appears like visually.
// With color management, these contents will appear desaturated, thus
@@ -743,6 +743,7 @@ protected:
int mActiveBufferSlot;
sp<GraphicBuffer> mActiveBuffer;
sp<NativeHandle> mSidebandStream;
+ ui::Dataspace mCurrentDataSpace = ui::Dataspace::UNKNOWN;
Rect mCurrentCrop;
uint32_t mCurrentTransform;
// We encode unset as -1.
diff --git a/services/surfaceflinger/RenderArea.cpp b/services/surfaceflinger/RenderArea.cpp
index 46ec8e68ba..1a8edf3e79 100644
--- a/services/surfaceflinger/RenderArea.cpp
+++ b/services/surfaceflinger/RenderArea.cpp
@@ -1,5 +1,7 @@
#include "RenderArea.h"
+#include <gui/LayerState.h>
+
namespace android {
float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
@@ -15,7 +17,7 @@ float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
* Checks that the requested width and height are valid and updates them to the render area
* dimensions if they are set to 0
*/
-status_t RenderArea::updateDimensions() {
+status_t RenderArea::updateDimensions(int displayRotation) {
// get screen geometry
uint32_t width = getWidth();
@@ -25,6 +27,10 @@ status_t RenderArea::updateDimensions() {
std::swap(width, height);
}
+ if (displayRotation & DisplayState::eOrientationSwapMask) {
+ std::swap(width, height);
+ }
+
if ((mReqWidth > width) || (mReqHeight > height)) {
ALOGE("size mismatch (%d, %d) > (%d, %d)", mReqWidth, mReqHeight, width, height);
return BAD_VALUE;
@@ -40,4 +46,4 @@ status_t RenderArea::updateDimensions() {
return NO_ERROR;
}
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index 938c3ce0dd..96e4b5f48b 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -36,7 +36,7 @@ public:
int getReqHeight() const { return mReqHeight; };
int getReqWidth() const { return mReqWidth; };
Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
- status_t updateDimensions();
+ status_t updateDimensions(int displayRotation);
CaptureFill getCaptureFill() const { return mCaptureFill; };
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9117207544..f5fa478a2d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -88,6 +88,8 @@
#include <cutils/compiler.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.1/types.h>
#include <configstore/Utils.h>
#include <layerproto/LayerProtoParser.h>
@@ -158,29 +160,18 @@ bool useTrebleTestingOverride() {
return std::string(value) == "true";
}
-DisplayColorSetting toDisplayColorSetting(int value) {
- switch(value) {
- case 0:
- return DisplayColorSetting::MANAGED;
- case 1:
- return DisplayColorSetting::UNMANAGED;
- case 2:
- return DisplayColorSetting::ENHANCED;
- default:
- return DisplayColorSetting::MANAGED;
- }
-}
-
std::string decodeDisplayColorSetting(DisplayColorSetting displayColorSetting) {
switch(displayColorSetting) {
case DisplayColorSetting::MANAGED:
- return std::string("Natural Mode");
+ return std::string("Managed");
case DisplayColorSetting::UNMANAGED:
- return std::string("Saturated Mode");
+ return std::string("Unmanaged");
case DisplayColorSetting::ENHANCED:
- return std::string("Auto Color Mode");
+ return std::string("Enhanced");
+ default:
+ return std::string("Unknown ") +
+ std::to_string(static_cast<int>(displayColorSetting));
}
- return std::string("Unknown Display Color Setting");
}
NativeWindowSurface::~NativeWindowSurface() = default;
@@ -282,6 +273,26 @@ SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {
hasWideColorDisplay =
getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
+ V1_1::DisplayOrientation primaryDisplayOrientation =
+ getDisplayOrientation< V1_1::ISurfaceFlingerConfigs, &V1_1::ISurfaceFlingerConfigs::primaryDisplayOrientation>(
+ V1_1::DisplayOrientation::ORIENTATION_0);
+
+ switch (primaryDisplayOrientation) {
+ case V1_1::DisplayOrientation::ORIENTATION_90:
+ mPrimaryDisplayOrientation = DisplayState::eOrientation90;
+ break;
+ case V1_1::DisplayOrientation::ORIENTATION_180:
+ mPrimaryDisplayOrientation = DisplayState::eOrientation180;
+ break;
+ case V1_1::DisplayOrientation::ORIENTATION_270:
+ mPrimaryDisplayOrientation = DisplayState::eOrientation270;
+ break;
+ default:
+ mPrimaryDisplayOrientation = DisplayState::eOrientationDefault;
+ break;
+ }
+ ALOGV("Primary Display Orientation is set to %2d.", mPrimaryDisplayOrientation);
+
mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset);
// debugging stuff...
@@ -738,9 +749,7 @@ void SurfaceFlinger::readPersistentProperties() {
ALOGV("Saturation is set to %.2f", mGlobalSaturationFactor);
property_get("persist.sys.sf.native_mode", value, "0");
- mDisplayColorSetting = toDisplayColorSetting(atoi(value));
- ALOGV("Display Color Setting is set to %s.",
- decodeDisplayColorSetting(mDisplayColorSetting).c_str());
+ mDisplayColorSetting = static_cast<DisplayColorSetting>(atoi(value));
}
void SurfaceFlinger::startBootAnim() {
@@ -895,6 +904,11 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
// All non-virtual displays are currently considered secure.
info.secure = true;
+ if (type == DisplayDevice::DISPLAY_PRIMARY &&
+ mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
+ std::swap(info.w, info.h);
+ }
+
configs->push_back(info);
}
@@ -1868,7 +1882,6 @@ void SurfaceFlinger::rebuildLayerStacks() {
// can only be one of
// - Dataspace::SRGB (use legacy dataspace and let HWC saturate when colors are enhanced)
// - Dataspace::DISPLAY_P3
-// - Dataspace::V0_SCRGB_LINEAR
// The returned HDR data space is one of
// - Dataspace::UNKNOWN
// - Dataspace::BT2020_HLG
@@ -1879,15 +1892,11 @@ Dataspace SurfaceFlinger::getBestDataspace(
*outHdrDataSpace = Dataspace::UNKNOWN;
for (const auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
- switch (layer->getDrawingState().dataSpace) {
+ switch (layer->getDataSpace()) {
case Dataspace::V0_SCRGB:
case Dataspace::V0_SCRGB_LINEAR:
- bestDataSpace = Dataspace::V0_SCRGB_LINEAR;
- break;
case Dataspace::DISPLAY_P3:
- if (bestDataSpace == Dataspace::SRGB) {
- bestDataSpace = Dataspace::DISPLAY_P3;
- }
+ bestDataSpace = Dataspace::DISPLAY_P3;
break;
case Dataspace::BT2020_PQ:
case Dataspace::BT2020_ITU_PQ:
@@ -1923,104 +1932,28 @@ void SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& displayDevice,
Dataspace hdrDataSpace;
Dataspace bestDataSpace = getBestDataspace(displayDevice, &hdrDataSpace);
- if (hdrDataSpace == Dataspace::BT2020_PQ) {
- // Hardware composer can handle BT2100 ColorMode only when
- // - colorimetrical tone mapping is supported, or
- // - Auto mode is turned on and enhanced tone mapping is supported.
- if (displayDevice->hasBT2100PQColorimetricSupport() ||
- (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
- displayDevice->hasBT2100PQEnhanceSupport())) {
- *outMode = ColorMode::BT2100_PQ;
- *outDataSpace = Dataspace::BT2020_PQ;
- } else if (displayDevice->hasHDR10Support()) {
- // Legacy HDR support. HDR layers are treated as UNKNOWN layers.
- hdrDataSpace = Dataspace::UNKNOWN;
- } else {
- // Simulate PQ through RenderEngine, pick DISPLAY_P3 color mode.
- *outMode = ColorMode::DISPLAY_P3;
- *outDataSpace = Dataspace::DISPLAY_P3;
- }
- } else if (hdrDataSpace == Dataspace::BT2020_HLG) {
- if (displayDevice->hasBT2100HLGColorimetricSupport() ||
- (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
- displayDevice->hasBT2100HLGEnhanceSupport())) {
- *outMode = ColorMode::BT2100_HLG;
- *outDataSpace = Dataspace::BT2020_HLG;
- } else if (displayDevice->hasHLGSupport()) {
- // Legacy HDR support. HDR layers are treated as UNKNOWN layers.
- hdrDataSpace = Dataspace::UNKNOWN;
- } else {
- // Simulate HLG through RenderEngine, pick DISPLAY_P3 color mode.
- *outMode = ColorMode::DISPLAY_P3;
- *outDataSpace = Dataspace::DISPLAY_P3;
- }
- }
-
- // At this point, there's no HDR layer.
- if (hdrDataSpace == Dataspace::UNKNOWN) {
- switch (bestDataSpace) {
- case Dataspace::DISPLAY_P3:
- case Dataspace::V0_SCRGB_LINEAR:
- *outMode = ColorMode::DISPLAY_P3;
- *outDataSpace = Dataspace::DISPLAY_P3;
- break;
- default:
- *outMode = ColorMode::SRGB;
- *outDataSpace = Dataspace::SRGB;
- break;
- }
+ RenderIntent intent;
+ switch (mDisplayColorSetting) {
+ case DisplayColorSetting::MANAGED:
+ case DisplayColorSetting::UNMANAGED:
+ intent = RenderIntent::COLORIMETRIC;
+ break;
+ case DisplayColorSetting::ENHANCED:
+ intent = RenderIntent::ENHANCE;
+ break;
+ default: // vendor display color setting
+ intent = static_cast<RenderIntent>(mDisplayColorSetting);
+ break;
}
- *outRenderIntent = pickRenderIntent(displayDevice, *outMode);
-}
-RenderIntent SurfaceFlinger::pickRenderIntent(const sp<DisplayDevice>& displayDevice,
- ColorMode colorMode) const {
- // Native Mode means the display is not color managed, and whichever
- // render intent is picked doesn't matter, thus return
- // RenderIntent::COLORIMETRIC as default here.
- if (mDisplayColorSetting == DisplayColorSetting::UNMANAGED) {
- return RenderIntent::COLORIMETRIC;
- }
-
- // In Auto Color Mode, we want to strech to panel color space, right now
- // only the built-in display supports it.
- if (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
- mBuiltinDisplaySupportsEnhance &&
- displayDevice->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
- switch (colorMode) {
- case ColorMode::DISPLAY_P3:
- case ColorMode::SRGB:
- return RenderIntent::ENHANCE;
- // In Auto Color Mode, BT2100_PQ and BT2100_HLG will only be picked
- // when TONE_MAP_ENHANCE or TONE_MAP_COLORIMETRIC is supported.
- // If TONE_MAP_ENHANCE is not supported, fall back to TONE_MAP_COLORIMETRIC.
- case ColorMode::BT2100_PQ:
- return displayDevice->hasBT2100PQEnhanceSupport() ?
- RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
- case ColorMode::BT2100_HLG:
- return displayDevice->hasBT2100HLGEnhanceSupport() ?
- RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
- // This statement shouldn't be reached, switch cases will always
- // cover all possible ColorMode returned by pickColorMode.
- default:
- return RenderIntent::COLORIMETRIC;
- }
+ // respect hdrDataSpace only when there is modern HDR support
+ if (hdrDataSpace != Dataspace::UNKNOWN && displayDevice->hasModernHdrSupport(hdrDataSpace)) {
+ bestDataSpace = hdrDataSpace;
+ intent = mDisplayColorSetting == DisplayColorSetting::ENHANCED ?
+ RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
}
- // Either enhance is not supported or we are in natural mode.
-
- // Natural Mode means it's color managed and the color must be right,
- // thus we pick RenderIntent::COLORIMETRIC as render intent for non-HDR
- // content and pick RenderIntent::TONE_MAP_COLORIMETRIC for HDR content.
- switch (colorMode) {
- // In Natural Color Mode, BT2100_PQ and BT2100_HLG will only be picked
- // when TONE_MAP_COLORIMETRIC is supported.
- case ColorMode::BT2100_PQ:
- case ColorMode::BT2100_HLG:
- return RenderIntent::TONE_MAP_COLORIMETRIC;
- default:
- return RenderIntent::COLORIMETRIC;
- }
+ displayDevice->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent);
}
void SurfaceFlinger::setUpHWComposer() {
@@ -2098,13 +2031,13 @@ void SurfaceFlinger::setUpHWComposer() {
"display %zd: %d", displayId, result);
}
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
- if ((layer->getDrawingState().dataSpace == Dataspace::BT2020_PQ ||
- layer->getDrawingState().dataSpace == Dataspace::BT2020_ITU_PQ) &&
+ if ((layer->getDataSpace() == Dataspace::BT2020_PQ ||
+ layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) &&
!displayDevice->hasHDR10Support()) {
layer->forceClientComposition(hwcId);
}
- if ((layer->getDrawingState().dataSpace == Dataspace::BT2020_HLG ||
- layer->getDrawingState().dataSpace == Dataspace::BT2020_ITU_HLG) &&
+ if ((layer->getDataSpace() == Dataspace::BT2020_HLG ||
+ layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) &&
!displayDevice->hasHLGSupport()) {
layer->forceClientComposition(hwcId);
}
@@ -2332,7 +2265,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state,
const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
bool hasWideColorGamut = false;
- std::unordered_map<ColorMode, std::vector<RenderIntent>> hdrAndRenderIntents;
+ std::unordered_map<ColorMode, std::vector<RenderIntent>> hwcColorModes;
if (hasWideColorDisplay) {
std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId);
@@ -2349,18 +2282,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
std::vector<RenderIntent> renderIntents = getHwComposer().getRenderIntents(hwcId,
colorMode);
- if (state.type == DisplayDevice::DISPLAY_PRIMARY) {
- for (auto intent : renderIntents) {
- if (intent == RenderIntent::ENHANCE) {
- mBuiltinDisplaySupportsEnhance = true;
- break;
- }
- }
- }
-
- if (colorMode == ColorMode::BT2100_PQ || colorMode == ColorMode::BT2100_HLG) {
- hdrAndRenderIntents.emplace(colorMode, renderIntents);
- }
+ hwcColorModes.emplace(colorMode, renderIntents);
}
}
@@ -2400,7 +2322,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
dispSurface, std::move(renderSurface), displayWidth, displayHeight,
hasWideColorGamut, hdrCapabilities,
getHwComposer().getSupportedPerFrameMetadata(hwcId),
- hdrAndRenderIntents, initialPowerMode);
+ hwcColorModes, initialPowerMode);
if (maxFrameBufferAcquiredBuffers >= 3) {
nativeWindowSurface->preallocateBuffers();
@@ -2410,7 +2332,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
Dataspace defaultDataSpace = Dataspace::UNKNOWN;
if (hasWideColorGamut) {
defaultColorMode = ColorMode::SRGB;
- defaultDataSpace = Dataspace::V0_SRGB;
+ defaultDataSpace = Dataspace::SRGB;
}
setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace,
RenderIntent::COLORIMETRIC);
@@ -2997,9 +2919,10 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDev
getRenderEngine().setupColorTransform(mDrawingState.colorMatrix);
}
- needsLegacyColorMatrix = (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
- outputDataspace != Dataspace::UNKNOWN &&
- outputDataspace != Dataspace::SRGB);
+ needsLegacyColorMatrix =
+ (displayDevice->getActiveRenderIntent() >= RenderIntent::ENHANCE &&
+ outputDataspace != Dataspace::UNKNOWN &&
+ outputDataspace != Dataspace::SRGB);
if (!displayDevice->makeCurrent()) {
ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
@@ -4171,7 +4094,8 @@ void SurfaceFlinger::dumpBufferingStats(String8& result) const {
void SurfaceFlinger::dumpWideColorInfo(String8& result) const {
result.appendFormat("hasWideColorDisplay: %d\n", hasWideColorDisplay);
- result.appendFormat("DisplayColorSetting: %d\n", mDisplayColorSetting);
+ result.appendFormat("DisplayColorSetting: %s\n",
+ decodeDisplayColorSetting(mDisplayColorSetting).c_str());
// TODO: print out if wide-color mode is active or not
@@ -4699,15 +4623,7 @@ status_t SurfaceFlinger::onTransact(
return NO_ERROR;
}
case 1023: { // Set native mode
- int32_t value = data.readInt32();
- if (value > 2) {
- return BAD_VALUE;
- }
- if (value == 2 && !mBuiltinDisplaySupportsEnhance) {
- return BAD_VALUE;
- }
-
- mDisplayColorSetting = toDisplayColorSetting(value);
+ mDisplayColorSetting = static_cast<DisplayColorSetting>(data.readInt32());
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
@@ -4736,20 +4652,27 @@ status_t SurfaceFlinger::onTransact(
}
// Is a DisplayColorSetting supported?
case 1027: {
- int32_t value = data.readInt32();
- switch (value) {
- case 0:
+ sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+ if (!hw) {
+ return NAME_NOT_FOUND;
+ }
+
+ DisplayColorSetting setting = static_cast<DisplayColorSetting>(data.readInt32());
+ switch (setting) {
+ case DisplayColorSetting::MANAGED:
reply->writeBool(hasWideColorDisplay);
- return NO_ERROR;
- case 1:
+ break;
+ case DisplayColorSetting::UNMANAGED:
reply->writeBool(true);
- return NO_ERROR;
- case 2:
- reply->writeBool(mBuiltinDisplaySupportsEnhance);
- return NO_ERROR;
- default:
- return BAD_VALUE;
+ break;
+ case DisplayColorSetting::ENHANCED:
+ reply->writeBool(hw->hasRenderIntent(RenderIntent::ENHANCE));
+ break;
+ default: // vendor display color setting
+ reply->writeBool(hw->hasRenderIntent(static_cast<RenderIntent>(setting)));
+ break;
}
+ return NO_ERROR;
}
}
}
@@ -4913,7 +4836,7 @@ status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
bool useIdentityTransform) {
ATRACE_CALL();
- renderArea.updateDimensions();
+ renderArea.updateDimensions(mPrimaryDisplayOrientation);
const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
@@ -4997,13 +4920,35 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
const auto reqHeight = renderArea.getReqHeight();
Rect sourceCrop = renderArea.getSourceCrop();
- const bool filtering = static_cast<int32_t>(reqWidth) != raWidth ||
- static_cast<int32_t>(reqHeight) != raHeight;
+ bool filtering = false;
+ if (mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
+ filtering = static_cast<int32_t>(reqWidth) != raHeight ||
+ static_cast<int32_t>(reqHeight) != raWidth;
+ } else {
+ filtering = static_cast<int32_t>(reqWidth) != raWidth ||
+ static_cast<int32_t>(reqHeight) != raHeight;
+ }
// if a default or invalid sourceCrop is passed in, set reasonable values
if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || !sourceCrop.isValid()) {
sourceCrop.setLeftTop(Point(0, 0));
sourceCrop.setRightBottom(Point(raWidth, raHeight));
+ } else if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) {
+ Transform tr;
+ uint32_t flags = 0x00;
+ switch (mPrimaryDisplayOrientation) {
+ case DisplayState::eOrientation90:
+ flags = Transform::ROT_90;
+ break;
+ case DisplayState::eOrientation180:
+ flags = Transform::ROT_180;
+ break;
+ case DisplayState::eOrientation270:
+ flags = Transform::ROT_270;
+ break;
+ }
+ tr.set(flags, raWidth, raHeight);
+ sourceCrop = tr.transform(sourceCrop);
}
// ensure that sourceCrop is inside screen
@@ -5027,9 +4972,40 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
// make sure to clear all GL error flags
engine.checkErrors();
+ Transform::orientation_flags rotation = renderArea.getRotationFlags();
+ if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) {
+ // convert hw orientation into flag presentation
+ // here inverse transform needed
+ uint8_t hw_rot_90 = 0x00;
+ uint8_t hw_flip_hv = 0x00;
+ switch (mPrimaryDisplayOrientation) {
+ case DisplayState::eOrientation90:
+ hw_rot_90 = Transform::ROT_90;
+ hw_flip_hv = Transform::ROT_180;
+ break;
+ case DisplayState::eOrientation180:
+ hw_flip_hv = Transform::ROT_180;
+ break;
+ case DisplayState::eOrientation270:
+ hw_rot_90 = Transform::ROT_90;
+ break;
+ }
+
+ // transform flags operation
+ // 1) flip H V if both have ROT_90 flag
+ // 2) XOR these flags
+ uint8_t rotation_rot_90 = rotation & Transform::ROT_90;
+ uint8_t rotation_flip_hv = rotation & Transform::ROT_180;
+ if (rotation_rot_90 & hw_rot_90) {
+ rotation_flip_hv = (~rotation_flip_hv) & Transform::ROT_180;
+ }
+ rotation = static_cast<Transform::orientation_flags>
+ ((rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv));
+ }
+
// set-up our viewport
engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, raHeight, yswap,
- renderArea.getRotationFlags());
+ rotation);
engine.disableTexturing();
const float alpha = RenderArea::getCaptureFillValue(renderArea.getCaptureFill());
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d9cf9461ca..062cb76960 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -341,6 +341,8 @@ public:
bool authenticateSurfaceTextureLocked(
const sp<IGraphicBufferProducer>& bufferProducer) const;
+ int getPrimaryDisplayOrientation() const { return mPrimaryDisplayOrientation; }
+
private:
friend class Client;
friend class DisplayEventConnection;
@@ -664,8 +666,6 @@ private:
ui::ColorMode* outMode,
ui::Dataspace* outDataSpace,
ui::RenderIntent* outRenderIntent) const;
- ui::RenderIntent pickRenderIntent(const sp<DisplayDevice>& displayDevice,
- ui::ColorMode colorMode) const;
void setUpHWComposer();
void doComposition();
@@ -845,6 +845,7 @@ private:
mutable std::unique_ptr<MessageQueue> mEventQueue{std::make_unique<impl::MessageQueue>()};
FrameTracker mAnimFrameTracker;
DispSync mPrimaryDispSync;
+ int mPrimaryDisplayOrientation = DisplayState::eOrientationDefault;
// protected by mDestroyedLayerLock;
mutable Mutex mDestroyedLayerLock;
@@ -880,7 +881,6 @@ private:
DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::MANAGED;
// Applied on sRGB layers when the render intent is non-colorimetric.
mat4 mLegacySrgbSaturationMatrix;
- bool mBuiltinDisplaySupportsEnhance = false;
using CreateBufferQueueFunction =
std::function<void(sp<IGraphicBufferProducer>* /* outProducer */,
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index cd691282d0..9b308bfcc8 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -505,10 +505,7 @@ struct WideColorNotSupportedVariant {
static void setupComposerCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
.WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
- EXPECT_CALL(*test->mComposer,
- setColorMode(Display::HWC_DISPLAY_ID, ColorMode::NATIVE,
- RenderIntent::COLORIMETRIC))
- .WillOnce(Return(Error::NONE));
+ EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
}
};