From 068e31b929b40a1bc9be742c04cbdf5b04f3ce97 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Wed, 21 Feb 2018 13:02:45 -0800 Subject: Implement Display Layer Stats Try to collect data for analyzing how many display controller layers we need and what we use them for. Also part of a bug fixing for potential memory leak of existing layer tracing work of winscope. Test: adb shell dumpsys SurfaceFlinger --enable-layer-stats Test: adb shell dumpsys SurfaceFlinger --disable-layer-stats Test: adb shell dumpsys SurfaceFlinger --clear-layer-stats Test: adb shell dumpsys SurfaceFlinger --dump-layer-stats Bug: b/73668062 Change-Id: Ie08aa85d34db2c2c767b8e27eb5aad6f7c3fb975 Merged-In: Ie08aa85d34db2c2c767b8e27eb5aad6f7c3fb975 --- services/surfaceflinger/LayerStats.cpp | 181 +++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 services/surfaceflinger/LayerStats.cpp (limited to 'services/surfaceflinger/LayerStats.cpp') diff --git a/services/surfaceflinger/LayerStats.cpp b/services/surfaceflinger/LayerStats.cpp new file mode 100644 index 0000000000..dc99b41cc6 --- /dev/null +++ b/services/surfaceflinger/LayerStats.cpp @@ -0,0 +1,181 @@ +/* + * 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. + */ +#undef LOG_TAG +#define LOG_TAG "LayerStats" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + +#include "LayerStats.h" +#include "DisplayHardware/HWComposer.h" + +#include +#include +#include +#include + +namespace android { + +void LayerStats::enable() { + ATRACE_CALL(); + std::lock_guard lock(mMutex); + if (mEnabled) return; + mLayerStatsMap.clear(); + mEnabled = true; + ALOGD("Logging enabled"); +} + +void LayerStats::disable() { + ATRACE_CALL(); + std::lock_guard lock(mMutex); + if (!mEnabled) return; + mEnabled = false; + ALOGD("Logging disabled"); +} + +void LayerStats::clear() { + ATRACE_CALL(); + std::lock_guard lock(mMutex); + mLayerStatsMap.clear(); + ALOGD("Cleared current layer stats"); +} + +bool LayerStats::isEnabled() { + return mEnabled; +} + +void LayerStats::traverseLayerTreeStatsLocked( + std::vector> layerTree, + const LayerProtoParser::LayerGlobal* layerGlobal) { + for (std::unique_ptr& layer : layerTree) { + if (!layer) continue; + traverseLayerTreeStatsLocked(std::move(layer->children), layerGlobal); + std::string key = + base::StringPrintf("%s,%s,%s,%s,%s,%s,%s,%s,%s", + destinationLocation(layer->hwcFrame.left, + layerGlobal->resolution[0], true), + destinationLocation(layer->hwcFrame.top, + layerGlobal->resolution[1], false), + destinationSize(layer->hwcFrame.right - layer->hwcFrame.left, + layerGlobal->resolution[0], true), + destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top, + layerGlobal->resolution[1], false), + layer->type.c_str(), scaleRatioWH(layer.get()).c_str(), + layerTransform(layer->hwcTransform), layer->pixelFormat.c_str(), + layer->dataspace.c_str()); + mLayerStatsMap[key]++; + } +} + +void LayerStats::logLayerStats(const LayersProto& layersProto) { + ATRACE_CALL(); + auto layerGlobal = LayerProtoParser::generateLayerGlobalInfo(layersProto); + auto layerTree = LayerProtoParser::generateLayerTree(layersProto); + std::lock_guard lock(mMutex); + traverseLayerTreeStatsLocked(std::move(layerTree), &layerGlobal); +} + +void LayerStats::dump(String8& result) { + ATRACE_CALL(); + ALOGD("Dumping"); + result.append("Count,DstPosX,DstPosY,DstWidth,DstHeight,LayerType,WScale,HScale,"); + result.append("Transform,PixelFormat,Dataspace\n"); + std::lock_guard lock(mMutex); + for (auto& u : mLayerStatsMap) { + result.appendFormat("%u,%s\n", u.second, u.first.c_str()); + } +} + +const char* LayerStats::destinationLocation(int32_t location, int32_t range, bool isHorizontal) { + static const char* locationArray[8] = {"0", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8"}; + int32_t ratio = location * 8 / range; + if (ratio < 0) return "N/A"; + if (isHorizontal) { + // X location is divided into 4 buckets {"0", "1/4", "1/2", "3/4"} + if (ratio > 6) return "3/4"; + // use index 0, 2, 4, 6 + return locationArray[ratio & ~1]; + } + if (ratio > 7) return "7/8"; + return locationArray[ratio]; +} + +const char* LayerStats::destinationSize(int32_t size, int32_t range, bool isWidth) { + static const char* sizeArray[8] = {"1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8", "1"}; + int32_t ratio = size * 8 / range; + if (ratio < 0) return "N/A"; + if (isWidth) { + // width is divided into 4 buckets {"1/4", "1/2", "3/4", "1"} + if (ratio > 6) return "1"; + // use index 1, 3, 5, 7 + return sizeArray[ratio | 1]; + } + if (ratio > 7) return "1"; + return sizeArray[ratio]; +} + +const char* LayerStats::layerTransform(int32_t transform) { + return getTransformName(static_cast(transform)); +} + +std::string LayerStats::scaleRatioWH(const LayerProtoParser::Layer* layer) { + if (!layer->type.compare("ColorLayer")) return "N/A,N/A"; + std::string ret = ""; + if (isRotated(layer->hwcTransform)) { + ret += scaleRatio(layer->hwcFrame.right - layer->hwcFrame.left, + static_cast(layer->hwcCrop.bottom - layer->hwcCrop.top)); + ret += ","; + ret += scaleRatio(layer->hwcFrame.bottom - layer->hwcFrame.top, + static_cast(layer->hwcCrop.right - layer->hwcCrop.left)); + } else { + ret += scaleRatio(layer->hwcFrame.right - layer->hwcFrame.left, + static_cast(layer->hwcCrop.right - layer->hwcCrop.left)); + ret += ","; + ret += scaleRatio(layer->hwcFrame.bottom - layer->hwcFrame.top, + static_cast(layer->hwcCrop.bottom - layer->hwcCrop.top)); + } + return ret; +} + +const char* LayerStats::scaleRatio(int32_t destinationScale, int32_t sourceScale) { + // Make scale buckets from <1/64 to >= 16, to avoid floating point + // calculation, x64 on destinationScale first + int32_t scale = destinationScale * 64 / sourceScale; + if (!scale) return "<1/64"; + if (scale < 2) return "1/64"; + if (scale < 4) return "1/32"; + if (scale < 8) return "1/16"; + if (scale < 16) return "1/8"; + if (scale < 32) return "1/4"; + if (scale < 64) return "1/2"; + if (scale < 128) return "1"; + if (scale < 256) return "2"; + if (scale < 512) return "4"; + if (scale < 1024) return "8"; + return ">=16"; +} + +bool LayerStats::isRotated(int32_t transform) { + return transform & HWC_TRANSFORM_ROT_90; +} + +bool LayerStats::isVFlipped(int32_t transform) { + return transform & HWC_TRANSFORM_FLIP_V; +} + +bool LayerStats::isHFlipped(int32_t transform) { + return transform & HWC_TRANSFORM_FLIP_H; +} + +} // namespace android -- cgit v1.2.3-59-g8ed1b From 7c64f17bd0d70aec63b475c3de850dcf3abaff33 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Wed, 7 Mar 2018 14:52:28 -0800 Subject: Implement Display Layer Stats V0.1 Try to collect data for analyzing how many display controller layers we need and what we use them for. This change will collect additional data from per frame point of view. Test: adb shell dumpsys SurfaceFlinger --enable-layer-stats Test: adb shell dumpsys SurfaceFlinger --disable-layer-stats Test: adb shell dumpsys SurfaceFlinger --clear-layer-stats Test: adb shell dumpsys SurfaceFlinger --dump-layer-stats Bug: b/75953772 Change-Id: Ib48777df7e1fed637be7eb1aefbdf1808d1daccd Merged-In: Ib48777df7e1fed637be7eb1aefbdf1808d1daccd --- libs/ui/DebugUtils.cpp | 27 ++++++ libs/ui/include/ui/DebugUtils.h | 1 + services/surfaceflinger/DisplayDevice.cpp | 11 +++ services/surfaceflinger/DisplayDevice.h | 6 ++ services/surfaceflinger/Layer.cpp | 11 +++ services/surfaceflinger/LayerStats.cpp | 97 +++++++++++++++++----- services/surfaceflinger/LayerStats.h | 19 +++-- services/surfaceflinger/SurfaceFlinger.cpp | 11 ++- .../surfaceflinger/layerproto/LayerProtoParser.cpp | 9 +- .../include/layerproto/LayerProtoParser.h | 5 ++ services/surfaceflinger/layerproto/layers.proto | 7 ++ 11 files changed, 171 insertions(+), 33 deletions(-) (limited to 'services/surfaceflinger/LayerStats.cpp') diff --git a/libs/ui/DebugUtils.cpp b/libs/ui/DebugUtils.cpp index d7d8618703..58fed84ea8 100644 --- a/libs/ui/DebugUtils.cpp +++ b/libs/ui/DebugUtils.cpp @@ -234,6 +234,33 @@ std::string decodeColorMode(ColorMode colorMode) { return android::base::StringPrintf("Unknown color mode %d", colorMode); } +std::string decodeColorTransform(android_color_transform colorTransform) { + switch (colorTransform) { + case HAL_COLOR_TRANSFORM_IDENTITY: + return std::string("Identity"); + + case HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX: + return std::string("Arbitrary matrix"); + + case HAL_COLOR_TRANSFORM_VALUE_INVERSE: + return std::string("Inverse value"); + + case HAL_COLOR_TRANSFORM_GRAYSCALE: + return std::string("Grayscale"); + + case HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA: + return std::string("Correct protanopia"); + + case HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA: + return std::string("Correct deuteranopia"); + + case HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA: + return std::string("Correct tritanopia"); + } + + return android::base::StringPrintf("Unknown color transform %d", colorTransform); +} + // Converts a PixelFormat to a human-readable string. Max 11 chars. // (Could use a table of prefab String8 objects.) std::string decodePixelFormat(android::PixelFormat format) { diff --git a/libs/ui/include/ui/DebugUtils.h b/libs/ui/include/ui/DebugUtils.h index 6350d0cf95..5e5df43740 100644 --- a/libs/ui/include/ui/DebugUtils.h +++ b/libs/ui/include/ui/DebugUtils.h @@ -30,5 +30,6 @@ std::string decodeTransfer(android_dataspace dataspace); std::string decodeRange(android_dataspace dataspace); std::string dataspaceDetails(android_dataspace dataspace); std::string decodeColorMode(android::ui::ColorMode colormode); +std::string decodeColorTransform(android_color_transform colorTransform); std::string decodePixelFormat(android::PixelFormat format); std::string to_string(const android::Rect& rect); diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 93cb849e28..8281ce0f56 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -97,6 +97,7 @@ DisplayDevice::DisplayDevice( mPowerMode(initialPowerMode), mActiveConfig(0), mActiveColorMode(ColorMode::NATIVE), + mColorTransform(HAL_COLOR_TRANSFORM_IDENTITY), mDisplayHasWideColor(supportWideColor), mDisplayHasHdr(supportHdr) { @@ -267,6 +268,16 @@ ColorMode DisplayDevice::getActiveColorMode() const { return mActiveColorMode; } +void DisplayDevice::setColorTransform(const mat4& transform) { + const bool isIdentity = (transform == mat4()); + mColorTransform = + isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX; +} + +android_color_transform_t DisplayDevice::getColorTransform() const { + return mColorTransform; +} + void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) { ANativeWindow* const window = mNativeWindow.get(); native_window_set_buffers_data_space(window, dataspace); diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index df729f5ce9..31bb4d0778 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -21,6 +21,8 @@ #include +#include + #include #include @@ -163,6 +165,8 @@ public: ui::ColorMode getActiveColorMode() const; void setActiveColorMode(ui::ColorMode mode); + android_color_transform_t getColorTransform() const; + void setColorTransform(const mat4& transform); void setCompositionDataSpace(android_dataspace dataspace); /* ------------------------------------------------------------------------ @@ -237,6 +241,8 @@ private: int mActiveConfig; // current active color mode ui::ColorMode mActiveColorMode; + // Current color transform + android_color_transform_t mColorTransform; // Need to know if display is wide-color capable or not. // Initialized by SurfaceFlinger when the DisplayDevice is created. diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index c3eb1bc85f..5c945edb5f 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -42,6 +42,7 @@ #include #include +#include "BufferLayer.h" #include "Colorizer.h" #include "DisplayDevice.h" #include "Layer.h" @@ -1937,6 +1938,16 @@ void Layer::writeToProto(LayerProto* layerInfo, int32_t hwcId) { const int32_t transform = static_cast(hwcInfo.transform); layerInfo->set_hwc_transform(transform); + + const int32_t compositionType = static_cast(hwcInfo.compositionType); + layerInfo->set_hwc_composition_type(compositionType); + + if (std::strcmp(getTypeId(), "BufferLayer") == 0 && + static_cast(this)->isProtected()) { + layerInfo->set_is_protected(true); + } else { + layerInfo->set_is_protected(false); + } } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/LayerStats.cpp b/services/surfaceflinger/LayerStats.cpp index dc99b41cc6..38ea6edfc5 100644 --- a/services/surfaceflinger/LayerStats.cpp +++ b/services/surfaceflinger/LayerStats.cpp @@ -19,6 +19,7 @@ #include "LayerStats.h" #include "DisplayHardware/HWComposer.h" +#include "ui/DebugUtils.h" #include #include @@ -31,7 +32,7 @@ void LayerStats::enable() { ATRACE_CALL(); std::lock_guard lock(mMutex); if (mEnabled) return; - mLayerStatsMap.clear(); + mLayerShapeStatsMap.clear(); mEnabled = true; ALOGD("Logging enabled"); } @@ -47,7 +48,7 @@ void LayerStats::disable() { void LayerStats::clear() { ATRACE_CALL(); std::lock_guard lock(mMutex); - mLayerStatsMap.clear(); + mLayerShapeStatsMap.clear(); ALOGD("Cleared current layer stats"); } @@ -57,42 +58,69 @@ bool LayerStats::isEnabled() { void LayerStats::traverseLayerTreeStatsLocked( std::vector> layerTree, - const LayerProtoParser::LayerGlobal* layerGlobal) { + const LayerProtoParser::LayerGlobal* layerGlobal, std::vector& layerShapeVec) { for (std::unique_ptr& layer : layerTree) { if (!layer) continue; - traverseLayerTreeStatsLocked(std::move(layer->children), layerGlobal); - std::string key = - base::StringPrintf("%s,%s,%s,%s,%s,%s,%s,%s,%s", - destinationLocation(layer->hwcFrame.left, - layerGlobal->resolution[0], true), - destinationLocation(layer->hwcFrame.top, - layerGlobal->resolution[1], false), - destinationSize(layer->hwcFrame.right - layer->hwcFrame.left, - layerGlobal->resolution[0], true), - destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top, - layerGlobal->resolution[1], false), - layer->type.c_str(), scaleRatioWH(layer.get()).c_str(), - layerTransform(layer->hwcTransform), layer->pixelFormat.c_str(), - layer->dataspace.c_str()); - mLayerStatsMap[key]++; + traverseLayerTreeStatsLocked(std::move(layer->children), layerGlobal, layerShapeVec); + std::string key = ""; + base::StringAppendF(&key, ",%s", layer->type.c_str()); + base::StringAppendF(&key, ",%s", layerCompositionType(layer->hwcCompositionType)); + base::StringAppendF(&key, ",%d", layer->isProtected); + base::StringAppendF(&key, ",%s", layerTransform(layer->hwcTransform)); + base::StringAppendF(&key, ",%s", layerPixelFormat(layer->activeBuffer.format)); + base::StringAppendF(&key, ",%s", layer->dataspace.c_str()); + base::StringAppendF(&key, ",%s", + destinationLocation(layer->hwcFrame.left, layerGlobal->resolution[0], + true)); + base::StringAppendF(&key, ",%s", + destinationLocation(layer->hwcFrame.top, layerGlobal->resolution[1], + false)); + base::StringAppendF(&key, ",%s", + destinationSize(layer->hwcFrame.right - layer->hwcFrame.left, + layerGlobal->resolution[0], true)); + base::StringAppendF(&key, ",%s", + destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top, + layerGlobal->resolution[1], false)); + base::StringAppendF(&key, ",%s", scaleRatioWH(layer.get()).c_str()); + base::StringAppendF(&key, ",%s", alpha(static_cast(layer->color.a))); + + layerShapeVec.push_back(key); + ALOGV("%s", key.c_str()); } } void LayerStats::logLayerStats(const LayersProto& layersProto) { ATRACE_CALL(); + ALOGV("Logging"); auto layerGlobal = LayerProtoParser::generateLayerGlobalInfo(layersProto); auto layerTree = LayerProtoParser::generateLayerTree(layersProto); + std::vector layerShapeVec; + std::lock_guard lock(mMutex); - traverseLayerTreeStatsLocked(std::move(layerTree), &layerGlobal); + traverseLayerTreeStatsLocked(std::move(layerTree), &layerGlobal, layerShapeVec); + + std::string layerShapeKey = + base::StringPrintf("%d,%s,%s,%s", static_cast(layerShapeVec.size()), + layerGlobal.colorMode.c_str(), layerGlobal.colorTransform.c_str(), + layerTransform(layerGlobal.globalTransform)); + ALOGV("%s", layerShapeKey.c_str()); + + std::sort(layerShapeVec.begin(), layerShapeVec.end(), std::greater()); + for (auto const& s : layerShapeVec) { + layerShapeKey += s; + } + + mLayerShapeStatsMap[layerShapeKey]++; } void LayerStats::dump(String8& result) { ATRACE_CALL(); ALOGD("Dumping"); - result.append("Count,DstPosX,DstPosY,DstWidth,DstHeight,LayerType,WScale,HScale,"); - result.append("Transform,PixelFormat,Dataspace\n"); std::lock_guard lock(mMutex); - for (auto& u : mLayerStatsMap) { + result.append("Frequency,LayerCount,ColorMode,ColorTransform,Orientation\n"); + result.append("LayerType,CompositionType,IsProtected,Transform,PixelFormat,Dataspace,"); + result.append("DstX,DstY,DstWidth,DstHeight,WScale,HScale,Alpha\n"); + for (auto& u : mLayerShapeStatsMap) { result.appendFormat("%u,%s\n", u.second, u.first.c_str()); } } @@ -129,6 +157,14 @@ const char* LayerStats::layerTransform(int32_t transform) { return getTransformName(static_cast(transform)); } +const char* LayerStats::layerCompositionType(int32_t compositionType) { + return getCompositionName(static_cast(compositionType)); +} + +const char* LayerStats::layerPixelFormat(int32_t pixelFormat) { + return decodePixelFormat(pixelFormat).c_str(); +} + std::string LayerStats::scaleRatioWH(const LayerProtoParser::Layer* layer) { if (!layer->type.compare("ColorLayer")) return "N/A,N/A"; std::string ret = ""; @@ -166,6 +202,21 @@ const char* LayerStats::scaleRatio(int32_t destinationScale, int32_t sourceScale return ">=16"; } +const char* LayerStats::alpha(float a) { + if (a == 1.0f) return "1.0"; + if (a > 0.9f) return "0.99"; + if (a > 0.8f) return "0.9"; + if (a > 0.7f) return "0.8"; + if (a > 0.6f) return "0.7"; + if (a > 0.5f) return "0.6"; + if (a > 0.4f) return "0.5"; + if (a > 0.3f) return "0.4"; + if (a > 0.2f) return "0.3"; + if (a > 0.1f) return "0.2"; + if (a > 0.0f) return "0.1"; + return "0.0"; +} + bool LayerStats::isRotated(int32_t transform) { return transform & HWC_TRANSFORM_ROT_90; } @@ -178,4 +229,4 @@ bool LayerStats::isHFlipped(int32_t transform) { return transform & HWC_TRANSFORM_FLIP_H; } -} // namespace android +} // namespace android diff --git a/services/surfaceflinger/LayerStats.h b/services/surfaceflinger/LayerStats.h index de2b47c3ba..7871fc6602 100644 --- a/services/surfaceflinger/LayerStats.h +++ b/services/surfaceflinger/LayerStats.h @@ -39,17 +39,24 @@ private: // Traverse layer tree to get all visible layers' stats void traverseLayerTreeStatsLocked( std::vector> layerTree, - const LayerProtoParser::LayerGlobal* layerGlobal); + const LayerProtoParser::LayerGlobal* layerGlobal, + std::vector& layerShapeVec); // Convert layer's top-left position into 8x8 percentage of the display static const char* destinationLocation(int32_t location, int32_t range, bool isHorizontal); // Convert layer's size into 8x8 percentage of the display static const char* destinationSize(int32_t size, int32_t range, bool isWidth); // Return the name of the transform static const char* layerTransform(int32_t transform); + // Return the name of the composition type + static const char* layerCompositionType(int32_t compositionType); + // Return the name of the pixel format + static const char* layerPixelFormat(int32_t pixelFormat); // Calculate scale ratios of layer's width/height with rotation information static std::string scaleRatioWH(const LayerProtoParser::Layer* layer); // Calculate scale ratio from source to destination and convert to string static const char* scaleRatio(int32_t destinationScale, int32_t sourceScale); + // Bucket the alpha into designed buckets + static const char* alpha(float a); // Return whether the original buffer is rotated in final composition static bool isRotated(int32_t transform); // Return whether the original buffer is V-flipped in final composition @@ -60,10 +67,10 @@ private: bool mEnabled = false; // Protect mLayersStatsMap std::mutex mMutex; - // Hashmap for tracking the layer stats - // KEY is a concatenation of a particular set of layer properties - // VALUE is the number of times this particular get scanned out - std::unordered_map mLayerStatsMap; + // Hashmap for tracking the frame(layer shape) stats + // KEY is a concatenation of all layers' properties within a frame + // VALUE is the number of times this particular set has been scanned out + std::unordered_map mLayerShapeStatsMap; }; -} // namespace android +} // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index babac37d7d..f7f5b58616 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1960,6 +1960,7 @@ void SurfaceFlinger::setUpHWComposer() { continue; } if (colorMatrix != mPreviousColorMatrix) { + displayDevice->setColorTransform(colorMatrix); status_t result = getBE().mHwc->setColorTransform(hwcId, colorMatrix); ALOGE_IF(result != NO_ERROR, "Failed to set color transform on " "display %zd: %d", displayId, result); @@ -4029,15 +4030,19 @@ LayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet) const LayersProto SurfaceFlinger::dumpVisibleLayersProtoInfo(int32_t hwcId) const { LayersProto layersProto; - const sp& displayDevice(mDisplays[hwcId]); + SizeProto* resolution = layersProto.mutable_resolution(); resolution->set_w(displayDevice->getWidth()); resolution->set_h(displayDevice->getHeight()); + layersProto.set_color_mode(decodeColorMode(displayDevice->getActiveColorMode())); + layersProto.set_color_transform(decodeColorTransform(displayDevice->getColorTransform())); + layersProto.set_global_transform( + static_cast(displayDevice->getOrientationTransform())); + mDrawingState.traverseInZOrder([&](Layer* layer) { - if (!layer->visibleRegion.isEmpty() && - layer->getBE().mHwcLayers.count(hwcId)) { + if (!layer->visibleRegion.isEmpty() && layer->getBE().mHwcLayers.count(hwcId)) { LayerProto* layerProto = layersProto.add_layers(); layer->writeToProto(layerProto, hwcId); } diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp index cef6c21eb1..fcf42f00a9 100644 --- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp +++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp @@ -44,7 +44,12 @@ bool sortLayerUniquePtrs(const std::unique_ptr& lhs, const LayerProtoParser::LayerGlobal LayerProtoParser::generateLayerGlobalInfo( const LayersProto& layersProto) { - return {{layersProto.resolution().w(), layersProto.resolution().h()}}; + LayerGlobal layerGlobal; + layerGlobal.resolution = {layersProto.resolution().w(), layersProto.resolution().h()}; + layerGlobal.colorMode = layersProto.color_mode(); + layerGlobal.colorTransform = layersProto.color_transform(); + layerGlobal.globalTransform = layersProto.global_transform(); + return layerGlobal; } std::vector> LayerProtoParser::generateLayerTree( @@ -116,6 +121,8 @@ LayerProtoParser::Layer* LayerProtoParser::generateLayer(const LayerProto& layer layer->hwcTransform = layerProto.hwc_transform(); layer->windowType = layerProto.window_type(); layer->appId = layerProto.app_id(); + layer->hwcCompositionType = layerProto.hwc_composition_type(); + layer->isProtected = layerProto.is_protected(); return layer; } diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h index fd893da1b1..74a6f28f2b 100644 --- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h +++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h @@ -112,6 +112,8 @@ public: int32_t hwcTransform; int32_t windowType; int32_t appId; + int32_t hwcCompositionType; + bool isProtected; std::string to_string() const; }; @@ -119,6 +121,9 @@ public: class LayerGlobal { public: int2 resolution; + std::string colorMode; + std::string colorTransform; + int32_t globalTransform; }; static const LayerGlobal generateLayerGlobalInfo(const LayersProto& layersProto); diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto index 6675aae797..77c6675b7f 100644 --- a/services/surfaceflinger/layerproto/layers.proto +++ b/services/surfaceflinger/layerproto/layers.proto @@ -8,6 +8,9 @@ package android.surfaceflinger; message LayersProto { repeated LayerProto layers = 1; optional SizeProto resolution = 2; + optional string color_mode = 3; + optional string color_transform = 4; + optional int32 global_transform = 5; } // Information about each layer. @@ -73,6 +76,10 @@ message LayerProto { optional int32 hwc_transform = 32; optional int32 window_type = 33; optional int32 app_id = 34; + // The layer's composition type + optional int32 hwc_composition_type = 35; + // If it's a buffer layer, indicate if the content is protected + optional bool is_protected = 36; } message PositionProto { -- cgit v1.2.3-59-g8ed1b From 2418010f4306096891373d74a9297e0f09b8bcd5 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Mon, 9 Apr 2018 11:05:39 -0700 Subject: LayerStats: some changes for referencings Change a reference use to pointer instead, also roll back some changes Test: go/display-layer-stats Bug: b/75953772 Change-Id: I06373e3264a8e9d8db3ed5ddfd10adf8fb5b901c --- services/surfaceflinger/LayerStats.cpp | 21 +++++++++++---------- services/surfaceflinger/LayerStats.h | 6 +++--- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'services/surfaceflinger/LayerStats.cpp') diff --git a/services/surfaceflinger/LayerStats.cpp b/services/surfaceflinger/LayerStats.cpp index 38ea6edfc5..04ab121560 100644 --- a/services/surfaceflinger/LayerStats.cpp +++ b/services/surfaceflinger/LayerStats.cpp @@ -57,11 +57,12 @@ bool LayerStats::isEnabled() { } void LayerStats::traverseLayerTreeStatsLocked( - std::vector> layerTree, - const LayerProtoParser::LayerGlobal* layerGlobal, std::vector& layerShapeVec) { - for (std::unique_ptr& layer : layerTree) { + const std::vector>& layerTree, + const LayerProtoParser::LayerGlobal& layerGlobal, + std::vector* const outLayerShapeVec) { + for (const auto& layer : layerTree) { if (!layer) continue; - traverseLayerTreeStatsLocked(std::move(layer->children), layerGlobal, layerShapeVec); + traverseLayerTreeStatsLocked(layer->children, layerGlobal, outLayerShapeVec); std::string key = ""; base::StringAppendF(&key, ",%s", layer->type.c_str()); base::StringAppendF(&key, ",%s", layerCompositionType(layer->hwcCompositionType)); @@ -70,21 +71,21 @@ void LayerStats::traverseLayerTreeStatsLocked( base::StringAppendF(&key, ",%s", layerPixelFormat(layer->activeBuffer.format)); base::StringAppendF(&key, ",%s", layer->dataspace.c_str()); base::StringAppendF(&key, ",%s", - destinationLocation(layer->hwcFrame.left, layerGlobal->resolution[0], + destinationLocation(layer->hwcFrame.left, layerGlobal.resolution[0], true)); base::StringAppendF(&key, ",%s", - destinationLocation(layer->hwcFrame.top, layerGlobal->resolution[1], + destinationLocation(layer->hwcFrame.top, layerGlobal.resolution[1], false)); base::StringAppendF(&key, ",%s", destinationSize(layer->hwcFrame.right - layer->hwcFrame.left, - layerGlobal->resolution[0], true)); + layerGlobal.resolution[0], true)); base::StringAppendF(&key, ",%s", destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top, - layerGlobal->resolution[1], false)); + layerGlobal.resolution[1], false)); base::StringAppendF(&key, ",%s", scaleRatioWH(layer.get()).c_str()); base::StringAppendF(&key, ",%s", alpha(static_cast(layer->color.a))); - layerShapeVec.push_back(key); + outLayerShapeVec->push_back(key); ALOGV("%s", key.c_str()); } } @@ -97,7 +98,7 @@ void LayerStats::logLayerStats(const LayersProto& layersProto) { std::vector layerShapeVec; std::lock_guard lock(mMutex); - traverseLayerTreeStatsLocked(std::move(layerTree), &layerGlobal, layerShapeVec); + traverseLayerTreeStatsLocked(layerTree, layerGlobal, &layerShapeVec); std::string layerShapeKey = base::StringPrintf("%d,%s,%s,%s", static_cast(layerShapeVec.size()), diff --git a/services/surfaceflinger/LayerStats.h b/services/surfaceflinger/LayerStats.h index 7871fc6602..7a190fdb41 100644 --- a/services/surfaceflinger/LayerStats.h +++ b/services/surfaceflinger/LayerStats.h @@ -38,9 +38,9 @@ public: private: // Traverse layer tree to get all visible layers' stats void traverseLayerTreeStatsLocked( - std::vector> layerTree, - const LayerProtoParser::LayerGlobal* layerGlobal, - std::vector& layerShapeVec); + const std::vector>& layerTree, + const LayerProtoParser::LayerGlobal& layerGlobal, + std::vector* const outLayerShapeVec); // Convert layer's top-left position into 8x8 percentage of the display static const char* destinationLocation(int32_t location, int32_t range, bool isHorizontal); // Convert layer's size into 8x8 percentage of the display -- cgit v1.2.3-59-g8ed1b