diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-05-24 07:21:37 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-05-24 07:21:37 +0000 |
commit | 9ba99577d8abf5841e50d48220008b67ab64ebf5 (patch) | |
tree | c2c4f7c4282ad38025c6902024fa2c78ec3c6965 | |
parent | b6f150d67de27a6a62836c0799f7cecda70067f5 (diff) | |
parent | db83ea84ab10d097e692edfe32972eeea7312fd9 (diff) | |
download | native-9ba99577d8abf5841e50d48220008b67ab64ebf5.tar.gz |
Snap for 4801384 from db83ea84ab10d097e692edfe32972eeea7312fd9 to pi-release
Change-Id: Iabb9257409efa3b4a240109ce91c13b6aa7350c4
-rw-r--r-- | cmds/atrace/atrace.cpp | 14 | ||||
-rw-r--r-- | data/etc/aosp_excluded_hardware.xml | 21 | ||||
-rw-r--r-- | libs/binder/BpBinder.cpp | 4 | ||||
-rw-r--r-- | libs/binder/IPCThreadState.cpp | 38 | ||||
-rw-r--r-- | libs/binder/include/binder/IPCThreadState.h | 8 | ||||
-rw-r--r-- | services/surfaceflinger/Android.bp | 1 | ||||
-rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 12 | ||||
-rw-r--r-- | services/surfaceflinger/ColorLayer.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 279 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 54 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 20 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/RenderArea.cpp | 10 | ||||
-rw-r--r-- | services/surfaceflinger/RenderArea.h | 2 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 312 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 6 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp | 5 |
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); } }; |