1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza// #define LOG_NDEBUG 0 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 191c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 21921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h> 220147a17adb08a155e1d6f72e6ca5e794fc7f5cc4Romain Guy#include <algorithm> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h> 25c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju#include <mutex> 2663f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h> 2786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h> 28b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h> 292b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza#include <optional> 30921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 327823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 35c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h> 3699b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 377303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian 3887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar#include <dvr/vr_flinger.h> 3987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 405d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter#include <ui/DebugUtils.h> 41c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h> 4267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h> 43c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 441a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h> 454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h> 461a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h> 47a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita#include <gui/LayerDebugInfo.h> 48e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h> 49921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h> 51921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h> 524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h> 53d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 54cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h> 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 580a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato#include <utils/Timers.h> 591c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 61921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h> 62ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 64578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr#include "BufferLayer.h" 653e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h" 66578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr#include "ColorLayer.h" 673e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h" 68578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr#include "ContainerLayer.h" 6990ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h" 70faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h" 71578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr#include "DisplayDevice.h" 72d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h" 73d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h" 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 751f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr#include "LayerVector.h" 761db73f66624e7d151710483dd58e03eed672f064Robert Carr#include "MonitoredProducer.h" 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 78578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr#include "clz.h" 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 80b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas#include "DisplayHardware/ComposerHal.h" 81a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h" 82a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h" 8399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h" 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 85ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h" 86ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian 87875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h" 88ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h> 89875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 904b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> 917501ed66a05f530062925011d1342e8651216051Iris Chang#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h> 927501ed66a05f530062925011d1342e8651216051Iris Chang#include <android/hardware/configstore/1.1/types.h> 934351857c9de86df9f418b3df28aebb1239ca35ddJaesoo Lee#include <configstore/Utils.h> 944b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park 951d04428c3cff3503212ec3e76775ca5ba20abc18chaviw#include <layerproto/LayerProtoParser.h> 961d04428c3cff3503212ec3e76775ca5ba20abc18chaviw 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT 1 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 99fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/* 100fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all 101fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels. 102fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */ 103fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS false 104fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1074351857c9de86df9f418b3df28aebb1239ca35ddJaesoo Leeusing namespace android::hardware::configstore; 1084b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Parkusing namespace android::hardware::configstore::V1_0; 109fd997e0969100418b4df8b8d97d21d497afa76c3Peiyong Linusing ui::ColorMode; 11034beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Linusing ui::Dataspace; 1116266589793ddd9769a649a6b5f61ef115179572bPeiyong Linusing ui::Hdr; 1120e7a791d51e92aafefd416044a2d38b6eec22a00Peiyong Linusing ui::RenderIntent; 1134b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park 114b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomasnamespace { 115b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomasclass ConditionalLock { 116b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomaspublic: 117b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas ConditionalLock(Mutex& mutex, bool lock) : mMutex(mutex), mLocked(lock) { 118b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas if (lock) { 119b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas mMutex.lock(); 120b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas } 121b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas } 122b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas ~ConditionalLock() { if (mLocked) mMutex.unlock(); } 123b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomasprivate: 124b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas Mutex& mMutex; 125b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas bool mLocked; 126b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas}; 127b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas} // namespace anonymous 128b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 13199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 13299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 13399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 13499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP"); 13599b49840d309727678b77403d6cc9f920111623fMathias Agopian 13699b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 1370cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglardint64_t SurfaceFlinger::vsyncPhaseOffsetNs; 1380cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglardint64_t SurfaceFlinger::sfVsyncPhaseOffsetNs; 139c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglardint64_t SurfaceFlinger::dispSyncPresentTimeOffset; 140a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglardbool SurfaceFlinger::useHwcForRgbToYuv; 141c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglarduint64_t SurfaceFlinger::maxVirtualDisplaySize; 142cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglardbool SurfaceFlinger::hasSyncFramework; 143050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasbool SurfaceFlinger::useVrFlinger; 1441971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglardint64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers; 145c520831fb7ea03e9d515add9b2d96d423b3b6093Lloyd Pique// TODO(courtneygo): Rename hasWideColorDisplay to clarify its actual meaning. 1465d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchterbool SurfaceFlinger::hasWideColorDisplay; 14799b49840d309727678b77403d6cc9f920111623fMathias Agopian 148a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita 149a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raitastd::string getHwcServiceName() { 150a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita char value[PROPERTY_VALUE_MAX] = {}; 151a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita property_get("debug.sf.hwc_service_name", value, "default"); 152a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita ALOGI("Using HWComposer service: '%s'", value); 153a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita return std::string(value); 154a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita} 155a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita 156a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raitabool useTrebleTestingOverride() { 157a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita char value[PROPERTY_VALUE_MAX] = {}; 158a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita property_get("debug.sf.treble_testing_override", value, "false"); 159a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita ALOGI("Treble testing override: '%s'", value); 160a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita return std::string(value) == "true"; 161a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita} 162a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita 163dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Linstd::string decodeDisplayColorSetting(DisplayColorSetting displayColorSetting) { 164dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin switch(displayColorSetting) { 165dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin case DisplayColorSetting::MANAGED: 1660d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu return std::string("Managed"); 167dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin case DisplayColorSetting::UNMANAGED: 1680d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu return std::string("Unmanaged"); 169dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin case DisplayColorSetting::ENHANCED: 1700d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu return std::string("Enhanced"); 1710d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu default: 1720d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu return std::string("Unknown ") + 1730d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu std::to_string(static_cast<int>(displayColorSetting)); 174dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin } 175dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin} 176dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin 1770959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd PiqueNativeWindowSurface::~NativeWindowSurface() = default; 1780959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 1790959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Piquenamespace impl { 1800959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 1810959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Piqueclass NativeWindowSurface final : public android::NativeWindowSurface { 1820959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Piquepublic: 1830959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique static std::unique_ptr<android::NativeWindowSurface> create( 1840959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique const sp<IGraphicBufferProducer>& producer) { 1850959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique return std::make_unique<NativeWindowSurface>(producer); 1860959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique } 1870959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 1880959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique explicit NativeWindowSurface(const sp<IGraphicBufferProducer>& producer) 1890959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique : surface(new Surface(producer, false)) {} 1900959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 1910959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique ~NativeWindowSurface() override = default; 1920959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 1930959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Piqueprivate: 1940959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique sp<ANativeWindow> getNativeWindow() const override { return surface; } 1950959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 1960959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique void preallocateBuffers() override { surface->allocateBuffers(); } 1970959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 1980959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique sp<Surface> surface; 1990959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique}; 2000959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 2010959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique} // namespace impl 2020959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 203bc8152863f81c9af1038d92c9eb8caca1cfd4027David SodmanSurfaceFlingerBE::SurfaceFlingerBE() 204bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman : mHwcServiceName(getHwcServiceName()), 205bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman mRenderEngine(nullptr), 2064a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman mFrameBuckets(), 2074a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman mTotalTime(0), 2084a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman mLastSwapTime(0), 209bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman mComposerSequenceId(0) { 210bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman} 211bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman 2122d3ee6dda3547b08b0de3373da5b6b2edb223fa9Lloyd PiqueSurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag) 21312eb423785adba54be4c7112e5198a80d563896eLloyd Pique : BnSurfaceComposer(), 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 2152d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending(false), 2162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending(false), 217076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLayersRemoved(false), 2181f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mLayersAdded(false), 21952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian mRepaintEverything(0), 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBootTime(systemTime()), 2219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mBuiltinDisplays(), 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty(false), 2239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid(false), 2244b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending(false), 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion(0), 2268afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS(0), 22773d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian mDebugDisableHWC(0), 228a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint(0), 2299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInSwapBuffers(0), 2309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastSwapBufferTime(0), 2319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mDebugInTransaction(0), 2329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian mLastTransactionTime(0), 233ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian mBootFinished(false), 234ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage(false), 2354a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mPrimaryDispSync("PrimaryDispSync"), 236faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled(false), 237948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable(false), 238b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff(false), 239050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas mNumLayers(0), 240b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas mVrFlingerRequestsDisplay(false), 24112eb423785adba54be4c7112e5198a80d563896eLloyd Pique mMainThreadId(std::this_thread::get_id()), 2420959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique mCreateBufferQueue(&BufferQueue::createBufferQueue), 2430959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique mCreateNativeWindowSurface(&impl::NativeWindowSurface::create) {} 2442d3ee6dda3547b08b0de3373da5b6b2edb223fa9Lloyd Pique 2452d3ee6dda3547b08b0de3373da5b6b2edb223fa9Lloyd PiqueSurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) { 246cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard ALOGI("SurfaceFlinger is starting"); 2470cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard 2480cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs, 2490cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard &ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000); 2500cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard 2510cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs, 2520cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard &ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000); 2530cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard 254cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard hasSyncFramework = getBool< ISurfaceFlingerConfigs, 255cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard &ISurfaceFlingerConfigs::hasSyncFramework>(true); 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 257c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs, 258c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0); 259c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard 260a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs, 261a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard &ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false); 262a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard 263c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs, 264c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard &ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0); 265c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard 266050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Vr flinger is only enabled on Daydream ready devices. 267050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas useVrFlinger = getBool< ISurfaceFlingerConfigs, 268050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas &ISurfaceFlingerConfigs::useVrFlinger>(false); 269050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 2701971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard maxFrameBufferAcquiredBuffers = getInt64< ISurfaceFlingerConfigs, 2711971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2); 2721971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard 2735d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter hasWideColorDisplay = 2745d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false); 2755d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 2767501ed66a05f530062925011d1342e8651216051Iris Chang V1_1::DisplayOrientation primaryDisplayOrientation = 2777501ed66a05f530062925011d1342e8651216051Iris Chang getDisplayOrientation< V1_1::ISurfaceFlingerConfigs, &V1_1::ISurfaceFlingerConfigs::primaryDisplayOrientation>( 2787501ed66a05f530062925011d1342e8651216051Iris Chang V1_1::DisplayOrientation::ORIENTATION_0); 2797501ed66a05f530062925011d1342e8651216051Iris Chang 2807501ed66a05f530062925011d1342e8651216051Iris Chang switch (primaryDisplayOrientation) { 2817501ed66a05f530062925011d1342e8651216051Iris Chang case V1_1::DisplayOrientation::ORIENTATION_90: 2827501ed66a05f530062925011d1342e8651216051Iris Chang mPrimaryDisplayOrientation = DisplayState::eOrientation90; 2837501ed66a05f530062925011d1342e8651216051Iris Chang break; 2847501ed66a05f530062925011d1342e8651216051Iris Chang case V1_1::DisplayOrientation::ORIENTATION_180: 2857501ed66a05f530062925011d1342e8651216051Iris Chang mPrimaryDisplayOrientation = DisplayState::eOrientation180; 2867501ed66a05f530062925011d1342e8651216051Iris Chang break; 2877501ed66a05f530062925011d1342e8651216051Iris Chang case V1_1::DisplayOrientation::ORIENTATION_270: 2887501ed66a05f530062925011d1342e8651216051Iris Chang mPrimaryDisplayOrientation = DisplayState::eOrientation270; 2897501ed66a05f530062925011d1342e8651216051Iris Chang break; 2907501ed66a05f530062925011d1342e8651216051Iris Chang default: 2917501ed66a05f530062925011d1342e8651216051Iris Chang mPrimaryDisplayOrientation = DisplayState::eOrientationDefault; 2927501ed66a05f530062925011d1342e8651216051Iris Chang break; 2937501ed66a05f530062925011d1342e8651216051Iris Chang } 2947501ed66a05f530062925011d1342e8651216051Iris Chang ALOGV("Primary Display Orientation is set to %2d.", mPrimaryDisplayOrientation); 2957501ed66a05f530062925011d1342e8651216051Iris Chang 29699974d2935a520141d77983ac0329350460f2379David Sodman mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset); 297f41745301d5ecfa680dcef3a1948a8a321f80509Saurabh Shah 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // debugging stuff... 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char value[PROPERTY_VALUE_MAX]; 3008afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 301b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian property_get("ro.bq.gpu_to_cpu_unsupported", value, "0"); 30250210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian mGpuToCpuSupported = !atoi(value); 303b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project property_get("debug.sf.showupdates", value, "0"); 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = atoi(value); 3068afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian 3078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian property_get("debug.sf.ddms", value, "0"); 3088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian mDebugDDMS = atoi(value); 3098afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian if (mDebugDDMS) { 31063f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!startDdmConnection()) { 31163f165fd6b86d04be94d4023e845e98560504a96Keun young Park // start failed, and DDMS debugging not enabled 31263f165fd6b86d04be94d4023e845e98560504a96Keun young Park mDebugDDMS = 0; 31363f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 3148afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian } 315c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugRegion, "showupdates enabled"); 316c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 317c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza 318c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza property_get("debug.sf.disable_backpressure", value, "0"); 319c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza mPropagateBackpressure = !atoi(value); 320c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation"); 3218cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza 322642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard property_get("debug.sf.enable_hwc_vds", value, "0"); 323642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard mUseHwcVirtualDisplays = atoi(value); 324642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays"); 32563a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard 326c65dafa95467f52e7f65350b38e94ab217c008daFabien Sanglard property_get("ro.sf.disable_triple_buffer", value, "1"); 327c65dafa95467f52e7f65350b38e94ab217c008daFabien Sanglard mLayerTripleBufferingDisabled = atoi(value); 32863a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering"); 3293054f004567bffc4b77e31fcf8d6c126b2262295Romain Guy 330243b378f47552ab6916fc9b92557c0df0557fd98Yiwei Zhang const size_t defaultListSize = MAX_LAYERS; 3310a0158c25c74de41770a9fa2f8d7da234a0daceeDan Stoza auto listSize = property_get_int32("debug.sf.max_igbp_list_size", int32_t(defaultListSize)); 3320a0158c25c74de41770a9fa2f8d7da234a0daceeDan Stoza mMaxGraphicBufferProducerListSize = (listSize > 0) ? size_t(listSize) : defaultListSize; 3330a0158c25c74de41770a9fa2f8d7da234a0daceeDan Stoza 3342713c30843816d3511b39b85a2c268a2b7682047Dan Stoza property_get("debug.sf.early_phase_offset_ns", value, "0"); 3352713c30843816d3511b39b85a2c268a2b7682047Dan Stoza const int earlyWakeupOffsetOffsetNs = atoi(value); 3362713c30843816d3511b39b85a2c268a2b7682047Dan Stoza ALOGI_IF(earlyWakeupOffsetOffsetNs != 0, "Enabling separate early offset"); 3372713c30843816d3511b39b85a2c268a2b7682047Dan Stoza mVsyncModulator.setPhaseOffsets(sfVsyncPhaseOffsetNs - earlyWakeupOffsetOffsetNs, 3382713c30843816d3511b39b85a2c268a2b7682047Dan Stoza sfVsyncPhaseOffsetNs); 3392713c30843816d3511b39b85a2c268a2b7682047Dan Stoza 34011d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy // We should be reading 'persist.sys.sf.color_saturation' here 34111d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy // but since /data may be encrypted, we need to wait until after vold 34211d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy // comes online to attempt to read the property. The property is 34311d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy // instead read after the boot animation 344a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita 345a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita if (useTrebleTestingOverride()) { 346a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita // Without the override SurfaceFlinger cannot connect to HIDL 347a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita // services that are not listed in the manifests. Considered 348a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita // deriving the setting from the set service name, but it 349a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita // would be brittle if the name that's not 'default' is used 350a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita // for production purposes later on. 351a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita setenv("TREBLE_TESTING_OVERRIDE", "true", true); 352a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita } 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 35599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef() 35699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 3579123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique mEventQueue->init(this); 35899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 35999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger() 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 364c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */) 36599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{ 36699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // the window manager died on us. prepare its eulogy. 36799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 36813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // restore initial conditions (default device unblank, etc) 36913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 37099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 37199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian // restart the boot-animation 372a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian startBootAnim(); 37399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 37499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 3751db73f66624e7d151710483dd58e03eed672f064Robert Carrstatic sp<ISurfaceComposerClient> initClient(const sp<Client>& client) { 37696f0819f81293076e652792794a961543e6750d7Mathias Agopian status_t err = client->initCheck(); 37796f0819f81293076e652792794a961543e6750d7Mathias Agopian if (err == NO_ERROR) { 3781db73f66624e7d151710483dd58e03eed672f064Robert Carr return client; 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3801db73f66624e7d151710483dd58e03eed672f064Robert Carr return nullptr; 3811db73f66624e7d151710483dd58e03eed672f064Robert Carr} 3821db73f66624e7d151710483dd58e03eed672f064Robert Carr 3831db73f66624e7d151710483dd58e03eed672f064Robert Carrsp<ISurfaceComposerClient> SurfaceFlinger::createConnection() { 3841db73f66624e7d151710483dd58e03eed672f064Robert Carr return initClient(new Client(this)); 3851db73f66624e7d151710483dd58e03eed672f064Robert Carr} 3861db73f66624e7d151710483dd58e03eed672f064Robert Carr 3871db73f66624e7d151710483dd58e03eed672f064Robert Carrsp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection( 3881db73f66624e7d151710483dd58e03eed672f064Robert Carr const sp<IGraphicBufferProducer>& gbp) { 3891db73f66624e7d151710483dd58e03eed672f064Robert Carr if (authenticateSurfaceTexture(gbp) == false) { 3901db73f66624e7d151710483dd58e03eed672f064Robert Carr return nullptr; 3911db73f66624e7d151710483dd58e03eed672f064Robert Carr } 3921db73f66624e7d151710483dd58e03eed672f064Robert Carr const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer(); 3931db73f66624e7d151710483dd58e03eed672f064Robert Carr if (layer == nullptr) { 3941db73f66624e7d151710483dd58e03eed672f064Robert Carr return nullptr; 3951db73f66624e7d151710483dd58e03eed672f064Robert Carr } 3961db73f66624e7d151710483dd58e03eed672f064Robert Carr 3971db73f66624e7d151710483dd58e03eed672f064Robert Carr return initClient(new Client(this, layer)); 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 400dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, 401dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis bool secure) 402e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 403e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian class DisplayToken : public BBinder { 404e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<SurfaceFlinger> flinger; 405e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian virtual ~DisplayToken() { 406e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // no more references, this display must be terminated 407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(flinger->mStateLock); 408e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->mCurrentState.displays.removeItem(this); 409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flinger->setTransactionFlags(eDisplayTransactionNeeded); 410e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 411e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian public: 412c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit DisplayToken(const sp<SurfaceFlinger>& flinger) 413e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian : flinger(flinger) { 414e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 415e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian }; 416e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 417e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian sp<BBinder> token = new DisplayToken(this); 418e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 419e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian Mutex::Autolock _l(mStateLock); 42053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure); 4218dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden info.displayName = displayName; 422e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.displays.add(token, info); 4234d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->saveDisplayCreation(info); 424e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return token; 425e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 426e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 4276c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) { 4286c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall Mutex::Autolock _l(mStateLock); 4296c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 4306c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ssize_t idx = mCurrentState.displays.indexOfKey(display); 4316c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (idx < 0) { 4326c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGW("destroyDisplay: invalid display token"); 4336c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 4346c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 4356c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 4366c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 4376c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall if (!info.isVirtualDisplay()) { 4386c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall ALOGE("destroyDisplay called for non-virtual display"); 4396c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall return; 4406c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall } 4414d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->saveDisplayDeletion(info.displayId); 4426c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall mCurrentState.displays.removeItemsAt(idx); 4436c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall setTransactionFlags(eDisplayTransactionNeeded); 4446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall} 4456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall 446e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 4479e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 448e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 449566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin return nullptr; 450e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 451692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall return mBuiltinDisplays[id]; 452e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 453e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished() 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 456f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang if (mStartPropertySetThread->join() != NO_ERROR) { 457f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang ALOGE("Join StartPropertySetThread failed!"); 458b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang } 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t now = systemTime(); 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const nsecs_t duration = now - mBootTime; 461a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 4621f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 4631f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // wait patiently for the window manager death 4641f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian const String16 name("window"); 4651f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian sp<IBinder> window(defaultServiceManager()->getService(name)); 4661f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian if (window != 0) { 467921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 4681f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian } 4691f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian 470050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (mVrFlinger) { 471050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas mVrFlinger->OnBootFinished(); 472050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } 473050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 4741f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian // stop boot animation 475a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // formerly we would just kill the process, but we now ask it to exit so it 476a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian // can choose where to stop the animation. 477a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian property_set("service.bootanim.exit", "1"); 4780a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato 4790a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato const int LOGTAG_SF_STOP_BOOTANIM = 60110; 4800a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM, 4810a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); 48211d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy 4832924d01304dba0b714c556b14e45e34f70472e96Thierry Strudel sp<LambdaMessage> readProperties = new LambdaMessage([&]() { 48411d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy readPersistentProperties(); 48511d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy }); 4862924d01304dba0b714c556b14e45e34f70472e96Thierry Strudel postMessageAsync(readProperties); 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) { 490921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageDestroyGLTexture : public MessageBase { 491144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique RE::RenderEngine& engine; 4923f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texture; 493921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian public: 494144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique MessageDestroyGLTexture(RE::RenderEngine& engine, uint32_t texture) 495144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique : engine(engine), texture(texture) {} 496921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian virtual bool handler() { 4973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.deleteTextures(1, &texture); 498921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return true; 499921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian } 500921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian }; 5013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture)); 502921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 503921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 504e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Piqueclass DispSyncSource final : public VSyncSource, private DispSync::Callback { 505faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic: 5065167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync, 5074a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray const char* name) : 5084a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mName(name), 5090a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue(0), 5100a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mTraceVsync(traceVsync), 5114a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mVsyncOnLabel(String8::format("VsyncOn-%s", name)), 5124a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray mVsyncEventLabel(String8::format("VSYNC-%s", name)), 513db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mDispSync(dispSync), 514db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mCallbackMutex(), 515db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mVsyncMutex(), 516db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset(phaseOffset), 517db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled(false) {} 518faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 519e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique ~DispSyncSource() override = default; 520faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 521e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique void setVSyncEnabled(bool enable) override { 522db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 523faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (enable) { 5244a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray status_t err = mDispSync->addEventListener(mName, mPhaseOffset, 525faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 526faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 527faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error registering vsync callback: %s (%d)", 528faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 529faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 5305167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 1); 531faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 532faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis status_t err = mDispSync->removeEventListener( 533faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis static_cast<DispSync::Callback*>(this)); 534faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (err != NO_ERROR) { 535faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ALOGE("error unregistering vsync callback: %s (%d)", 536faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis strerror(-err), err); 537faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 5385167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden //ATRACE_INT(mVsyncOnLabel.string(), 0); 539faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 540db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEnabled = enable; 541faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 542faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 543e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique void setCallback(VSyncSource::Callback* callback) override{ 544db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 545faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mCallback = callback; 546faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 547faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 548e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique void setPhaseOffset(nsecs_t phaseOffset) override { 549db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mVsyncMutex); 550db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 551db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // Normalize phaseOffset to [0, period) 552db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza auto period = mDispSync->getPeriod(); 553db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset %= period; 554db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (phaseOffset < 0) { 555db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're here, then phaseOffset is in (-period, 0). After this 556db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // operation, it will be in (0, period) 557db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza phaseOffset += period; 558db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 559db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mPhaseOffset = phaseOffset; 560db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 561db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza // If we're not enabled, we don't need to mess with the listeners 562db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (!mEnabled) { 563db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return; 564db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 565db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 5662713c30843816d3511b39b85a2c268a2b7682047Dan Stoza status_t err = mDispSync->changePhaseOffset(static_cast<DispSync::Callback*>(this), 5672713c30843816d3511b39b85a2c268a2b7682047Dan Stoza mPhaseOffset); 568db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza if (err != NO_ERROR) { 5692713c30843816d3511b39b85a2c268a2b7682047Dan Stoza ALOGE("error changing vsync offset: %s (%d)", 570db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza strerror(-err), err); 571db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 572db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 573db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 574faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate: 575faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis virtual void onDispSyncEvent(nsecs_t when) { 576e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique VSyncSource::Callback* callback; 577faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis { 578db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex::Autolock lock(mCallbackMutex); 579faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback = mCallback; 580a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 5810a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis if (mTraceVsync) { 5820a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis mValue = (mValue + 1) % 2; 5835167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden ATRACE_INT(mVsyncEventLabel.string(), mValue); 5840a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis } 585faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 586faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 587566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (callback != nullptr) { 588faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis callback->onVSyncEvent(when); 589faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 590faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 591faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 5924a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray const char* const mName; 5934a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray 594faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis int mValue; 595faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 5960a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis const bool mTraceVsync; 5975167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncOnLabel; 5985167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden const String8 mVsyncEventLabel; 5990a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis 600faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis DispSync* mDispSync; 601db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 602db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mCallbackMutex; // Protects the following 603e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique VSyncSource::Callback* mCallback = nullptr; 604db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza 605db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza Mutex mVsyncMutex; // Protects the following 606db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza nsecs_t mPhaseOffset; 607db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza bool mEnabled; 608faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}; 609faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 610e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Piqueclass InjectVSyncSource final : public VSyncSource { 611c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjupublic: 612e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique InjectVSyncSource() = default; 613e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique ~InjectVSyncSource() override = default; 614c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 615e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique void setCallback(VSyncSource::Callback* callback) override { 616c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju std::lock_guard<std::mutex> lock(mCallbackMutex); 617c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mCallback = callback; 618c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 619c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 620e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique void onInjectSyncEvent(nsecs_t when) { 621c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju std::lock_guard<std::mutex> lock(mCallbackMutex); 62290f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu if (mCallback) { 62390f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu mCallback->onVSyncEvent(when); 62490f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu } 625c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 626c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 627e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique void setVSyncEnabled(bool) override {} 628e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique void setPhaseOffset(nsecs_t) override {} 629c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 630c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuprivate: 631c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju std::mutex mCallbackMutex; // Protects the following 632e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique VSyncSource::Callback* mCallback = nullptr; 633c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}; 634c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 635f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang// Do not call property_set on main thread which will be blocked by init 636f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang// Use StartPropertySetThread instead. 637faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() { 638a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian ALOGI( "SurfaceFlinger's main thread ready to run. " 639a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian "Initializing graphics H/W..."); 640a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 6412924d01304dba0b714c556b14e45e34f70472e96Thierry Strudel ALOGI("Phase offest NS: %" PRId64 "", vsyncPhaseOffsetNs); 6424b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park 643b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas Mutex::Autolock _l(mStateLock); 6449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 645b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // start the EventThread 6460fcde1b23edcb8105b944df70bf1113cac8f0c15Lloyd Pique mEventThreadSource = 6470fcde1b23edcb8105b944df70bf1113cac8f0c15Lloyd Pique std::make_unique<DispSyncSource>(&mPrimaryDispSync, SurfaceFlinger::vsyncPhaseOffsetNs, 6480fcde1b23edcb8105b944df70bf1113cac8f0c15Lloyd Pique true, "app"); 64924b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique mEventThread = std::make_unique<impl::EventThread>(mEventThreadSource.get(), 65024b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique [this]() { resyncWithRateLimit(); }, 65124b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique impl::EventThread::InterceptVSyncsCallback(), 6520fcde1b23edcb8105b944df70bf1113cac8f0c15Lloyd Pique "appEventThread"); 6530fcde1b23edcb8105b944df70bf1113cac8f0c15Lloyd Pique mSfEventThreadSource = 6540fcde1b23edcb8105b944df70bf1113cac8f0c15Lloyd Pique std::make_unique<DispSyncSource>(&mPrimaryDispSync, 6550fcde1b23edcb8105b944df70bf1113cac8f0c15Lloyd Pique SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf"); 6569123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique 65724b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique mSFEventThread = 65824b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique std::make_unique<impl::EventThread>(mSfEventThreadSource.get(), 65924b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique [this]() { resyncWithRateLimit(); }, 66024b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique [this](nsecs_t timestamp) { 66124b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique mInterceptor->saveVSyncEvent(timestamp); 66224b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique }, 66324b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique "sfEventThread"); 6649123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique mEventQueue->setEventThread(mSFEventThread.get()); 6652713c30843816d3511b39b85a2c268a2b7682047Dan Stoza mVsyncModulator.setEventThread(mSFEventThread.get()); 66641a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray 667b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // Get a RenderEngine for the given display / config (can't fail) 668144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique getBE().mRenderEngine = 669144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888, 670144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique hasWideColorDisplay 671144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique ? RE::RenderEngine::WIDE_COLOR_SUPPORT 672144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique : 0); 673bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine"); 674b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas 675b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay, 676b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas "Starting with vr flinger active is not currently supported."); 677a822d52f1a7f651bf1056f4b99e7b8dd214c2ebbLloyd Pique getBE().mHwc.reset( 678a822d52f1a7f651bf1056f4b99e7b8dd214c2ebbLloyd Pique new HWComposer(std::make_unique<Hwc2::impl::Composer>(getBE().mHwcServiceName))); 679105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId); 680ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique // Process any initial hotplug and resulting display changes. 681ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique processDisplayHotplugEventsLocked(); 682ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique LOG_ALWAYS_FATAL_IF(!getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY), 683ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique "Registered composer callback but didn't create the default primary display"); 684875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 685fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique // make the default display GLContext current so that we can create textures 686fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique // when creating Layers (which may happens before we render something) 687fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique getDefaultDisplayDeviceLocked()->makeCurrent(); 688fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique 689050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (useVrFlinger) { 690050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) { 691be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas // This callback is called from the vr flinger dispatch thread. We 692be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas // need to call signalTransaction(), which requires holding 693be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas // mStateLock when we're not on the main thread. Acquiring 694be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas // mStateLock from the vr flinger dispatch thread might trigger a 695be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas // deadlock in surface flinger (see b/66916578), so post a message 696be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas // to be handled on the main thread instead. 697be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas sp<LambdaMessage> message = new LambdaMessage([=]() { 698be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas ALOGI("VR request display mode: requestDisplay=%d", requestDisplay); 699be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas mVrFlingerRequestsDisplay = requestDisplay; 700be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas signalTransaction(); 701be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas }); 702be6cbae3b61a55ab87c131e79dba03d159961aa3Steven Thomas postMessageAsync(message); 703050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas }; 704105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman mVrFlinger = dvr::VrFlinger::Create(getBE().mHwc->getComposer(), 705105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman getBE().mHwc->getHwcDisplayId(HWC_DISPLAY_PRIMARY).value_or(0), 7066e8f706c21a01d6a1225e86972ff432bba5f0106Steven Thomas vrFlingerRequestDisplayCallback); 707050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (!mVrFlinger) { 708050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas ALOGE("Failed to start vrflinger"); 709050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } 710050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } 711050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 7120c3a88319136a8ce0e7050ef5695610a986ce900Lloyd Pique mEventControlThread = std::make_unique<impl::EventControlThread>( 7130c3a88319136a8ce0e7050ef5695610a986ce900Lloyd Pique [this](bool enabled) { setVsyncEnabled(HWC_DISPLAY_PRIMARY, enabled); }); 714d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 71592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian // initialize our drawing state 71692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian mDrawingState = mCurrentState; 7178630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 71813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden // set initial conditions (e.g. unblank default device) 71913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden initializeDisplays(); 72013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 721bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman getBE().mRenderEngine->primeCache(); 7224e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza 723f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang // Inform native graphics APIs whether the present timestamp is supported: 724f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang if (getHwComposer().hasCapability( 725f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang HWC2::Capability::PresentFenceIsNotReliable)) { 726f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang mStartPropertySetThread = new StartPropertySetThread(false); 727f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang } else { 728f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang mStartPropertySetThread = new StartPropertySetThread(true); 729f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang } 730f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang 731f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang if (mStartPropertySetThread->Start() != NO_ERROR) { 732f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang ALOGE("Run StartPropertySetThread failed!"); 733b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang } 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 735dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin mLegacySrgbSaturationMatrix = getBE().mHwc->getDataspaceSaturationMatrix(HWC_DISPLAY_PRIMARY, 736dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin Dataspace::SRGB_LINEAR); 737dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin 7389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Done initializing"); 7393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian} 7403ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian 74111d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guyvoid SurfaceFlinger::readPersistentProperties() { 74228f320b443106f1656f9720224f579136dcf0c61Chia-I Wu Mutex::Autolock _l(mStateLock); 74328f320b443106f1656f9720224f579136dcf0c61Chia-I Wu 74411d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy char value[PROPERTY_VALUE_MAX]; 74511d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy 74611d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy property_get("persist.sys.sf.color_saturation", value, "1.0"); 747dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin mGlobalSaturationFactor = atof(value); 74828f320b443106f1656f9720224f579136dcf0c61Chia-I Wu updateColorMatrixLocked(); 749dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin ALOGV("Saturation is set to %.2f", mGlobalSaturationFactor); 75054f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy 75154f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy property_get("persist.sys.sf.native_mode", value, "0"); 7520d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu mDisplayColorSetting = static_cast<DisplayColorSetting>(atoi(value)); 75311d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy} 75411d63f4b7d99cc09ff1f8c320bb7a8648ca07fa1Romain Guy 755a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() { 756b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang // Start boot animation service by setting a property mailbox 757b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang // if property setting thread is already running, Start() will be just a NOP 758f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang mStartPropertySetThread->Start(); 759b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang // Wait until property was set 760f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang if (mStartPropertySetThread->join() != NO_ERROR) { 761f9b05eeb5f3b3ea92ea196f37a53df06b535690cWei Wang ALOGE("Join StartPropertySetThread failed!"); 762b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang } 763a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian} 764a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian 765875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const { 766bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman return getBE().mRenderEngine->getMaxTextureSize(); 767a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 768a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 769875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const { 770bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman return getBE().mRenderEngine->getMaxViewportDims(); 771a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian} 772a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian 773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 774d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 775582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture( 7762adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden const sp<IGraphicBufferProducer>& bufferProducer) const { 777134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis Mutex::Autolock _l(mStateLock); 7780d48072f6047140119ff194c1194ce402fca2c0bRobert Carr return authenticateSurfaceTextureLocked(bufferProducer); 7790d48072f6047140119ff194c1194ce402fca2c0bRobert Carr} 7800d48072f6047140119ff194c1194ce402fca2c0bRobert Carr 7810d48072f6047140119ff194c1194ce402fca2c0bRobert Carrbool SurfaceFlinger::authenticateSurfaceTextureLocked( 7820d48072f6047140119ff194c1194ce402fca2c0bRobert Carr const sp<IGraphicBufferProducer>& bufferProducer) const { 783097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); 784101d8dc00001bd282f09a25f10058c77f982c11cDan Stoza return mGraphicBufferProducerList.count(surfaceTextureBinder.get()) > 0; 785134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis} 786134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis 7876b376713907086c9642e7b7e66e51ddfa531b003Brian Andersonstatus_t SurfaceFlinger::getSupportedFrameTimestamps( 7886b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson std::vector<FrameEvent>* outSupported) const { 7896b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson *outSupported = { 7906b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::REQUESTED_PRESENT, 7916b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::ACQUIRE, 7926b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::LATCH, 7936b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::FIRST_REFRESH_START, 7946b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::LAST_REFRESH_START, 7956b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::GPU_COMPOSITION_DONE, 7966b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::DEQUEUE_READY, 7976b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson FrameEvent::RELEASE, 7986b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson }; 7996d8110b1708171da278782d18886fa1a21971cd9Steven Thomas ConditionalLock _l(mStateLock, 8006d8110b1708171da278782d18886fa1a21971cd9Steven Thomas std::this_thread::get_id() != mMainThreadId); 8016b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson if (!getHwComposer().hasCapability( 8026b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson HWC2::Capability::PresentFenceIsNotReliable)) { 8036b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson outSupported->push_back(FrameEvent::DISPLAY_PRESENT); 8046b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson } 8056b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson return NO_ERROR; 8066b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson} 8076b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson 8087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, 8097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza Vector<DisplayInfo>* configs) { 810566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (configs == nullptr || display.get() == nullptr) { 8117f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return BAD_VALUE; 8127f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 8137f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 8147aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed if (!display.get()) 8157aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed return NAME_NOT_FOUND; 8167aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed 817692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall int32_t type = NAME_NOT_FOUND; 8189e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 819692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall if (display == mBuiltinDisplays[i]) { 8201604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian type = i; 8211604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian break; 8221604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 8231604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 8241604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 8251604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian if (type < 0) { 8261604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian return type; 827c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian } 8288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 8298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian // TODO: Not sure if display density should handled by SF any longer 8308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian class Density { 8318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getDensityFromProperty(char const* propName) { 8328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian char property[PROPERTY_VALUE_MAX]; 8338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian int density = 0; 834566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (property_get(propName, property, nullptr) > 0) { 8358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian density = atoi(property); 8368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 8378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return density; 8388b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 8398b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian public: 8408b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getEmuDensity() { 8418b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("qemu.sf.lcd_density"); } 8428b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian static int getBuildDensity() { 8438b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian return getDensityFromProperty("ro.sf.lcd_density"); } 8448b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian }; 8451604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian 8467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza configs->clear(); 8477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 8486d8110b1708171da278782d18886fa1a21971cd9Steven Thomas ConditionalLock _l(mStateLock, 8496d8110b1708171da278782d18886fa1a21971cd9Steven Thomas std::this_thread::get_id() != mMainThreadId); 8509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (const auto& hwConfig : getHwComposer().getConfigs(type)) { 8517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza DisplayInfo info = DisplayInfo(); 8527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 8539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float xdpi = hwConfig->getDpiX(); 8549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza float ydpi = hwConfig->getDpiY(); 8557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 8567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (type == DisplayDevice::DISPLAY_PRIMARY) { 8577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // The density of the device is provided by a build property 8587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza float density = Density::getBuildDensity() / 160.0f; 8597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (density == 0) { 8607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // the build doesn't provide a density -- this is wrong! 8617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // use xdpi instead 8627f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza ALOGE("ro.sf.lcd_density must be defined as a build property"); 8637f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density = xdpi / 160.0f; 8647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 8657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza if (Density::getEmuDensity()) { 8667f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // if "qemu.sf.lcd_density" is specified, it overrides everything 8677f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza xdpi = ydpi = density = Density::getEmuDensity(); 8687f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza density /= 160.0f; 8697f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } 8707f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = density; 8717f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 8727f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: this needs to go away (currently needed only by webkit) 8736d8110b1708171da278782d18886fa1a21971cd9Steven Thomas sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked()); 8742ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique info.orientation = hw ? hw->getOrientation() : 0; 8757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza } else { 8767f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // TODO: where should this value come from? 8777f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza static const int TV_DENSITY = 213; 8787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.density = TV_DENSITY / 160.0f; 8797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.orientation = 0; 8801604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian } 8817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 8829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.w = hwConfig->getWidth(); 8839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.h = hwConfig->getHeight(); 8847f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.xdpi = xdpi; 8857f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.ydpi = ydpi; 8869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.fps = 1e9 / hwConfig->getVsyncPeriod(); 8874b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park info.appVsyncOffset = vsyncPhaseOffsetNs; 8889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 88991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // This is how far in advance a buffer must be queued for 89091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // presentation at a given time. If you want a buffer to appear 89191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // on the screen at time N, you must submit the buffer before 89291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // (N - presentationDeadline). 89391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 89491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // Normally it's one full refresh period (to give SF a chance to 89591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // latch the buffer), but this can be reduced by configuring a 89691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // DispSync offset. Any additional delays introduced by the hardware 89791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // composer or panel must be accounted for here. 89891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // 89991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // We add an additional 1ms to allow for processing time and 90091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden // differences between the ideal and actual refresh rate. 9019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza info.presentationDeadline = hwConfig->getVsyncPeriod() - 9020cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard sfVsyncPhaseOffsetNs + 1000000; 9037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 9047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza // All non-virtual displays are currently considered secure. 9057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza info.secure = true; 9067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza 9077501ed66a05f530062925011d1342e8651216051Iris Chang if (type == DisplayDevice::DISPLAY_PRIMARY && 9087501ed66a05f530062925011d1342e8651216051Iris Chang mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) { 9097501ed66a05f530062925011d1342e8651216051Iris Chang std::swap(info.w, info.h); 9107501ed66a05f530062925011d1342e8651216051Iris Chang } 9117501ed66a05f530062925011d1342e8651216051Iris Chang 91228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright configs->push_back(info); 9138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian } 9148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian 9157f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza return NO_ERROR; 9167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 917dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 91889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */, 91967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar DisplayStatInfo* stats) { 920566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (stats == nullptr) { 92167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return BAD_VALUE; 92267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar } 92367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 92467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar // FIXME for now we always return stats for the primary display 92567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar memset(stats, 0, sizeof(*stats)); 92667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncTime = mPrimaryDispSync.computeNextRefresh(0); 92767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar stats->vsyncPeriod = mPrimaryDispSync.getPeriod(); 92867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar return NO_ERROR; 92967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar} 93067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar 9316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) { 932566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (display == nullptr) { 933566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin ALOGE("%s : display is nullptr", __func__); 9349f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong return BAD_VALUE; 9359f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong } 9367d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 9377d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<const DisplayDevice> device(getDisplayDevice(display)); 938566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (device != nullptr) { 93924a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return device->getActiveConfig(); 94024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza } 9417d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 94224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza return BAD_VALUE; 9437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza} 944dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis 9456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) { 9466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 9476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine this); 9486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int32_t type = hw->getDisplayType(); 9496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int currentMode = hw->getActiveConfig(); 9506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 9516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (mode == currentMode) { 9526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode); 9536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 9546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 9556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 9566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 9576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Trying to set config for virtual display"); 9586c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return; 9596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 9606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 9616c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine hw->setActiveConfig(mode); 9626c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine getHwComposer().setActiveConfig(type, mode); 9636c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine} 9646c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine 9656c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) { 9666c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine class MessageSetActiveConfig: public MessageBase { 9676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine SurfaceFlinger& mFlinger; 9686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<IBinder> mDisplay; 9696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mMode; 9706c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine public: 9716c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp, 9726c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine int mode) : 9736c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger(flinger), mDisplay(disp) { mMode = mode; } 9746c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine virtual bool handler() { 9757306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine Vector<DisplayInfo> configs; 9767306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mFlinger.getDisplayConfigs(mDisplay, &configs); 977784421160727c434c2a2897ed3345445fcc30f75Jesse Hall if (mMode < 0 || mMode >= static_cast<int>(configs.size())) { 9789ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine ALOGE("Attempt to set active config = %d for display with %zu configs", 9797306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, configs.size()); 98028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 9817306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine } 9826c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 983566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (hw == nullptr) { 9846c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGE("Attempt to set active config = %d for null display %p", 9857306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 9866c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 9876c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine ALOGW("Attempt to set active config = %d for virtual display", 9886c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mMode); 9896c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } else { 9906c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine mFlinger.setActiveConfigInternal(hw, mMode); 9916c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 9926c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine return true; 9936c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine } 9946c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine }; 9956c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode); 9966c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine postMessageSync(msg); 997888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian return NO_ERROR; 998c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian} 99928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display, 1000a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin Vector<ColorMode>* outColorModes) { 100128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if ((outColorModes == nullptr) || (display.get() == nullptr)) { 100228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return BAD_VALUE; 100328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 100428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 100528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (!display.get()) { 100628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NAME_NOT_FOUND; 100728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 100828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 100928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = NAME_NOT_FOUND; 101028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { 101128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (display == mBuiltinDisplays[i]) { 101228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright type = i; 101328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright break; 101428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 101528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 101628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 101728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (type < 0) { 101828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return type; 101928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 102028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 1021a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin std::vector<ColorMode> modes; 10226d8110b1708171da278782d18886fa1a21971cd9Steven Thomas { 10236d8110b1708171da278782d18886fa1a21971cd9Steven Thomas ConditionalLock _l(mStateLock, 10246d8110b1708171da278782d18886fa1a21971cd9Steven Thomas std::this_thread::get_id() != mMainThreadId); 10256d8110b1708171da278782d18886fa1a21971cd9Steven Thomas modes = getHwComposer().getColorModes(type); 10266d8110b1708171da278782d18886fa1a21971cd9Steven Thomas } 102728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright outColorModes->clear(); 102828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes)); 102928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 103028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 103128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 103228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 1033a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong LinColorMode SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) { 10347d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<const DisplayDevice> device(getDisplayDevice(display)); 103528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (device != nullptr) { 103628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return device->getActiveColorMode(); 103728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 1038a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin return static_cast<ColorMode>(BAD_VALUE); 103928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 104028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 104128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw, 1042d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin ColorMode mode, Dataspace dataSpace, 1043d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin RenderIntent renderIntent) { 104428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright int32_t type = hw->getDisplayType(); 1045a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin ColorMode currentMode = hw->getActiveColorMode(); 1046dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin Dataspace currentDataSpace = hw->getCompositionDataSpace(); 104738e9a56173c64a9640c6c390735a398d32752650Peiyong Lin RenderIntent currentRenderIntent = hw->getActiveRenderIntent(); 104828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 104938e9a56173c64a9640c6c390735a398d32752650Peiyong Lin if (mode == currentMode && dataSpace == currentDataSpace && 105038e9a56173c64a9640c6c390735a398d32752650Peiyong Lin renderIntent == currentRenderIntent) { 105138e9a56173c64a9640c6c390735a398d32752650Peiyong Lin return; 105238e9a56173c64a9640c6c390735a398d32752650Peiyong Lin } 105338e9a56173c64a9640c6c390735a398d32752650Peiyong Lin 105438e9a56173c64a9640c6c390735a398d32752650Peiyong Lin if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 105538e9a56173c64a9640c6c390735a398d32752650Peiyong Lin ALOGW("Trying to set config for virtual display"); 105638e9a56173c64a9640c6c390735a398d32752650Peiyong Lin return; 105738e9a56173c64a9640c6c390735a398d32752650Peiyong Lin } 105838e9a56173c64a9640c6c390735a398d32752650Peiyong Lin 105938e9a56173c64a9640c6c390735a398d32752650Peiyong Lin hw->setActiveColorMode(mode); 106038e9a56173c64a9640c6c390735a398d32752650Peiyong Lin hw->setCompositionDataSpace(dataSpace); 1061dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin hw->setActiveRenderIntent(renderIntent); 1062dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin getHwComposer().setActiveColorMode(type, mode, renderIntent); 1063dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin 1064dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin ALOGV("Set active color mode: %s (%d), active render intent: %s (%d), type=%d", 1065dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin decodeColorMode(mode).c_str(), mode, 1066dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin decodeRenderIntent(renderIntent).c_str(), renderIntent, 1067dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin hw->getDisplayType()); 106828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 106928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 107028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright 107128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display, 1072a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin ColorMode colorMode) { 107328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright class MessageSetActiveColorMode: public MessageBase { 107428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright SurfaceFlinger& mFlinger; 107528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<IBinder> mDisplay; 1076a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin ColorMode mMode; 107728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright public: 107828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp, 1079a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin ColorMode mode) : 108028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger(flinger), mDisplay(disp) { mMode = mode; } 108128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright virtual bool handler() { 1082a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin Vector<ColorMode> modes; 108328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright mFlinger.getDisplayColorModes(mDisplay, &modes); 108428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes); 1085a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin if (mMode < ColorMode::NATIVE || !exists) { 10865d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter ALOGE("Attempt to set invalid active color mode %s (%d) for display %p", 10875d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter decodeColorMode(mMode).c_str(), mMode, mDisplay.get()); 108828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 108928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 109028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 109128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright if (hw == nullptr) { 10925d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter ALOGE("Attempt to set active color mode %s (%d) for null display %p", 10935d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter decodeColorMode(mMode).c_str(), mMode, mDisplay.get()); 109428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 10955d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter ALOGW("Attempt to set active color mode %s %d for virtual display", 10965d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter decodeColorMode(mMode).c_str(), mMode); 109728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } else { 1098d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin mFlinger.setActiveColorModeInternal(hw, mMode, Dataspace::UNKNOWN, 1099d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin RenderIntent::COLORIMETRIC); 110028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 110128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return true; 110228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright } 110328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright }; 110428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode); 110528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright postMessageSync(msg); 110628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright return NO_ERROR; 110728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright} 1108c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian 1109d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() { 1110d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 1111d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 1112d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 1113d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 1114d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 1115d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { 1116d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav Mutex::Autolock _l(mStateLock); 1117d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.getStats(outStats); 1118d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 1119d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 1120d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 1121c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display, 1122c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza HdrCapabilities* outCapabilities) const { 1123c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza Mutex::Autolock _l(mStateLock); 1124c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 11257d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<const DisplayDevice> displayDevice(getDisplayDeviceLocked(display)); 1126c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza if (displayDevice == nullptr) { 1127c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get()); 1128c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return BAD_VALUE; 1129c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza } 1130c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 1131fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin // At this point the DisplayDeivce should already be set up, 1132fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin // meaning the luminance information is already queried from 1133fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin // hardware composer and stored properly. 1134fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin const HdrCapabilities& capabilities = displayDevice->getHdrCapabilities(); 1135fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin *outCapabilities = HdrCapabilities(capabilities.getSupportedHdrTypes(), 1136fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin capabilities.getDesiredMaxLuminance(), 1137fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin capabilities.getDesiredMaxAverageLuminance(), 1138fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin capabilities.getDesiredMinLuminance()); 1139c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 1140c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza return NO_ERROR; 1141c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza} 1142c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza 1143c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) { 114490f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu sp<LambdaMessage> enableVSyncInjections = new LambdaMessage([&]() { 114590f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu Mutex::Autolock _l(mStateLock); 1146c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 114790f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu if (mInjectVSyncs == enable) { 114890f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu return; 1149c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 115090f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu 115190f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu if (enable) { 115290f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu ALOGV("VSync Injections enabled"); 115390f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu if (mVSyncInjector.get() == nullptr) { 1154e83f93151800f4f7999f7e0c3b727de9267a5f5fLloyd Pique mVSyncInjector = std::make_unique<InjectVSyncSource>(); 115524b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique mInjectorEventThread = std::make_unique< 115624b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique impl::EventThread>(mVSyncInjector.get(), 115724b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique [this]() { resyncWithRateLimit(); }, 115824b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique impl::EventThread::InterceptVSyncsCallback(), 115924b0a485fb58afd16a42de6378c0b743d7aca58aLloyd Pique "injEventThread"); 116090f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu } 11619123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique mEventQueue->setEventThread(mInjectorEventThread.get()); 116290f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu } else { 116390f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu ALOGV("VSync Injections disabled"); 11649123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique mEventQueue->setEventThread(mSFEventThread.get()); 116590f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu } 116690f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu 1167c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mInjectVSyncs = enable; 116890f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu }); 116990f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu postMessageSync(enableVSyncInjections); 1170c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 1171c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju} 1172c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 1173c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) { 117490f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu Mutex::Autolock _l(mStateLock); 117590f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu 1176c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (!mInjectVSyncs) { 1177c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGE("VSync Injections not enabled"); 1178c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return BAD_VALUE; 1179c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 1180c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) { 1181c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju ALOGV("Injecting VSync inside SurfaceFlinger"); 1182c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju mVSyncInjector->onInjectSyncEvent(when); 1183c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju } 1184c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju return NO_ERROR; 1185c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju} 1186c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju 1187755e319d6a656dc92bd4f2b486d8f5a44b0e7350Lloyd Piquestatus_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const 1188755e319d6a656dc92bd4f2b486d8f5a44b0e7350Lloyd Pique NO_THREAD_SAFETY_ANALYSIS { 1189a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita IPCThreadState* ipc = IPCThreadState::self(); 1190a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita const int pid = ipc->getCallingPid(); 1191a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita const int uid = ipc->getCallingUid(); 1192a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita if ((uid != AID_SHELL) && 1193a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita !PermissionCache::checkPermission(sDump, pid, uid)) { 1194a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita ALOGE("Layer debug info permission denied for pid=%d, uid=%d", pid, uid); 1195a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita return PERMISSION_DENIED; 1196a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita } 1197a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita 1198a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita // Try to acquire a lock for 1s, fail gracefully 1199a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita const status_t err = mStateLock.timedLock(s2ns(1)); 1200a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita const bool locked = (err == NO_ERROR); 1201a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita if (!locked) { 1202a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita ALOGE("LayerDebugInfo: SurfaceFlinger unresponsive (%s [%d]) - exit", strerror(-err), err); 1203a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita return TIMED_OUT; 1204a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita } 1205a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita 1206a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita outLayers->clear(); 1207a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita mCurrentState.traverseInZOrder([&](Layer* layer) { 1208a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita outLayers->push_back(layer->getLayerDebugInfo()); 1209a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita }); 1210a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita 1211a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita mStateLock.unlock(); 1212a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita return NO_ERROR; 1213a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita} 1214a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita 1215d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------- 1216d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian 1217b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggisp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection( 1218b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi ISurfaceComposer::VsyncSource vsyncSource) { 1219b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi if (vsyncSource == eVsyncSourceSurfaceFlinger) { 1220b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi return mSFEventThread->createEventConnection(); 1221b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi } else { 1222b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi return mEventThread->createEventConnection(); 1223b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi } 1224bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian} 1225bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian 1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 122799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 122899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() { 12299123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique mEventQueue->waitMessage(); 123099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 123199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 123299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() { 12339123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique mEventQueue->invalidate(); 123499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 123599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 123699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() { 12379123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique mEventQueue->invalidate(); 123899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 123999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 124099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() { 12412b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza mRefreshPending = true; 12429123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique mEventQueue->refresh(); 124399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 124499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 124599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 1246c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 12479123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique return mEventQueue->postMessage(msg, reltime); 124899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 124999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 125099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 1251c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza nsecs_t reltime, uint32_t /* flags */) { 12529123ae5f9da83f1d0efd2260c5ecd84f66a11fb7Lloyd Pique status_t res = mEventQueue->postMessage(msg, reltime); 125399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian if (res == NO_ERROR) { 125499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian msg->wait(); 125599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian } 125699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian return res; 125799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 1258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12594f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() { 12604f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian do { 12614f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian waitForEvent(); 12624f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian } while (true); 126399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian} 1264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1265faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() { 1266faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1267948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { 1268faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 1269d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 1270d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 1271faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 127243601a2dc320a271ff8c3765ff61414a07221635Andy McFadden } 1273faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1274faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1275948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) { 1276faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1277faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1278948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeAvailable) { 1279948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = true; 1280948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } else if (!mHWVsyncAvailable) { 12810a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // Hardware vsync is not currently available, so abort the resync 12820a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza // attempt for now 1283948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall return; 1284948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 1285948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 1286105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 12879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 1288faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1289faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.reset(); 1290faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.setPeriod(period); 1291faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1292faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (!mPrimaryHWVsyncEnabled) { 1293faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.beginResync(); 1294d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true); 1295d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(true); 1296faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = true; 1297faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1298faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1299faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1300948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) { 1301faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1302faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis if (mPrimaryHWVsyncEnabled) { 1303d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false); 1304d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis mEventControlThread->setVsyncEnabled(false); 1305faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryDispSync.endResync(); 1306faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis mPrimaryHWVsyncEnabled = false; 1307faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1308948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall if (makeUnavailable) { 1309948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall mHWVsyncAvailable = false; 1310948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall } 1311faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis} 1312faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 13134a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() { 13144a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray static constexpr nsecs_t kIgnoreDelay = ms2ns(500); 131557164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza 131657164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza // No explicit locking is needed here since EventThread holds a lock while calling this method 131757164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza static nsecs_t sLastResyncAttempted = 0; 131857164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza const nsecs_t now = systemTime(); 131957164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza if (now - sLastResyncAttempted > kIgnoreDelay) { 13200a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza resyncToHardwareVsync(false); 13214a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray } 132257164302da664fc58c3fd3c1ed9980bc1c9bdf1fDan Stoza sLastResyncAttempted = now; 13234a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray} 13244a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray 1325b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomasvoid SurfaceFlinger::onVsyncReceived(int32_t sequenceId, 1326b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas hwc2_display_t displayId, int64_t timestamp) { 13273cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas Mutex::Autolock lock(mStateLock); 1328b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // Ignore any vsyncs from a previous hardware composer. 1329105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman if (sequenceId != getBE().mComposerSequenceId) { 1330b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas return; 1331b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas } 1332b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas 1333b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas int32_t type; 1334105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman if (!getBE().mHwc->onVsync(displayId, timestamp, &type)) { 13353cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas return; 13363cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas } 13373cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas 1338d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis bool needsHwVsync = false; 1339faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1340d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis { // Scope for the lock 1341d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis Mutex::Autolock _l(mHWVsyncLock); 1342b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas if (type == DisplayDevice::DISPLAY_PRIMARY && mPrimaryHWVsyncEnabled) { 1343d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); 1344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1345148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian } 1346d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis 1347d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis if (needsHwVsync) { 1348d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis enableHardwareVsync(); 1349d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } else { 1350d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis disableHardwareVsync(false); 1351d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis } 1352148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian} 1353148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian 13540a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) { 135599974d2935a520141d77983ac0329350460f2379David Sodman std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock); 135699974d2935a520141d77983ac0329350460f2379David Sodman *compositorTiming = getBE().mCompositorTiming; 13570a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson} 13580a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 1359715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Piquevoid SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hwc2_display_t display, 1360715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique HWC2::Connection connection) { 1361715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique ALOGV("onHotplugReceived(%d, %" PRIu64 ", %s)", sequenceId, display, 1362715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique connection == HWC2::Connection::Connected ? "connected" : "disconnected"); 1363b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas 1364ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique // Ignore events that do not have the right sequenceId. 1365ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique if (sequenceId != getBE().mComposerSequenceId) { 1366ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique return; 1367ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique } 1368ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique 1369b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // Only lock if we're not on the main thread. This function is normally 1370b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // called on a hwbinder thread, but for the primary display it's called on 1371b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // the main thread with the state lock already held, so don't attempt to 1372b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // acquire it here. 1373ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId); 1374b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas 1375715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique mPendingHotplugEvents.emplace_back(HotplugEvent{display, connection}); 13769e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian 1377ccfd682b5280fe638d4e0b4c7841c98aab298788Jiwen 'Steve' Cai if (std::this_thread::get_id() == mMainThreadId) { 1378ccfd682b5280fe638d4e0b4c7841c98aab298788Jiwen 'Steve' Cai // Process all pending hot plug events immediately if we are on the main thread. 1379ccfd682b5280fe638d4e0b4c7841c98aab298788Jiwen 'Steve' Cai processDisplayHotplugEventsLocked(); 1380ccfd682b5280fe638d4e0b4c7841c98aab298788Jiwen 'Steve' Cai } 1381ccfd682b5280fe638d4e0b4c7841c98aab298788Jiwen 'Steve' Cai 1382ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique setTransactionFlags(eDisplayTransactionNeeded); 13838630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 13848630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 1385b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomasvoid SurfaceFlinger::onRefreshReceived(int sequenceId, 1386b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas hwc2_display_t /*display*/) { 13873cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas Mutex::Autolock lock(mStateLock); 1388105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman if (sequenceId != getBE().mComposerSequenceId) { 1389b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas return; 13903cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas } 1391c7a25adf66b138de66814383540905b83cf12a01Dan Stoza repaintEverything(); 13923cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas} 13933cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas 13949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) { 1395faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis ATRACE_CALL(); 1396b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas Mutex::Autolock lock(mStateLock); 13979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza getHwComposer().setVsyncEnabled(disp, 13989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable); 13998630320433bd15aca239522e54e711ef6372ab07Mathias Agopian} 14008630320433bd15aca239522e54e711ef6372ab07Mathias Agopian 14017d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk// Note: it is assumed the caller holds |mStateLock| when this is called 1402b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomasvoid SurfaceFlinger::resetDisplayState() { 140387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar disableHardwareVsync(true); 140487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar // Clear the drawing state so that the logic inside of 140587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar // handleTransactionLocked will fire. It will determine the delta between 140687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar // mCurrentState and mDrawingState and re-apply all changes when we make the 140787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar // transition. 140887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar mDrawingState.displays.clear(); 14097f40290b223afe1fea1d173da43e8e3d6ae49590Chia-I Wu getRenderEngine().resetCurrentSurface(); 141087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar mDisplays.clear(); 141187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar} 141287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 1413050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid SurfaceFlinger::updateVrFlinger() { 1414050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (!mVrFlinger) 1415050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas return; 1416050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay; 1417105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman if (vrFlingerRequestsDisplay == getBE().mHwc->isUsingVrComposer()) { 1418209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus return; 1419209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus } 14207d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 1421105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman if (vrFlingerRequestsDisplay && !getBE().mHwc->getComposer()->isRemote()) { 1422b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas ALOGE("Vr flinger is only supported for remote hardware composer" 1423b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas " service connections. Ignoring request to transition to vr" 1424b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas " flinger."); 1425b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas mVrFlingerRequestsDisplay = false; 1426b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas return; 1427209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus } 142887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 14297d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk Mutex::Autolock _l(mStateLock); 143087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 1431b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas int currentDisplayPowerMode = getDisplayDeviceLocked( 1432b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY])->getPowerMode(); 143387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 1434b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas if (!vrFlingerRequestsDisplay) { 14357d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk mVrFlinger->SeizeDisplayOwnership(); 1436b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas } 143787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 1438b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas resetDisplayState(); 1439105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman getBE().mHwc.reset(); // Delete the current instance before creating the new one 1440a822d52f1a7f651bf1056f4b99e7b8dd214c2ebbLloyd Pique getBE().mHwc.reset(new HWComposer(std::make_unique<Hwc2::impl::Composer>( 1441a822d52f1a7f651bf1056f4b99e7b8dd214c2ebbLloyd Pique vrFlingerRequestsDisplay ? "vr" : getBE().mHwcServiceName))); 1442105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman getBE().mHwc->registerCallback(this, ++getBE().mComposerSequenceId); 14437d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 1444105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman LOG_ALWAYS_FATAL_IF(!getBE().mHwc->getComposer()->isRemote(), 1445105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman "Switched to non-remote hardware composer"); 1446b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas 1447b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas if (vrFlingerRequestsDisplay) { 1448b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas mVrFlinger->GrantDisplayOwnership(); 1449b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas } else { 14507d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk enableHardwareVsync(); 145187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar } 14527d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 14537d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk mVisibleRegionsDirty = true; 14547d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk invalidateHwcGeometry(); 14557d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 1456096cb99ad877594121d0112ba52dc343d1d34d9bAlex Sakhartchouk // Re-enable default display. 1457b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas sp<DisplayDevice> hw(getDisplayDeviceLocked( 1458b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY])); 1459b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas setPowerModeInternal(hw, currentDisplayPowerMode, /*stateLockHeld*/ true); 1460096cb99ad877594121d0112ba52dc343d1d34d9bAlex Sakhartchouk 1461b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // Reset the timing values to account for the period of the swapped in HWC 1462105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 1463b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas const nsecs_t period = activeConfig->getVsyncPeriod(); 1464b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas mAnimFrameTracker.setDisplayRefreshPeriod(period); 1465096cb99ad877594121d0112ba52dc343d1d34d9bAlex Sakhartchouk 1466b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // Use phase of 0 since phase is not known. 1467b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas // Use latency of 0, which will snap to the ideal latency. 1468b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas setCompositorTimingSnapped(0, period, 0); 146982386cd4eb194a9bf4b8688cb02317909ba346e0Stephen Kiazyk 14707d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk android_atomic_or(1, &mRepaintEverything); 14717d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk setTransactionFlags(eDisplayTransactionNeeded); 147287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar} 147387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar 14744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) { 14751c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 147699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian switch (what) { 14776b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::INVALIDATE: { 14785018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza bool frameMissed = !mHadClientComposition && 14795018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza mPreviousPresentFence != Fence::NO_FENCE && 14800a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson (mPreviousPresentFence->getSignalTime() == 14810a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson Fence::SIGNAL_TIME_PENDING); 14825018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza ATRACE_INT("FrameMissed", static_cast<int>(frameMissed)); 14830102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang if (frameMissed) { 1484621f9d47638c7a147c6513801eaeb0ed0fdcad30Yiwei Zhang mTimeStats.incrementMissedFrames(); 1485621f9d47638c7a147c6513801eaeb0ed0fdcad30Yiwei Zhang if (mPropagateBackpressure) { 1486621f9d47638c7a147c6513801eaeb0ed0fdcad30Yiwei Zhang signalLayerUpdate(); 1487621f9d47638c7a147c6513801eaeb0ed0fdcad30Yiwei Zhang break; 1488621f9d47638c7a147c6513801eaeb0ed0fdcad30Yiwei Zhang } 14890102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang } 14905018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza 1491050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Now that we're going to make it to the handleMessageTransaction() 1492050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // call below it's safe to call updateVrFlinger(), which will 1493050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // potentially trigger a display handoff. 1494050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas updateVrFlinger(); 1495050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 14966b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool refreshNeeded = handleMessageTransaction(); 14976b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza refreshNeeded |= handleMessageInvalidate(); 14985878444fb8da043021f30d3de739531f15390df5Dan Stoza refreshNeeded |= mRepaintEverything; 14996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (refreshNeeded) { 15005878444fb8da043021f30d3de739531f15390df5Dan Stoza // Signal a refresh if a transaction modified the window state, 15015878444fb8da043021f30d3de739531f15390df5Dan Stoza // a new buffer was latched, or if HWC has requested a full 15025878444fb8da043021f30d3de739531f15390df5Dan Stoza // repaint 15036b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalRefresh(); 15046b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 15056b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 15066b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 15076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza case MessageQueue::REFRESH: { 15086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza handleMessageRefresh(); 15096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza break; 15106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 15114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 15124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15146b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() { 1515c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglard uint32_t transactionFlags = peekTransactionFlags(); 15164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian if (transactionFlags) { 151787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransaction(transactionFlags); 15186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return true; 15194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 15206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return false; 15214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 1522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 15236b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() { 1524cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 15256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza return handlePageFlip(); 15264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 15273a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian 15284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() { 1529cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 153014cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 15312b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza mRefreshPending = false; 15322b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza 153340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC); 153405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 1535d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson preComposition(refreshStartTime); 153605dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza rebuildLayerStacks(); 153705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza setUpHWComposer(); 153805dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doDebugFlashRegions(); 15391e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos doTracing("handleRefresh"); 1540068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang logLayerStats(); 154105dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza doComposition(); 15420a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson postComposition(refreshStartTime); 154305dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza 1544105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman mPreviousPresentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY); 1545bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza 1546bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = false; 1547bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 1548bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza const sp<DisplayDevice>& displayDevice = mDisplays[displayId]; 1549bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza mHadClientComposition = mHadClientComposition || 1550105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); 1551bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza } 15529053521815dc4cbe3d2ab21096e05d33386dd5daJorim Jaggi mVsyncModulator.onRefreshed(mHadClientComposition); 155314cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza 15549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mLayersWithQueuedFrames.clear(); 1555cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1556cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1557cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions() 1558cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 1559cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // is debugging enabled 1560cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (CC_LIKELY(!mDebugRegion)) 1561cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian return; 1562cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1563cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const bool repaintEverything = mRepaintEverything; 1564cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1565cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 15662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 1567cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 1568cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 1569cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (!dirtyRegion.isEmpty()) { 1570cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // redraw the whole screen 1571b02087dbd6a25e9d077fde16039050da8012b413Chia-I Wu doComposeSurfaces(hw); 1572cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1573cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // and draw the dirty region 1574cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const int32_t height = hw->getHeight(); 1575144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique auto& engine(getRenderEngine()); 15763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); 15773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1578da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian hw->swapBuffers(getHwComposer()); 1579cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1580cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1581cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1582cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1583cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian postFramebuffer(); 1584cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1585cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (mDebugRegion > 1) { 1586cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian usleep(mDebugRegion * 1000); 1587cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1588bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian 15899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 15907bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza auto& displayDevice = mDisplays[displayId]; 15917bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 15927bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 15937bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 15947bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza 1595105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman status_t result = displayDevice->prepareFrame(*getBE().mHwc); 1596105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman ALOGE_IF(result != NO_ERROR, 1597105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman "prepareFrame for display %zd failed:" 1598105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman " %d (%s)", 1599105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman displayId, result, strerror(-result)); 1600bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian } 1601cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1602cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 16031e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roosvoid SurfaceFlinger::doTracing(const char* where) { 16041e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos ATRACE_CALL(); 16051e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos ATRACE_NAME(where); 16061e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos if (CC_UNLIKELY(mTracing.isEnabled())) { 16078e0af3679ec73e07775142825d592448b255f61cJorim Jaggi mTracing.traceLayers(where, dumpProtoInfo(LayerVector::StateSet::Drawing)); 16081e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos } 16091e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos} 16101e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos 1611068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhangvoid SurfaceFlinger::logLayerStats() { 1612068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang ATRACE_CALL(); 1613068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang if (CC_UNLIKELY(mLayerStats.isEnabled())) { 1614068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang int32_t hwcId = -1; 1615068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang for (size_t dpy = 0; dpy < mDisplays.size(); ++dpy) { 1616068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang const sp<const DisplayDevice>& displayDevice(mDisplays[dpy]); 1617068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang if (displayDevice->isPrimary()) { 1618068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang hwcId = displayDevice->getHwcDisplayId(); 1619068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang break; 1620068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang } 1621068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang } 1622068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang if (hwcId < 0) { 1623068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang ALOGE("LayerStats: Hmmm, no primary display?"); 1624068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang return; 1625068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang } 1626068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang mLayerStats.logLayerStats(dumpVisibleLayersProtoInfo(hwcId)); 1627068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang } 1628068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang} 1629068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang 1630d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::preComposition(nsecs_t refreshStartTime) 1631cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 16329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 16339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("preComposition"); 16349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1635cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian bool needExtraInvalidate = false; 16362047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 16372047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr if (layer->onPreComposition(refreshStartTime)) { 1638cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian needExtraInvalidate = true; 1639cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 16402047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 16412047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr 1642cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian if (needExtraInvalidate) { 1643cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian signalLayerUpdate(); 1644cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 1645cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1646a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 16470a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::updateCompositorTiming( 16480a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime, 16490a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson std::shared_ptr<FenceTime>& presentFenceTime) { 16500a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Update queue of past composite+present times and determine the 16510a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // most recently known composite to present latency. 165299974d2935a520141d77983ac0329350460f2379David Sodman getBE().mCompositePresentTimes.push({compositeTime, presentFenceTime}); 16530a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t compositeToPresentLatency = -1; 165499974d2935a520141d77983ac0329350460f2379David Sodman while (!getBE().mCompositePresentTimes.empty()) { 165599974d2935a520141d77983ac0329350460f2379David Sodman SurfaceFlingerBE::CompositePresentTime& cpt = getBE().mCompositePresentTimes.front(); 16560a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Cached values should have been updated before calling this method, 16570a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // which helps avoid duplicate syscalls. 16580a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t displayTime = cpt.display->getCachedSignalTime(); 16590a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson if (displayTime == Fence::SIGNAL_TIME_PENDING) { 16600a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson break; 16610a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson } 16620a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson compositeToPresentLatency = displayTime - cpt.composite; 166399974d2935a520141d77983ac0329350460f2379David Sodman getBE().mCompositePresentTimes.pop(); 16640a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson } 16650a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 16660a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Don't let mCompositePresentTimes grow unbounded, just in case. 166799974d2935a520141d77983ac0329350460f2379David Sodman while (getBE().mCompositePresentTimes.size() > 16) { 166899974d2935a520141d77983ac0329350460f2379David Sodman getBE().mCompositePresentTimes.pop(); 16690a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson } 16700a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 1671d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson setCompositorTimingSnapped( 1672d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson vsyncPhase, vsyncInterval, compositeToPresentLatency); 1673d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson} 1674d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson 1675d001058145c2186f454a3fb043388d6d9b84c9d8Brian Andersonvoid SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase, 1676d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) { 16770a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Integer division and modulo round toward 0 not -inf, so we need to 16780a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // treat negative and positive offsets differently. 1679d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ? 16800a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) : 16810a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson ((-sfVsyncPhaseOffsetNs) % vsyncInterval); 16820a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 1683d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval. 1684d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson if (idealLatency <= 0) { 1685d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson idealLatency = vsyncInterval; 1686d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson } 1687d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson 16880a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Snap the latency to a value that removes scheduling jitter from the 16890a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // composition and present times, which often have >1ms of jitter. 16900a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Reducing jitter is important if an app attempts to extrapolate 16910a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // something (such as user input) to an accurate diasplay time. 16920a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs 16930a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // with (presentLatency % interval). 1694d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson nsecs_t bias = vsyncInterval / 2; 1695d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson int64_t extraVsyncs = 1696d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; 1697d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ? 1698d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson idealLatency + (extraVsyncs * vsyncInterval) : idealLatency; 16990a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 170099974d2935a520141d77983ac0329350460f2379David Sodman std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock); 170199974d2935a520141d77983ac0329350460f2379David Sodman getBE().mCompositorTiming.deadline = vsyncPhase - idealLatency; 170299974d2935a520141d77983ac0329350460f2379David Sodman getBE().mCompositorTiming.interval = vsyncInterval; 170399974d2935a520141d77983ac0329350460f2379David Sodman getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency; 17040a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson} 17050a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 17060a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime) 1707cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{ 17089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 17099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postComposition"); 17109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 17113546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson // Release any buffers which were replaced this frame 1712f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson nsecs_t dequeueReadyTime = systemTime(); 17133546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson for (auto& layer : mLayersWithQueuedFrames) { 1714f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson layer->releasePendingBuffer(dequeueReadyTime); 17153546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson } 17163546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson 17177d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // |mStateLock| not needed as we are on the main thread 17187d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk const sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked()); 17193d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 172073bededbdc82a5b6199f0860c8900e75c6f0e467David Sodman getBE().mGlCompositionDoneTimeline.updateSignalTimes(); 17213d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson std::shared_ptr<FenceTime> glCompositionDoneFenceTime; 17222ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (hw && getBE().mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) { 17233d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson glCompositionDoneFenceTime = 17243d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson std::make_shared<FenceTime>(hw->getClientTargetAcquireFence()); 172573bededbdc82a5b6199f0860c8900e75c6f0e467David Sodman getBE().mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime); 17263d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson } else { 17273d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson glCompositionDoneFenceTime = FenceTime::NO_FENCE; 17283d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson } 17293d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 173073bededbdc82a5b6199f0860c8900e75c6f0e467David Sodman getBE().mDisplayTimeline.updateSignalTimes(); 1731105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman sp<Fence> presentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY); 17324e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson auto presentFenceTime = std::make_shared<FenceTime>(presentFence); 173373bededbdc82a5b6199f0860c8900e75c6f0e467David Sodman getBE().mDisplayTimeline.push(presentFenceTime); 17343d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 17350a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0); 17360a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod(); 17370a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 17380a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // We use the refreshStartTime which might be sampled a little later than 17390a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // when we started doing work for this frame, but that should be okay 17400a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson // since updateCompositorTiming has snapping logic. 17410a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson updateCompositorTiming( 17424e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime); 1743d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson CompositorTiming compositorTiming; 1744d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson { 174599974d2935a520141d77983ac0329350460f2379David Sodman std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock); 174699974d2935a520141d77983ac0329350460f2379David Sodman compositorTiming = getBE().mCompositorTiming; 1747d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson } 17480a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 17492047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 17502047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime, 17514e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson presentFenceTime, compositorTiming); 1752e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (frameLatched) { 17532047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr recordBufferingStats(layer->getName().string(), 17542047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr layer->getOccupancyHistory(false)); 1755e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 17562047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 17574b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 1758fbc80aef0ba1b11982cf4ca88d218b65b6eca0f3Brian Anderson if (presentFenceTime->isValid()) { 1759fbc80aef0ba1b11982cf4ca88d218b65b6eca0f3Brian Anderson if (mPrimaryDispSync.addPresentFence(presentFenceTime)) { 1760faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1761faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } else { 1762948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(false); 1763faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1764faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1765faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 1766cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard if (!hasSyncFramework) { 17672ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY) && hw->isDisplayOn()) { 1768faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis enableHardwareVsync(); 1769faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1770faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis } 1771faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis 17724b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (mAnimCompositionPending) { 17734b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = false; 17744b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 17754e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson if (presentFenceTime->isValid()) { 17763d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mAnimFrameTracker.setActualPresentFence( 17774e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson std::move(presentFenceTime)); 17782ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique } else if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY)) { 17794b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // The HWC doesn't support present fences, so use the refresh 17804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // timestamp instead. 17819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza nsecs_t presentTime = 1782105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman getBE().mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 17834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.setActualPresentTime(presentTime); 17844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 17854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimFrameTracker.advanceFrame(); 17864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 1787b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 17880102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang mTimeStats.incrementTotalFrames(); 17890102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang if (mHadClientComposition) { 17900102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang mTimeStats.incrementClientCompositionFrames(); 17910102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang } 17920102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang 17932ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY) && 17942ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique hw->getPowerMode() == HWC_POWER_MODE_OFF) { 1795b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza return; 1796b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 1797b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 1798b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza nsecs_t currentTime = systemTime(); 1799b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if (mHasPoweredOff) { 1800b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = false; 1801b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 18024a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman nsecs_t elapsedTime = currentTime - getBE().mLastSwapTime; 18030a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson size_t numPeriods = static_cast<size_t>(elapsedTime / vsyncInterval); 18044a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman if (numPeriods < SurfaceFlingerBE::NUM_BUCKETS - 1) { 18054a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman getBE().mFrameBuckets[numPeriods] += elapsedTime; 1806b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } else { 18074a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1] += elapsedTime; 1808b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 18094a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman getBE().mTotalTime += elapsedTime; 1810b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 18114a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman getBE().mLastSwapTime = currentTime; 1812cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 1813cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian 1814cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() { 18159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 18169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("rebuildLayerStacks"); 18179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1818cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // rebuild the visible layer list per screen 1819764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey if (CC_UNLIKELY(mVisibleRegionsDirty)) { 1820fc2589e27981836d36b97ff19e85c84d8f50f915Siarhei Vishniakou ATRACE_NAME("rebuildLayerStacks VR Dirty"); 1821764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey mVisibleRegionsDirty = false; 1822764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey invalidateHwcGeometry(); 1823ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian 1824764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1825764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey Region opaqueRegion; 1826764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey Region dirtyRegion; 1827764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey Vector<sp<Layer>> layersSortedByZ; 182883806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu Vector<sp<Layer>> layersNeedingFences; 1829764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey const sp<DisplayDevice>& displayDevice(mDisplays[dpy]); 1830764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey const Transform& tr(displayDevice->getTransform()); 1831764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey const Rect bounds(displayDevice->getBounds()); 1832764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey if (displayDevice->isDisplayOn()) { 1833ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu computeVisibleRegions(displayDevice, dirtyRegion, opaqueRegion); 1834764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey 1835764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey mDrawingState.traverseInZOrder([&](Layer* layer) { 183683806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu bool hwcLayerDestroyed = false; 1837ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu if (layer->belongsToDisplay(displayDevice->getLayerStack(), 1838ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu displayDevice->isPrimary())) { 1839764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey Region drawRegion(tr.transform( 1840764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey layer->visibleNonTransparentRegion)); 1841764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey drawRegion.andSelf(bounds); 1842764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey if (!drawRegion.isEmpty()) { 1843764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey layersSortedByZ.add(layer); 1844764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey } else { 1845764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey // Clear out the HWC layer if this layer was 1846764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey // previously visible, but no longer is 184783806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu hwcLayerDestroyed = layer->destroyHwcLayer( 1848b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas displayDevice->getHwcDisplayId()); 1849764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey } 185006a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard } else { 18518226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard // WM changes displayDevice->layerStack upon sleep/awake. 18528226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard // Here we make sure we delete the HWC layers even if 18538226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard // WM changed their layer stack. 185483806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu hwcLayerDestroyed = layer->destroyHwcLayer( 185583806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu displayDevice->getHwcDisplayId()); 185683806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu } 185783806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu 185883806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu // If a layer is not going to get a release fence because 185983806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu // it is invisible, but it is also going to release its 186083806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu // old buffer, add it to the list of layers needing 186183806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu // fences. 186283806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu if (hwcLayerDestroyed) { 186383806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu auto found = std::find(mLayersWithQueuedFrames.cbegin(), 186483806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu mLayersWithQueuedFrames.cend(), layer); 186583806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu if (found != mLayersWithQueuedFrames.cend()) { 186683806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu layersNeedingFences.add(layer); 186783806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu } 186887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 1869764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey }); 1870764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey } 1871764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey displayDevice->setVisibleLayersSortedByZ(layersSortedByZ); 187283806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu displayDevice->setLayersNeedingFences(layersNeedingFences); 1873764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey displayDevice->undefinedRegion.set(bounds); 1874764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey displayDevice->undefinedRegion.subtractSelf( 1875764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey tr.transform(opaqueRegion)); 1876764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey displayDevice->dirtyRegion.orSelf(dirtyRegion); 18773b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 18783b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian } 1879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 18803b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian 1881d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin// Returns a data space that fits all visible layers. The returned data space 1882dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin// can only be one of 18837a28ecb9bdbc1697bdf08804e47a512291e0b878Chia-I Wu// - Dataspace::SRGB (use legacy dataspace and let HWC saturate when colors are enhanced) 1884dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin// - Dataspace::DISPLAY_P3 1885d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin// The returned HDR data space is one of 1886d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin// - Dataspace::UNKNOWN 1887d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin// - Dataspace::BT2020_HLG 1888d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin// - Dataspace::BT2020_PQ 1889d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong LinDataspace SurfaceFlinger::getBestDataspace( 1890d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin const sp<const DisplayDevice>& displayDevice, Dataspace* outHdrDataSpace) const { 1891d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin Dataspace bestDataSpace = Dataspace::SRGB; 1892d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin *outHdrDataSpace = Dataspace::UNKNOWN; 1893d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin 1894dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin for (const auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 18951b6bafca6e5c4a71bc97f14be30e64541633bda7Chia-I Wu switch (layer->getDataSpace()) { 1896dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin case Dataspace::V0_SCRGB: 1897dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin case Dataspace::V0_SCRGB_LINEAR: 1898f59a719fe91b201ea0ef9447ae436457aa29a6d6Peiyong Lin case Dataspace::DISPLAY_P3: 18990607fbe8956a64151b165ac88ef9f3cf9b4ece5dChia-I Wu bestDataSpace = Dataspace::DISPLAY_P3; 1900f59a719fe91b201ea0ef9447ae436457aa29a6d6Peiyong Lin break; 1901dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin case Dataspace::BT2020_PQ: 1902dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin case Dataspace::BT2020_ITU_PQ: 1903d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin *outHdrDataSpace = Dataspace::BT2020_PQ; 1904dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin break; 1905f59a719fe91b201ea0ef9447ae436457aa29a6d6Peiyong Lin case Dataspace::BT2020_HLG: 1906f59a719fe91b201ea0ef9447ae436457aa29a6d6Peiyong Lin case Dataspace::BT2020_ITU_HLG: 1907d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin // When there's mixed PQ content and HLG content, we set the HDR 1908d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin // data space to be BT2020_PQ and convert HLG to PQ. 1909d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin if (*outHdrDataSpace == Dataspace::UNKNOWN) { 1910d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin *outHdrDataSpace = Dataspace::BT2020_HLG; 1911f59a719fe91b201ea0ef9447ae436457aa29a6d6Peiyong Lin } 1912dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin break; 1913dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin default: 1914dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin break; 1915dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin } 191654f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy } 191754f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy 1918d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin return bestDataSpace; 1919dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin} 19205d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 1921dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin// Pick the ColorMode / Dataspace for the display device. 1922dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Linvoid SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& displayDevice, 1923d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin ColorMode* outMode, Dataspace* outDataSpace, 1924d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin RenderIntent* outRenderIntent) const { 1925dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin if (mDisplayColorSetting == DisplayColorSetting::UNMANAGED) { 1926dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin *outMode = ColorMode::NATIVE; 1927dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin *outDataSpace = Dataspace::UNKNOWN; 1928d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin *outRenderIntent = RenderIntent::COLORIMETRIC; 1929dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin return; 1930dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin } 1931dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin 1932d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin Dataspace hdrDataSpace; 1933d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin Dataspace bestDataSpace = getBestDataspace(displayDevice, &hdrDataSpace); 1934d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin 19353c6b7efc5204eab5701d5ab2f0ff87763cc322faPeiyong Lin // respect hdrDataSpace only when there is no legacy HDR support 1936c4b08bde2aaa455a7f789eb2858863d19563b949Chia-I Wu const bool isHdr = hdrDataSpace != Dataspace::UNKNOWN && 19373c6b7efc5204eab5701d5ab2f0ff87763cc322faPeiyong Lin !displayDevice->hasLegacyHdrSupport(hdrDataSpace); 1938c4b08bde2aaa455a7f789eb2858863d19563b949Chia-I Wu if (isHdr) { 1939c4b08bde2aaa455a7f789eb2858863d19563b949Chia-I Wu bestDataSpace = hdrDataSpace; 1940c4b08bde2aaa455a7f789eb2858863d19563b949Chia-I Wu } 1941c4b08bde2aaa455a7f789eb2858863d19563b949Chia-I Wu 19420d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu RenderIntent intent; 19430d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu switch (mDisplayColorSetting) { 19440d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu case DisplayColorSetting::MANAGED: 19450d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu case DisplayColorSetting::UNMANAGED: 1946c4b08bde2aaa455a7f789eb2858863d19563b949Chia-I Wu intent = isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC; 19470d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu break; 19480d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu case DisplayColorSetting::ENHANCED: 1949c4b08bde2aaa455a7f789eb2858863d19563b949Chia-I Wu intent = isHdr ? RenderIntent::TONE_MAP_ENHANCE : RenderIntent::ENHANCE; 19500d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu break; 19510d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu default: // vendor display color setting 19520d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu intent = static_cast<RenderIntent>(mDisplayColorSetting); 19530d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu break; 19540d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu } 1955d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin 19560607fbe8956a64151b165ac88ef9f3cf9b4ece5dChia-I Wu displayDevice->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent); 19575d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter} 19585d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 1959cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() { 19609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ATRACE_CALL(); 19619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("setUpHWComposer"); 19629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1963028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1964c7a25adf66b138de66814383540905b83cf12a01Dan Stoza bool dirty = !mDisplays[dpy]->getDirtyRegion(mRepaintEverything).isEmpty(); 1965b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0; 1966b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers; 1967b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1968b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If nothing has changed (!dirty), don't recompose. 1969b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // If something changed, but we don't currently have any visible layers, 1970b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // and didn't when we last did a composition, then skip it this time. 1971b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // The second rule does two things: 1972b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When all layers are removed from a display, we'll emit one black 1973b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // frame, then nothing more until we get new layers. 1974b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // - When a display is created with a private layer stack, we won't 1975b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall // emit any black frames until a layer is added to the layer stack. 1976b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall bool mustRecompose = dirty && !(empty && wasEmpty); 1977b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1978b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL, 1979b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy, 1980b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mustRecompose ? "doing" : "skipping", 1981b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall dirty ? "+" : "-", 1982b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall empty ? "+" : "-", 1983b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall wasEmpty ? "+" : "-"); 1984b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 19857143316af216fa92c31a60d4407b707637382da1Dan Stoza mDisplays[dpy]->beginFrame(mustRecompose); 1986b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall 1987b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall if (mustRecompose) { 1988b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty; 1989b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall } 1990028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall } 1991028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall 19929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // build the h/w work list 19939e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (CC_UNLIKELY(mGeometryInvalid)) { 19949e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = false; 19959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 19969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza sp<const DisplayDevice> displayDevice(mDisplays[dpy]); 19979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 19989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 19999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Vector<sp<Layer>>& currentLayers( 20009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getVisibleLayersSortedByZ()); 2001ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr for (size_t i = 0; i < currentLayers.size(); i++) { 20021f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const auto& layer = currentLayers[i]; 20039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (!layer->hasHwcLayer(hwcId)) { 2004105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman if (!layer->createHwcLayer(getBE().mHwc.get(), hwcId)) { 20059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 20069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 2007a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 2008a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis } 2009a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis 2010ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr layer->setGeometry(displayDevice, i); 20119f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza if (mDebugDisableHWC || mDebugRegion) { 20129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->forceClientComposition(hwcId); 201303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 201403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 201503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 201603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 20179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 201803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 20199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza // Set the per-frame data 20209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 20219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 20229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 20235d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 20249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId < 0) { 20259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza continue; 20269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 202728f320b443106f1656f9720224f579136dcf0c61Chia-I Wu if (mDrawingState.colorMatrixChanged) { 202828f320b443106f1656f9720224f579136dcf0c61Chia-I Wu displayDevice->setColorTransform(mDrawingState.colorMatrix); 202928f320b443106f1656f9720224f579136dcf0c61Chia-I Wu status_t result = getBE().mHwc->setColorTransform(hwcId, mDrawingState.colorMatrix); 20309f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza ALOGE_IF(result != NO_ERROR, "Failed to set color transform on " 20319f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza "display %zd: %d", displayId, result); 20329f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 20339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 203407376a98a6c66c4e48bdebe82616f0ae47e5f805Chia-I Wu if (layer->isHdrY410()) { 203507376a98a6c66c4e48bdebe82616f0ae47e5f805Chia-I Wu layer->forceClientComposition(hwcId); 203607376a98a6c66c4e48bdebe82616f0ae47e5f805Chia-I Wu } else if ((layer->getDataSpace() == Dataspace::BT2020_PQ || 203707376a98a6c66c4e48bdebe82616f0ae47e5f805Chia-I Wu layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) && 20386266589793ddd9769a649a6b5f61ef115179572bPeiyong Lin !displayDevice->hasHDR10Support()) { 20395c6e46353676b4fd647317fde28c413d8ffe3565Chia-I Wu layer->forceClientComposition(hwcId); 204007376a98a6c66c4e48bdebe82616f0ae47e5f805Chia-I Wu } else if ((layer->getDataSpace() == Dataspace::BT2020_HLG || 204107376a98a6c66c4e48bdebe82616f0ae47e5f805Chia-I Wu layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) && 2042f59a719fe91b201ea0ef9447ae436457aa29a6d6Peiyong Lin !displayDevice->hasHLGSupport()) { 2043f59a719fe91b201ea0ef9447ae436457aa29a6d6Peiyong Lin layer->forceClientComposition(hwcId); 2044f59a719fe91b201ea0ef9447ae436457aa29a6d6Peiyong Lin } 20455c6e46353676b4fd647317fde28c413d8ffe3565Chia-I Wu 2046c9232edd34618360d099272fb0537cae2f715860chaviw if (layer->getForceClientComposition(hwcId)) { 2047c9232edd34618360d099272fb0537cae2f715860chaviw ALOGV("[%s] Requesting Client composition", layer->getName().string()); 2048c9232edd34618360d099272fb0537cae2f715860chaviw layer->setCompositionType(hwcId, HWC2::Composition::Client); 2049c9232edd34618360d099272fb0537cae2f715860chaviw continue; 2050c9232edd34618360d099272fb0537cae2f715860chaviw } 2051c9232edd34618360d099272fb0537cae2f715860chaviw 20529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->setPerFrameData(displayDevice); 205338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall } 20545d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter 20555d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter if (hasWideColorDisplay) { 2056dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin ColorMode colorMode; 2057dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin Dataspace dataSpace; 2058d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin RenderIntent renderIntent; 2059d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin pickColorMode(displayDevice, &colorMode, &dataSpace, &renderIntent); 2060d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin setActiveColorModeInternal(displayDevice, colorMode, dataSpace, renderIntent); 20615d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter } 206252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 20639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 206428f320b443106f1656f9720224f579136dcf0c61Chia-I Wu mDrawingState.colorMatrixChanged = false; 20659f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 20669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 20677bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza auto& displayDevice = mDisplays[displayId]; 20687bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 20697bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 20707bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 20717bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza 2072105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman status_t result = displayDevice->prepareFrame(*getBE().mHwc); 20739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:" 20749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza " %d (%s)", displayId, result, strerror(-result)); 20759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 2076cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian} 207752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian 2078cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() { 2079cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian ATRACE_CALL(); 20809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposition"); 20819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 208252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 208392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 20844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 20852c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (hw->isDisplayOn()) { 2086cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian // transform the dirty region into this screen's coordinate space 2087cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 208802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 208902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian // repaint the framebuffer (if needed) 209002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian doDisplayComposition(hw, dirtyRegion); 209102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian 2092cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian hw->dirtyRegion.clear(); 2093b02087dbd6a25e9d077fde16039050da8012b413Chia-I Wu hw->flip(); 209487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian } 20954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 209652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian postFramebuffer(); 2097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer() 2100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2101841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 21029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("postFramebuffer"); 2103b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian 2104a44b04163957d6086362f6f365443c4c93379031Mathias Agopian const nsecs_t now = systemTime(); 2105a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = now; 2106c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall 21079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 21089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 21097bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza if (!displayDevice->isDisplayOn()) { 21107bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza continue; 21117bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza } 21129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 21139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 2114105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman getBE().mHwc->presentAndGetReleaseFences(hwcId); 21159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 21162dc3be88bd85791556ab0e6df6a080989886749eDan Stoza displayDevice->onSwapBuffersCompleted(); 21177f40290b223afe1fea1d173da43e8e3d6ae49590Chia-I Wu displayDevice->makeCurrent(); 21189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 21197b5495932f6cb57c0b5771641655b70218a690faChia-I Wu // The layer buffer from the previous frame (if any) is released 21207b5495932f6cb57c0b5771641655b70218a690faChia-I Wu // by HWC only when the release fence from this frame (if any) is 21217b5495932f6cb57c0b5771641655b70218a690faChia-I Wu // signaled. Always get the release fence from HWC first. 21227b5495932f6cb57c0b5771641655b70218a690faChia-I Wu auto hwcLayer = layer->getHwcLayer(hwcId); 2123105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman sp<Fence> releaseFence = getBE().mHwc->getLayerReleaseFence(hwcId, hwcLayer); 21247b5495932f6cb57c0b5771641655b70218a690faChia-I Wu 21257b5495932f6cb57c0b5771641655b70218a690faChia-I Wu // If the layer was client composited in the previous frame, we 21267b5495932f6cb57c0b5771641655b70218a690faChia-I Wu // need to merge with the previous client target acquire fence. 21277b5495932f6cb57c0b5771641655b70218a690faChia-I Wu // Since we do not track that, always merge with the current 21287b5495932f6cb57c0b5771641655b70218a690faChia-I Wu // client target acquire fence when it is available, even though 21297b5495932f6cb57c0b5771641655b70218a690faChia-I Wu // this is suboptimal. 21309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) { 21317b5495932f6cb57c0b5771641655b70218a690faChia-I Wu releaseFence = Fence::merge("LayerRelease", releaseFence, 21327b5495932f6cb57c0b5771641655b70218a690faChia-I Wu displayDevice->getClientTargetAcquireFence()); 213352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian } 21347b5495932f6cb57c0b5771641655b70218a690faChia-I Wu 21359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->onLayerDisplayed(releaseFence); 21369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza } 213783806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu 213883806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu // We've got a list of layers needing fences, that are disjoint with 213983806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu // displayDevice->getVisibleLayersSortedByZ. The best we can do is to 214083806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu // supply them with the present fence. 214183806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu if (!displayDevice->getLayersNeedingFences().isEmpty()) { 2142105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman sp<Fence> presentFence = getBE().mHwc->getPresentFence(hwcId); 214383806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu for (auto& layer : displayDevice->getLayersNeedingFences()) { 214483806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu layer->onLayerDisplayed(presentFence); 214583806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu } 214683806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu } 214783806897c6366d841971a38f4a007bb83a7afb64Chia-I Wu 21489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hwcId >= 0) { 2149105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman getBE().mHwc->clearReleaseFences(hwcId); 2150ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 2151e8696a40e09b24b634214684d18526187b316a2fJamie Gennis } 2152e8696a40e09b24b634214684d18526187b316a2fJamie Gennis 2153a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mLastSwapBufferTime = systemTime() - now; 2154a44b04163957d6086362f6f365443c4c93379031Mathias Agopian mDebugInSwapBuffers = 0; 21556547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 21567d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // |mStateLock| not needed as we are on the main thread 21572ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY)) { 21582ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount(); 21592ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { 21602ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique logFrameStats(); 21612ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique } 21626547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis } 2163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 216587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 2166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2167841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 2168841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 21697cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // here we keep a copy of the drawing state (that is the state that's 21707cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // going to be overwritten by handleTransactionLocked()) outside of 21717cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // mStateLock so that the side-effects of the State assignment 21727cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian // don't happen with mStateLock held (which can cause deadlocks). 21737cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian State drawingState(mDrawingState); 21747cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian 2175ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian Mutex::Autolock _l(mStateLock); 2176ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian const nsecs_t now = systemTime(); 2177ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = now; 2178ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 2179ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // Here we're guaranteed that some transaction flags are set 2180ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // so we can call handleTransactionLocked() unconditionally. 2181ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // We call getTransactionFlags(), which will also clear the flags, 2182ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // with mStateLock held to guarantee that mCurrentState won't change 2183ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // until the transaction is committed. 2184ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 2185f15c3be1e8eab73da2dd3b2a7e6215302dae4314Jorim Jaggi mVsyncModulator.onTransactionHandled(); 2186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian transactionFlags = getTransactionFlags(eTransactionMask); 218787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian handleTransactionLocked(transactionFlags); 2188ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian 2189ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mLastTransactionTime = systemTime() - now; 2190ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian mDebugInTransaction = 0; 2191ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian invalidateHwcGeometry(); 2192ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian // here the transaction has been committed 21933d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian} 2194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2195715a2c13e6a010143761c1822ce7c4975921aa0bLloyd PiqueDisplayDevice::DisplayType SurfaceFlinger::determineDisplayType(hwc2_display_t display, 21960959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique HWC2::Connection connection) const { 2197715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique // Figure out whether the event is for the primary display or an 2198715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique // external display by matching the Hwc display id against one for a 2199715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique // connected display. If we did not find a match, we then check what 2200715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique // displays are not already connected to determine the type. If we don't 2201715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique // have a connected primary display, we assume the new display is meant to 2202715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique // be the primary display, and then if we don't have an external display, 2203715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique // we assume it is that. 2204715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique const auto primaryDisplayId = 2205715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique getBE().mHwc->getHwcDisplayId(DisplayDevice::DISPLAY_PRIMARY); 2206715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique const auto externalDisplayId = 2207715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique getBE().mHwc->getHwcDisplayId(DisplayDevice::DISPLAY_EXTERNAL); 2208715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique if (primaryDisplayId && primaryDisplayId == display) { 2209715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique return DisplayDevice::DISPLAY_PRIMARY; 2210715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique } else if (externalDisplayId && externalDisplayId == display) { 2211715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique return DisplayDevice::DISPLAY_EXTERNAL; 2212715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique } else if (connection == HWC2::Connection::Connected && !primaryDisplayId) { 2213715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique return DisplayDevice::DISPLAY_PRIMARY; 2214715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique } else if (connection == HWC2::Connection::Connected && !externalDisplayId) { 2215715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique return DisplayDevice::DISPLAY_EXTERNAL; 2216715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique } 2217715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique 2218715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique return DisplayDevice::DISPLAY_ID_INVALID; 2219715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique} 2220715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique 2221ba04e6237fb6ae1aede76b543028da101412b11dLloyd Piquevoid SurfaceFlinger::processDisplayHotplugEventsLocked() { 2222ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique for (const auto& event : mPendingHotplugEvents) { 2223715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique auto displayType = determineDisplayType(event.display, event.connection); 2224715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique if (displayType == DisplayDevice::DISPLAY_ID_INVALID) { 2225715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique ALOGW("Unable to determine the display type for display %" PRIu64, event.display); 2226715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique continue; 2227715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique } 2228ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique 2229ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique if (getBE().mHwc->isUsingVrComposer() && displayType == DisplayDevice::DISPLAY_EXTERNAL) { 2230ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique ALOGE("External displays are not supported by the vr hardware composer."); 2231ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique continue; 2232ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique } 2233ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique 2234715a2c13e6a010143761c1822ce7c4975921aa0bLloyd Pique getBE().mHwc->onHotplug(event.display, displayType, event.connection); 2235ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique 2236ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique if (event.connection == HWC2::Connection::Connected) { 22373bed0524e31f5f1844909006d952ff72196b98a2Steven Thomas if (!mBuiltinDisplays[displayType].get()) { 22383bed0524e31f5f1844909006d952ff72196b98a2Steven Thomas ALOGV("Creating built in display %d", displayType); 22393bed0524e31f5f1844909006d952ff72196b98a2Steven Thomas mBuiltinDisplays[displayType] = new BBinder(); 22403bed0524e31f5f1844909006d952ff72196b98a2Steven Thomas // All non-virtual displays are currently considered secure. 22413bed0524e31f5f1844909006d952ff72196b98a2Steven Thomas DisplayDeviceState info(displayType, true); 22423bed0524e31f5f1844909006d952ff72196b98a2Steven Thomas info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ? 22433bed0524e31f5f1844909006d952ff72196b98a2Steven Thomas "Built-in Screen" : "External Screen"; 22443bed0524e31f5f1844909006d952ff72196b98a2Steven Thomas mCurrentState.displays.add(mBuiltinDisplays[displayType], info); 22454d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->saveDisplayCreation(info); 22463bed0524e31f5f1844909006d952ff72196b98a2Steven Thomas } 2247ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique } else { 2248fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique ALOGV("Removing built in display %d", displayType); 2249ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique 2250fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique ssize_t idx = mCurrentState.displays.indexOfKey(mBuiltinDisplays[displayType]); 2251fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique if (idx >= 0) { 2252fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); 22534d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->saveDisplayDeletion(info.displayId); 2254fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique mCurrentState.displays.removeItemsAt(idx); 2255fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique } 2256fcd86617fb5cbbad3463c828211868859de23329Lloyd Pique mBuiltinDisplays[displayType].clear(); 2257ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique } 2258ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique 2259ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique processDisplayChangesLocked(); 2260ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique } 2261ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique 2262ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique mPendingHotplugEvents.clear(); 2263ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique} 2264ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique 22650959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Piquesp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( 22660959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state, 22670959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) { 2268dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin bool hasWideColorGamut = false; 22690607fbe8956a64151b165ac88ef9f3cf9b4ece5dChia-I Wu std::unordered_map<ColorMode, std::vector<RenderIntent>> hwcColorModes; 2270d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin 22710959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique if (hasWideColorDisplay) { 2272dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId); 22730959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique for (ColorMode colorMode : modes) { 22740959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique switch (colorMode) { 22750959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique case ColorMode::DISPLAY_P3: 22760959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique case ColorMode::ADOBE_RGB: 22770959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique case ColorMode::DCI_P3: 2278dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin hasWideColorGamut = true; 22790959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique break; 22800959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique default: 22810959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique break; 22820959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique } 2283dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin 2284dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin std::vector<RenderIntent> renderIntents = getHwComposer().getRenderIntents(hwcId, 2285dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin colorMode); 22860607fbe8956a64151b165ac88ef9f3cf9b4ece5dChia-I Wu hwcColorModes.emplace(colorMode, renderIntents); 22870959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique } 22880959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique } 22890959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 22906266589793ddd9769a649a6b5f61ef115179572bPeiyong Lin HdrCapabilities hdrCapabilities; 22916266589793ddd9769a649a6b5f61ef115179572bPeiyong Lin getHwComposer().getHdrCapabilities(hwcId, &hdrCapabilities); 22920959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 22930959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique auto nativeWindowSurface = mCreateNativeWindowSurface(producer); 22940959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique auto nativeWindow = nativeWindowSurface->getNativeWindow(); 22950959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 22960959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique /* 22970959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique * Create our display's surface 22980959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique */ 22990959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique std::unique_ptr<RE::Surface> renderSurface = getRenderEngine().createSurface(); 23000959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique renderSurface->setCritical(state.type == DisplayDevice::DISPLAY_PRIMARY); 23010959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique renderSurface->setAsync(state.type >= DisplayDevice::DISPLAY_VIRTUAL); 23020959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique renderSurface->setNativeWindow(nativeWindow.get()); 23030959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique const int displayWidth = renderSurface->queryWidth(); 23040959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique const int displayHeight = renderSurface->queryHeight(); 23050959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 23060959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique // Make sure that composition can never be stalled by a virtual display 23070959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique // consumer that isn't processing buffers fast enough. We have to do this 23080959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique // in two places: 23090959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique // * Here, in case the display is composed entirely by HWC. 23100959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the 23110959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique // window's swap interval in eglMakeCurrent, so they'll override the 23120959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique // interval we set here. 23130959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique if (state.type >= DisplayDevice::DISPLAY_VIRTUAL) { 23140959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique nativeWindow->setSwapInterval(nativeWindow.get(), 0); 23150959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique } 23160959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 23170959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique // virtual displays are always considered enabled 23180959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique auto initialPowerMode = (state.type >= DisplayDevice::DISPLAY_VIRTUAL) ? HWC_POWER_MODE_NORMAL 23190959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique : HWC_POWER_MODE_OFF; 23200959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 23210959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique sp<DisplayDevice> hw = 23220959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow, 23230959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique dispSurface, std::move(renderSurface), displayWidth, displayHeight, 23242c327ac2840b34848543cc961d16d3dbad102f16Peiyong Lin hasWideColorGamut, hdrCapabilities, 23252c327ac2840b34848543cc961d16d3dbad102f16Peiyong Lin getHwComposer().getSupportedPerFrameMetadata(hwcId), 23260607fbe8956a64151b165ac88ef9f3cf9b4ece5dChia-I Wu hwcColorModes, initialPowerMode); 23270959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 23280959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique if (maxFrameBufferAcquiredBuffers >= 3) { 23290959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique nativeWindowSurface->preallocateBuffers(); 23300959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique } 23310959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 23320959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique ColorMode defaultColorMode = ColorMode::NATIVE; 2333dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin Dataspace defaultDataSpace = Dataspace::UNKNOWN; 2334dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin if (hasWideColorGamut) { 23350959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique defaultColorMode = ColorMode::SRGB; 23360607fbe8956a64151b165ac88ef9f3cf9b4ece5dChia-I Wu defaultDataSpace = Dataspace::SRGB; 23370959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique } 2338d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace, 2339d6fa4a70ba70393816176eda0b64e2b576ce6d6bPeiyong Lin RenderIntent::COLORIMETRIC); 23403c085a07a84bc03aefb2c0caf24a1ae1a9f5f90cLloyd Pique if (state.type < DisplayDevice::DISPLAY_VIRTUAL) { 23413c085a07a84bc03aefb2c0caf24a1ae1a9f5f90cLloyd Pique hw->setActiveConfig(getHwComposer().getActiveConfigIndex(state.type)); 23423c085a07a84bc03aefb2c0caf24a1ae1a9f5f90cLloyd Pique } 23430959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique hw->setLayerStack(state.layerStack); 23440959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique hw->setProjection(state.orientation, state.viewport, state.frame); 23450959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique hw->setDisplayName(state.displayName); 23460959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 23470959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique return hw; 23480959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique} 23490959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique 2350347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Piquevoid SurfaceFlinger::processDisplayChangesLocked() { 2351347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // here we take advantage of Vector's copy-on-write semantics to 2352347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // improve performance by skipping the transaction entirely when 2353347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // know that the lists are identical 2354347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const KeyedVector<wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 2355347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const KeyedVector<wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 2356347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (!curr.isIdenticalTo(draw)) { 2357347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique mVisibleRegionsDirty = true; 2358347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const size_t cc = curr.size(); 2359347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique size_t dc = draw.size(); 2360347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2361347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // find the displays that were removed 2362347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // (ie: in drawing state but not in current state) 2363347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // also handle displays that changed 2364347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // (ie: displays that are in both lists) 2365347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique for (size_t i = 0; i < dc;) { 2366347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 2367347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (j < 0) { 2368347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // in drawing state but not in current state 23692ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique // Call makeCurrent() on the primary display so we can 23702ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique // be sure that nothing associated with this display 23712ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique // is current. 23722ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked()); 23732ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (defaultDisplay != nullptr) defaultDisplay->makeCurrent(); 23742ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i))); 23752ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (hw != nullptr) hw->disconnect(getHwComposer()); 23762ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) 23772ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique mEventThread->onHotplugReceived(draw[i].type, false); 23782ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique mDisplays.removeItem(draw.keyAt(i)); 2379347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } else { 2380347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // this display is in both lists. see if something changed. 2381347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const DisplayDeviceState& state(curr[j]); 2382347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const wp<IBinder>& display(curr.keyAt(j)); 2383347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const sp<IBinder> state_binder = IInterface::asBinder(state.surface); 2384347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface); 2385347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (state_binder != draw_binder) { 2386347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // changing the surface is like destroying and 2387347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // recreating the DisplayDevice, so we just remove it 2388347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // from the drawing state, so that it get re-added 2389347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // below. 2390347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique sp<DisplayDevice> hw(getDisplayDeviceLocked(display)); 2391347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (hw != nullptr) hw->disconnect(getHwComposer()); 2392347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique mDisplays.removeItem(display); 2393347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique mDrawingState.displays.removeItemsAt(i); 2394347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique dc--; 2395347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // at this point we must loop to the next item 2396347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique continue; 2397347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2398347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2399347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const sp<DisplayDevice> disp(getDisplayDeviceLocked(display)); 2400347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (disp != nullptr) { 2401347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (state.layerStack != draw[i].layerStack) { 2402347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique disp->setLayerStack(state.layerStack); 2403347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2404347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if ((state.orientation != draw[i].orientation) || 2405347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique (state.viewport != draw[i].viewport) || (state.frame != draw[i].frame)) { 2406347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique disp->setProjection(state.orientation, state.viewport, state.frame); 2407347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2408347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (state.width != draw[i].width || state.height != draw[i].height) { 2409347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique disp->setDisplaySize(state.width, state.height); 2410347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2411347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2412347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2413347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique ++i; 2414347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2415347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2416347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // find displays that were added 2417347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // (ie: in current state but not in drawing state) 2418347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique for (size_t i = 0; i < cc; i++) { 2419347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (draw.indexOfKey(curr.keyAt(i)) < 0) { 2420347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const DisplayDeviceState& state(curr[i]); 2421347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2422347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique sp<DisplaySurface> dispSurface; 2423347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique sp<IGraphicBufferProducer> producer; 2424347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique sp<IGraphicBufferProducer> bqProducer; 2425347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique sp<IGraphicBufferConsumer> bqConsumer; 242612eb423785adba54be4c7112e5198a80d563896eLloyd Pique mCreateBufferQueue(&bqProducer, &bqConsumer, false); 2427347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2428347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique int32_t hwcId = -1; 2429347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (state.isVirtualDisplay()) { 2430347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // Virtual displays without a surface are dormant: 2431347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // they have external state (layer stack, projection, 2432347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // etc.) but no internal state (i.e. a DisplayDevice). 2433347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (state.surface != nullptr) { 2434347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // Allow VR composer to use virtual displays. 2435347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (mUseHwcVirtualDisplays || getBE().mHwc->isUsingVrComposer()) { 2436347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique int width = 0; 2437347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique int status = state.surface->query(NATIVE_WINDOW_WIDTH, &width); 2438347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique ALOGE_IF(status != NO_ERROR, "Unable to query width (%d)", status); 2439347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique int height = 0; 2440347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique status = state.surface->query(NATIVE_WINDOW_HEIGHT, &height); 2441347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique ALOGE_IF(status != NO_ERROR, "Unable to query height (%d)", status); 2442347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique int intFormat = 0; 2443347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique status = state.surface->query(NATIVE_WINDOW_FORMAT, &intFormat); 2444347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status); 244534beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Lin auto format = static_cast<ui::PixelFormat>(intFormat); 2446347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2447347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique getBE().mHwc->allocateVirtualDisplay(width, height, &format, &hwcId); 2448347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2449347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2450347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique // TODO: Plumb requested format back up to consumer 2451347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2452347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique sp<VirtualDisplaySurface> vds = 2453347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique new VirtualDisplaySurface(*getBE().mHwc, hwcId, state.surface, 2454347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique bqProducer, bqConsumer, 2455347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique state.displayName); 2456347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2457347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique dispSurface = vds; 2458347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique producer = vds; 2459347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2460347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } else { 2461347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique ALOGE_IF(state.surface != nullptr, 2462347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique "adding a supported display, but rendering " 2463347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique "surface is provided (%p), ignoring it", 2464347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique state.surface.get()); 2465347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2466347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique hwcId = state.type; 2467347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique dispSurface = new FramebufferSurface(*getBE().mHwc, hwcId, bqConsumer); 2468347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique producer = bqProducer; 2469347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2470347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 2471347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique const wp<IBinder>& display(curr.keyAt(i)); 2472347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (dispSurface != nullptr) { 24730959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique mDisplays.add(display, 24740959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique setupNewDisplayDeviceInternal(display, hwcId, state, dispSurface, 24750959483fe3a2e4f70c91d4a0579ddbe03c9d3262Lloyd Pique producer)); 2476347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique if (!state.isVirtualDisplay()) { 2477347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique mEventThread->onHotplugReceived(state.type, true); 2478347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2479347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2480347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2481347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2482347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique } 2483ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique 2484ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique mDrawingState.displays = mCurrentState.displays; 2485347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique} 2486347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique 248787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 24883d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{ 24897dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza // Notify all layers of available frames 24902047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([](Layer* layer) { 24912047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr layer->notifyAvailableFrames(); 24922047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 24937dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza 2494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 2495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Traversal of the children 2496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (perform the transaction for each of them if needed) 2497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 2498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24993559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (transactionFlags & eTraversalNeeded) { 25002047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 2501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 25022047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr if (!trFlags) return; 2503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t flags = layer->doTransaction(0); 2505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & Layer::eVisibleRegion) 2506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mVisibleRegionsDirty = true; 25072047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 2508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 25113559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform display own transactions if needed 2512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 2513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (transactionFlags & eDisplayTransactionNeeded) { 2515347200f079e004495aa46d6e1d5c1dec2632bbc6Lloyd Pique processDisplayChangesLocked(); 2516ba04e6237fb6ae1aede76b543028da101412b11dLloyd Pique processDisplayHotplugEventsLocked(); 25173559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 2518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2519d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique if (transactionFlags & (eDisplayLayerStackChanged|eDisplayTransactionNeeded)) { 25208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // The transform hint might have changed for some layers 25218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (either because a display has changed, or because a layer 25228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // as changed). 25238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 25248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // Walk through all the layers in currentLayers, 25258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // and update their transform hint. 25268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 25278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // If a layer is visible only on a single display, then that 25288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // display is used to calculate the hint, otherwise we use the 25298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // default display. 25308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 25318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we do this here, rather than in rebuildLayerStacks() so that 25328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // the hint is set before we acquire a buffer from the surface texture. 25338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 25348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: layer transactions have taken place already, so we use their 25358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // drawing state. However, SurfaceFlinger's own transaction has not 25368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // happened yet, so we must use the current state layer list 25378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (soon to become the drawing state list). 25388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // 25398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> disp; 25408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian uint32_t currentlayerStack = 0; 25412047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr bool first = true; 25422047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 25438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // NOTE: we rely on the fact that layers are sorted by 25448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // layerStack first (so we don't have to traverse the list 25458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // of displays for every layer). 25461f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr uint32_t layerStack = layer->getLayerStack(); 25472047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr if (first || currentlayerStack != layerStack) { 25488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian currentlayerStack = layerStack; 25498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // figure out if this layerstack is mirrored 25508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // (more than one display) if so, pick the default display, 25518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian // if not, pick the only display it's on. 25528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian disp.clear(); 25538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 25548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian sp<const DisplayDevice> hw(mDisplays[dpy]); 2555ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu if (layer->belongsToDisplay(hw->getLayerStack(), hw->isPrimary())) { 2556566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (disp == nullptr) { 2557406a285ab039e4bd83fc98fc7c3fb4a9107d8dd2George Burgess IV disp = std::move(hw); 25588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } else { 2559566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin disp = nullptr; 25608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian break; 25618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 25628430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 25638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 25648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 256556a0b9ac6a951053e283cf42e245a48d28d2624cRobert Carr 2566d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique if (disp == nullptr) { 2567d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to 2568d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique // redraw after transform hint changes. See bug 8508397. 256956a0b9ac6a951053e283cf42e245a48d28d2624cRobert Carr 2570d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique // could be null when this layer is using a layerStack 2571d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique // that is not visible on any display. Also can occur at 2572d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique // screen off/on times. 2573d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique disp = getDefaultDisplayDeviceLocked(); 25748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 2575d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique 2576d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique // disp can be null if there is no display available at all to get 2577d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique // the transform hint from. 25782ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (disp != nullptr) { 25792ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique layer->updateTransformHint(disp); 25802ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique } 25812047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr 25822047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr first = false; 25832047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 25848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian } 25858430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 25868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian 25873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian /* 25883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian * Perform our own transaction if needed 25893559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian */ 25901f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr 25911f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (mLayersAdded) { 25921f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mLayersAdded = false; 25931f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr // Layers have been added. 25943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 25953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian } 25963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian 25973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // some layers might have been removed, so 25983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // we need to update the regions they're exposing. 25993559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian if (mLayersRemoved) { 26003559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mLayersRemoved = false; 26013559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian mVisibleRegionsDirty = true; 26022047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 26031f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (mLayersPendingRemoval.indexOf(layer) >= 0) { 26043559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // this layer is not visible anymore 26053559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could traverse the tree from front to back and 26063559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // compute the actual visible region 26073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian // TODO: we could cache the transformed region 26081f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr Region visibleReg; 26091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr visibleReg.set(layer->computeScreenBounds()); 2610ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu invalidateLayerStack(layer, visibleReg); 26110aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian } 26122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 2613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project commitTransaction(); 261603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 261703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews updateCursorAsync(); 261803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews} 261903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews 262003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync() 262103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{ 26229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { 26239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza auto& displayDevice = mDisplays[displayId]; 26249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getHwcDisplayId() < 0) { 262503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews continue; 262603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 26279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 26289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 26299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza layer->updateCursorPosition(displayDevice); 263003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 263103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews } 26324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian} 26334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 26344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction() 26354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{ 2636598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch if (!mLayersPendingRemoval.isEmpty()) { 26374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian // Notify removed layers now that they can't be drawn from 26381f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr for (const auto& l : mLayersPendingRemoval) { 26391f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr recordBufferingStats(l->getName().string(), 26401f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr l->getOccupancyHistory(true)); 26411f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr l->onRemoved(); 26424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 26434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mLayersPendingRemoval.clear(); 26444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 26454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian 26464b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // If this transaction is part of a window animation then the next frame 26474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis // we composite should be considered an animation as well. 26484b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis mAnimCompositionPending = mAnimTransactionPending; 26494b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 26504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mDrawingState = mCurrentState; 265128f320b443106f1656f9720224f579136dcf0c61Chia-I Wu // clear the "changed" flags in current state 265228f320b443106f1656f9720224f579136dcf0c61Chia-I Wu mCurrentState.colorMatrixChanged = false; 265328f320b443106f1656f9720224f579136dcf0c61Chia-I Wu 26541f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mDrawingState.traverseInZOrder([](Layer* layer) { 26551f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr layer->commitChildList(); 26561f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr }); 26572d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 26582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 26594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian mTransactionCV.broadcast(); 2660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2662ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wuvoid SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displayDevice, 266387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian Region& outDirtyRegion, Region& outOpaqueRegion) 2664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2665841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian ATRACE_CALL(); 26669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("computeVisibleRegions"); 2667841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian 2668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveOpaqueLayers; 2669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region aboveCoveredLayers; 2670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty; 2671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 267287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.clear(); 2673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26742047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInReverseZOrder([&](Layer* layer) { 2675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // start with the whole surface at its current location 26761eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian const Layer::State& s(layer->getDrawingState()); 2677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 267801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // only consider the layers on the given layer stack 2679ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu if (!layer->belongsToDisplay(displayDevice->getLayerStack(), displayDevice->isPrimary())) 26802047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr return; 268187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 2682ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 2683ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * opaqueRegion: area of a surface that is fully opaque. 2684ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 2685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region opaqueRegion; 2686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 2688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visibleRegion: area of a surface that is visible on screen 2689ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * and not fully transparent. This is essentially the layer's 2690ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * footprint minus the opaque regions above it. 2691ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * Areas covered by a translucent surface are considered visible. 2692ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 2693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region visibleRegion; 2694ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2695ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian /* 2696ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * coveredRegion: area of a surface that is covered by all 2697ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible regions above it (which includes the translucent areas). 2698ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian */ 2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region coveredRegion; 2700ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2701a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall /* 2702a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparentRegion: area of a surface that is hinted to be completely 2703a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * transparent. This is only used to tell when the layer has no visible 2704a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * non-transparent regions and can be removed from the layer list. It 2705a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * does not affect the visibleRegion of this layer or any layers 2706a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * beneath it. The hint may not be correct if apps don't respect the 2707a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall * SurfaceView restrictions (which, sadly, some don't). 2708a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall */ 2709a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall Region transparentRegion; 2710a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall 2711ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2712ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // handle hidden surfaces by setting the visible region to empty 2713da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian if (CC_LIKELY(layer->isVisible())) { 27144125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden const bool translucent = !layer->isOpaque(s); 27151f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr Rect bounds(layer->computeScreenBounds()); 2716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.set(bounds); 27171f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr Transform tr = layer->getTransform(); 2718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (!visibleRegion.isEmpty()) { 2719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Remove the transparent area from the visible region 2720ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian if (translucent) { 272122f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza if (tr.preserveRects()) { 272222f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transform the transparent region 272322f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion = tr.transform(s.activeTransparentRegion); 27244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } else { 272522f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transformation too complex, can't do the 272622f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza // transparent region optimization. 272722f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza transparentRegion.clear(); 27284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 2729ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 2730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2731ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // compute the opaque region 27321f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const int32_t layerOrientation = tr.getOrientation(); 2733039bbb8aca1280afdf0ecf20810c32804a82199dJorim Jaggi if (layer->getAlpha() == 1.0f && !translucent && 2734ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian ((layerOrientation & Transform::ROT_INVALID) == false)) { 2735ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // the opaque region is the layer's footprint 2736ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian opaqueRegion = visibleRegion; 2737ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian } 2738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2741e5f4f694f11ad1e8a9bb3b1b9579a175435c7c19Robert Carr if (visibleRegion.isEmpty()) { 2742e5f4f694f11ad1e8a9bb3b1b9579a175435c7c19Robert Carr layer->clearVisibilityRegions(); 2743e5f4f694f11ad1e8a9bb3b1b9579a175435c7c19Robert Carr return; 2744e5f4f694f11ad1e8a9bb3b1b9579a175435c7c19Robert Carr } 2745e5f4f694f11ad1e8a9bb3b1b9579a175435c7c19Robert Carr 2746ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Clip the covered region to the visible region 2747ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 2748ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2749ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveCoveredLayers for next (lower) layer 2750ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian aboveCoveredLayers.orSelf(visibleRegion); 2751ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian 2752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // subtract the opaque region covered by the layers above us 2753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegion.subtractSelf(aboveOpaqueLayers); 2754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // compute this layer's dirty region 2756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (layer->contentDirty) { 2757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we need to invalidate the whole region 2758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty = visibleRegion; 2759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // as well, as the old visible region 27604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian dirty.orSelf(layer->visibleRegion); 2761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->contentDirty = false; 2762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 2763a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian /* compute the exposed region: 2764ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * the exposed region consists of two components: 2765ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 1) what's VISIBLE now and was COVERED before 2766ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2) what's EXPOSED now less what was EXPOSED before 2767ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2768ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * note that (1) is conservative, we start with the whole 2769ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * visible region but only keep what used to be covered by 2770ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * something -- which mean it may have been exposed. 2771ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * 2772ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * (2) handles areas that were not covered by anything but got 2773ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian * exposed because of a resize. 2774a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian */ 2775ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region newExposed = visibleRegion - coveredRegion; 27764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldVisibleRegion = layer->visibleRegion; 27774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian const Region oldCoveredRegion = layer->coveredRegion; 2778ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 2779ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 2780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.subtractSelf(aboveOpaqueLayers); 2782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // accumulate to the screen dirty region 278487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outDirtyRegion.orSelf(dirty); 2785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2786ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian // Update aboveOpaqueLayers for next (lower) layer 2787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project aboveOpaqueLayers.orSelf(opaqueRegion); 27888b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 2789a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall // Store the visible region in screen space 2790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setVisibleRegion(visibleRegion); 2791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer->setCoveredRegion(coveredRegion); 2792a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall layer->setVisibleNonTransparentRegion( 2793a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall visibleRegion.subtract(transparentRegion)); 27942047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 2795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 279687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian outOpaqueRegion = aboveOpaqueLayers; 2797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2799ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wuvoid SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) { 280092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 28014297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian const sp<DisplayDevice>& hw(mDisplays[dpy]); 2802ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu if (layer->belongsToDisplay(hw->getLayerStack(), hw->isPrimary())) { 28034297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian hw->dirtyRegion.orSelf(dirty); 280492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 280592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian } 280687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian} 280787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian 28086b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip() 2809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 28109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("handlePageFlip"); 28119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 2812d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson nsecs_t latchTime = systemTime(); 281399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 28144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian bool visibleRegions = false; 28156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza bool frameQueued = false; 28160cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan bool newDataLatched = false; 281751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner 281851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Store the set of layers that need updates. This set must not change as 281951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // buffers are being latched, as this could result in a deadlock. 282051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Example: Two producers share the same command stream and: 282151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 1.) Layer 0 is latched 282251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 0 gets a new frame 282351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 2.) Layer 1 gets a new frame 282451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // 3.) Layer 1 is latched. 282551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // Display is now waiting on Layer 1's frame, which is behind layer 0's 282651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner // second frame. But layer 0's second frame could be waiting on display. 28272047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 28286b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->hasQueuedFrame()) { 28296b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza frameQueued = true; 28306b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza if (layer->shouldPresentNow(mPrimaryDispSync)) { 28312047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mLayersWithQueuedFrames.push_back(layer); 2832ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 2833ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 28346b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 2835ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } else { 2836ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useEmptyDamage(); 28376b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 28382047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 28392047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr 28409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza for (auto& layer : mLayersWithQueuedFrames) { 2841d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const Region dirty(layer->latchBuffer(visibleRegions, latchTime)); 2842ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza layer->useSurfaceDamage(); 2843ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu invalidateLayerStack(layer, dirty); 2844a36bf92663256f1c8d2956902daf0f1045961953Chia-I Wu if (layer->isBufferLatched()) { 28450cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan newDataLatched = true; 28460cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan } 28474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian } 28484da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian 28493b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian mVisibleRegionsDirty |= visibleRegions; 28506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 28516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // If we will need to wake up at some time in the future to deal with a 28526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // queued frame that shouldn't be displayed during this vsync period, wake 28536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // up during the next vsync period to check again. 2854a36bf92663256f1c8d2956902daf0f1045961953Chia-I Wu if (frameQueued && (mLayersWithQueuedFrames.empty() || !newDataLatched)) { 28556b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza signalLayerUpdate(); 28566b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza } 28576b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza 28586b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza // Only continue with the refresh if there is actually new work to do 28590cd7619bce422d46a5f2c45ca97734ae467a1b01Mike Stroyan return !mLayersWithQueuedFrames.empty() && newDataLatched; 2860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2862ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry() 2863ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{ 28649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza mGeometryInvalid = true; 2865ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian} 2866ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian 286799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian 2868830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::doDisplayComposition( 2869830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard const sp<const DisplayDevice>& displayDevice, 287087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian const Region& inDirtyRegion) 2871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 28727143316af216fa92c31a60d4407b707637382da1Dan Stoza // We only need to actually compose the display if: 28737143316af216fa92c31a60d4407b707637382da1Dan Stoza // 1) It is being handled by hardware composer, which may need this to 28747143316af216fa92c31a60d4407b707637382da1Dan Stoza // keep its virtual display state machine in sync, or 28757143316af216fa92c31a60d4407b707637382da1Dan Stoza // 2) There is work to be done (the dirty region isn't empty) 2876830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard bool isHwcDisplay = displayDevice->getHwcDisplayId() >= 0; 28777143316af216fa92c31a60d4407b707637382da1Dan Stoza if (!isHwcDisplay && inDirtyRegion.isEmpty()) { 28789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Skipping display composition"); 28797143316af216fa92c31a60d4407b707637382da1Dan Stoza return; 28807143316af216fa92c31a60d4407b707637382da1Dan Stoza } 28817143316af216fa92c31a60d4407b707637382da1Dan Stoza 28829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doDisplayComposition"); 2883b02087dbd6a25e9d077fde16039050da8012b413Chia-I Wu if (!doComposeSurfaces(displayDevice)) return; 2884da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian 2885da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian // swap buffers (presentation) 2886830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard displayDevice->swapBuffers(getHwComposer()); 2887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 2888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2889b02087dbd6a25e9d077fde16039050da8012b413Chia-I Wubool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDevice) 2890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 28919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("doComposeSurfaces"); 28929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 2893b02087dbd6a25e9d077fde16039050da8012b413Chia-I Wu const Region bounds(displayDevice->bounds()); 2894a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const DisplayRenderArea renderArea(displayDevice); 28959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const auto hwcId = displayDevice->getHwcDisplayId(); 2896dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin const bool hasClientComposition = getBE().mHwc->hasClientComposition(hwcId); 2897dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin ATRACE_INT("hasClientComposition", hasClientComposition); 28989f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 28998e50e696caf054c2f014162834916a8926a194c7Chia-I Wu bool applyColorMatrix = false; 290076dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin bool needsLegacyColorMatrix = false; 290176dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin bool legacyColorMatrixApplied = false; 29029f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 29039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasClientComposition) { 29049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("hasClientComposition"); 2905a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 290634beb7a0ff0494b0c5ad81104171f8a49e599163Peiyong Lin Dataspace outputDataspace = Dataspace::UNKNOWN; 2907dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin if (displayDevice->hasWideColorGamut()) { 2908dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin outputDataspace = displayDevice->getCompositionDataSpace(); 290969bf10f5ea9b8abce49d49235630388dd57d3e62Chia-I Wu } 291069bf10f5ea9b8abce49d49235630388dd57d3e62Chia-I Wu getBE().mRenderEngine->setOutputDataSpace(outputDataspace); 2911fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin getBE().mRenderEngine->setDisplayMaxLuminance( 2912fb069305e90947aeb76b72527f23aa24564f3c87Peiyong Lin displayDevice->getHdrCapabilities().getDesiredMaxLuminance()); 291369bf10f5ea9b8abce49d49235630388dd57d3e62Chia-I Wu 29148e50e696caf054c2f014162834916a8926a194c7Chia-I Wu const bool hasDeviceComposition = getBE().mHwc->hasDeviceComposition(hwcId); 29158e50e696caf054c2f014162834916a8926a194c7Chia-I Wu const bool skipClientColorTransform = getBE().mHwc->hasCapability( 29168e50e696caf054c2f014162834916a8926a194c7Chia-I Wu HWC2::Capability::SkipClientColorTransform); 29178e50e696caf054c2f014162834916a8926a194c7Chia-I Wu 29188e50e696caf054c2f014162834916a8926a194c7Chia-I Wu applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform; 29198e50e696caf054c2f014162834916a8926a194c7Chia-I Wu if (applyColorMatrix) { 292076dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin getRenderEngine().setupColorTransform(mDrawingState.colorMatrix); 29218e50e696caf054c2f014162834916a8926a194c7Chia-I Wu } 29228e50e696caf054c2f014162834916a8926a194c7Chia-I Wu 2923bbb44464990d0becd1c5eef77f85da82b8008534Chia-I Wu needsLegacyColorMatrix = 29240d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu (displayDevice->getActiveRenderIntent() >= RenderIntent::ENHANCE && 2925bbb44464990d0becd1c5eef77f85da82b8008534Chia-I Wu outputDataspace != Dataspace::UNKNOWN && 2926bbb44464990d0becd1c5eef77f85da82b8008534Chia-I Wu outputDataspace != Dataspace::SRGB); 29278e50e696caf054c2f014162834916a8926a194c7Chia-I Wu 29287f40290b223afe1fea1d173da43e8e3d6ae49590Chia-I Wu if (!displayDevice->makeCurrent()) { 2929c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", 29309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza displayDevice->getDisplayName().string()); 29317f40290b223afe1fea1d173da43e8e3d6ae49590Chia-I Wu getRenderEngine().resetCurrentSurface(); 29327d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk 29337d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk // |mStateLock| not needed as we are on the main thread 29347f40290b223afe1fea1d173da43e8e3d6ae49590Chia-I Wu if(!getDefaultDisplayDeviceLocked()->makeCurrent()) { 29353f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting."); 29363f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine } 29373f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return false; 2938c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock } 2939a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian 2940a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian // Never touch the framebuffer if we don't have any framebuffer layers 29419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (hasDeviceComposition) { 2942b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // when using overlays, we assume a fully transparent framebuffer 2943b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // NOTE: we could reduce how much we need to clear, for instance 2944b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // remove where there are opaque FB layers. however, on some 29453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // GPUs doing a "clean slate" clear might be more efficient. 2946b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // We'll revisit later if needed. 2947bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman getBE().mRenderEngine->clearWithColor(0, 0, 0, 0); 2948b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } else { 2949b02087dbd6a25e9d077fde16039050da8012b413Chia-I Wu // we start with the whole screen area and remove the scissor part 2950766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // we're left with the letterbox region 2951766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // (common case is that letterbox ends-up being empty) 29529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Region letterbox(bounds.subtract(displayDevice->getScissor())); 2953766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2954766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // compute the area to clear 29559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza Region region(displayDevice->undefinedRegion.merge(letterbox)); 2956766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian 2957b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // screen is already cleared here 295887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian if (!region.isEmpty()) { 2959b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian // can happen with SurfaceView 29609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza drawWormhole(displayDevice, region); 2961b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian } 2962a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 2963f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 29649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { 2965766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian // just to be on the safe side, we don't set the 2966f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor on the main display. It should never be needed 2967f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // anyways (though in theory it could since the API allows it). 29689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& bounds(displayDevice->getBounds()); 29699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Rect& scissor(displayDevice->getScissor()); 2970f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian if (scissor != bounds) { 2971f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // scissor doesn't match the screen's dimensions, so we 2972f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // need to clear everything outside of it and enable 2973f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // the GL scissor so we don't draw anything where we shouldn't 29743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2975f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // enable scissor for this frame 29769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const uint32_t height = displayDevice->getHeight(); 2977bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom, 29783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian scissor.getWidth(), scissor.getHeight()); 2979f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 2980f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian } 298185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 29824b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 298385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian /* 298485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian * and then, render the layers targeted at the framebuffer 298585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian */ 29864b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian 29879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza ALOGV("Rendering client layers"); 29889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const Transform& displayTransform = displayDevice->getTransform(); 29895e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu bool firstLayer = true; 29905e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { 29915e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu const Region clip(bounds.intersect( 29925e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu displayTransform.transform(layer->visibleRegion))); 29935e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu ALOGV("Layer: %s", layer->getName().string()); 29945e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu ALOGV(" Composition type: %s", 29955e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu to_string(layer->getCompositionType(hwcId)).c_str()); 29965e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu if (!clip.isEmpty()) { 29975e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu switch (layer->getCompositionType(hwcId)) { 29985e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu case HWC2::Composition::Cursor: 29995e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu case HWC2::Composition::Device: 30005e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu case HWC2::Composition::Sideband: 30015e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu case HWC2::Composition::SolidColor: { 30025e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu const Layer::State& state(layer->getDrawingState()); 30035e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu if (layer->getClearClientTarget(hwcId) && !firstLayer && 30045e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu layer->isOpaque(state) && (state.color.a == 1.0f) 30055e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu && hasClientComposition) { 30065e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu // never clear the very first layer since we're 30075e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu // guaranteed the FB is already cleared 30085e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu layer->clearWithOpenGL(renderArea); 300985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 30105e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu break; 30115e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu } 30125e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu case HWC2::Composition::Client: { 30138e50e696caf054c2f014162834916a8926a194c7Chia-I Wu // switch color matrices lazily 301476dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin if (layer->isLegacyDataSpace() && needsLegacyColorMatrix) { 301576dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin if (!legacyColorMatrixApplied) { 301676dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin getRenderEngine().setSaturationMatrix(mLegacySrgbSaturationMatrix); 301776dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin legacyColorMatrixApplied = true; 3018dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin } 301976dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin } else if (legacyColorMatrixApplied) { 302076dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin getRenderEngine().setSaturationMatrix(mat4()); 302176dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin legacyColorMatrixApplied = false; 3022a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian } 30238e50e696caf054c2f014162834916a8926a194c7Chia-I Wu 30245e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu layer->draw(renderArea, clip); 30255e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu break; 3026cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian } 30275e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu default: 30285e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu break; 302985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian } 30305e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu } else { 30315e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu ALOGV(" Skipping for empty clip"); 30324b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 30335e9a43e006a185fa43409c7fdb6c32d5bb786e70Chia-I Wu firstLayer = false; 30344b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian } 3035f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian 303676dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin if (applyColorMatrix) { 30378e50e696caf054c2f014162834916a8926a194c7Chia-I Wu getRenderEngine().setupColorTransform(mat4()); 30389f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 303976dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin if (needsLegacyColorMatrix && legacyColorMatrixApplied) { 304076dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin getRenderEngine().setSaturationMatrix(mat4()); 304176dd77a6f5298bf0e7cb89ec570ab1578e3947fbPeiyong Lin } 30429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza 3043f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian // disable scissor at the end of the frame 3044bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman getBE().mRenderEngine->disableScissor(); 30453f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine return true; 3046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3048830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const { 3049830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard const int32_t height = displayDevice->getHeight(); 3050144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique auto& engine(getRenderEngine()); 30513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.fillRegionWithColor(region, height, 0, 0, 0, 0); 3052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30547d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 3055ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian const sp<IBinder>& handle, 30566710604286401d4205c27235a252dd0e5008cc08Mathias Agopian const sp<IGraphicBufferProducer>& gbc, 30571f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const sp<Layer>& lbc, 30581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const sp<Layer>& parent) 30591b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{ 30607d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza // add this layer to the current state list 30617d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza { 30627d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza Mutex::Autolock _l(mStateLock); 30631f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (mNumLayers >= MAX_LAYERS) { 3064ab702f5110628108de5f3611820d86b97852826fCourtney Goeltzenleuchter ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers, 3065ab702f5110628108de5f3611820d86b97852826fCourtney Goeltzenleuchter MAX_LAYERS); 30667d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_MEMORY; 30677d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 30681f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (parent == nullptr) { 30691f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mCurrentState.layersSortedByZ.add(lbc); 30701f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } else { 3071ebd62af1a1efcd200c7f7ecf5f165a31568907b0Robert Carr if (parent->isPendingRemoval()) { 307298f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu ALOGE("addClientLayer called with a removed parent"); 307398f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu return NAME_NOT_FOUND; 307498f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu } 30751f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr parent->addChild(lbc); 30761f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 307798f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu 3078243b378f47552ab6916fc9b92557c0df0557fd98Yiwei Zhang if (gbc != nullptr) { 3079243b378f47552ab6916fc9b92557c0df0557fd98Yiwei Zhang mGraphicBufferProducerList.insert(IInterface::asBinder(gbc).get()); 3080243b378f47552ab6916fc9b92557c0df0557fd98Yiwei Zhang LOG_ALWAYS_FATAL_IF(mGraphicBufferProducerList.size() > 3081243b378f47552ab6916fc9b92557c0df0557fd98Yiwei Zhang mMaxGraphicBufferProducerListSize, 3082243b378f47552ab6916fc9b92557c0df0557fd98Yiwei Zhang "Suspected IGBP leak: %zu IGBPs (%zu max), %zu Layers", 3083243b378f47552ab6916fc9b92557c0df0557fd98Yiwei Zhang mGraphicBufferProducerList.size(), 3084243b378f47552ab6916fc9b92557c0df0557fd98Yiwei Zhang mMaxGraphicBufferProducerListSize, mNumLayers); 3085243b378f47552ab6916fc9b92557c0df0557fd98Yiwei Zhang } 30861f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mLayersAdded = true; 30871f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mNumLayers++; 30887d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 30897d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 309096f0819f81293076e652792794a961543e6750d7Mathias Agopian // attach this layer to the client 3091ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian client->attachLayer(handle, lbc); 30924f113740180b6512b43723c4728f262882dc9b45Mathias Agopian 30937d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return NO_ERROR; 309496f0819f81293076e652792794a961543e6750d7Mathias Agopian} 309596f0819f81293076e652792794a961543e6750d7Mathias Agopian 3096515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wustatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer, bool topLevelOnly) { 30977f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr Mutex::Autolock _l(mStateLock); 3098ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw return removeLayerLocked(mStateLock, layer, topLevelOnly); 3099ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw} 31007f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr 3101ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviwstatus_t SurfaceFlinger::removeLayerLocked(const Mutex&, const sp<Layer>& layer, 3102ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw bool topLevelOnly) { 31038b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->isPendingRemoval()) { 31048b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw return NO_ERROR; 31058b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 31068b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw 31071f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr const auto& p = layer->getParent(); 3108515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu ssize_t index; 310998f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu if (p != nullptr) { 3110515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu if (topLevelOnly) { 3111515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu return NO_ERROR; 3112515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu } 3113515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu 311498f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu sp<Layer> ancestor = p; 311598f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu while (ancestor->getParent() != nullptr) { 311698f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu ancestor = ancestor->getParent(); 311798f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu } 311898f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu if (mCurrentState.layersSortedByZ.indexOf(ancestor) < 0) { 311998f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu ALOGE("removeLayer called with a layer whose parent has been removed"); 312098f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu return NAME_NOT_FOUND; 312198f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu } 3122fae51c438827ae0a55c1b83c0e9be348254bfbd4Chia-I Wu 3123fae51c438827ae0a55c1b83c0e9be348254bfbd4Chia-I Wu index = p->removeChild(layer); 3124515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu } else { 3125515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu index = mCurrentState.layersSortedByZ.remove(layer); 312698f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu } 312798f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu 3128136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // As a matter of normal operation, the LayerCleaner will produce a second 3129136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // attempt to remove the surface. The Layer will be kept alive in mDrawingState 3130136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // so we will succeed in promoting it, but it's already been removed 3131136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // from mCurrentState. As long as we can find it in mDrawingState we have no problem 3132136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr // otherwise something has gone wrong and we are leaking the layer. 3133136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr if (index < 0 && mDrawingState.layersSortedByZ.indexOf(layer) < 0) { 31341f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr ALOGE("Failed to find layer (%s) in layer parent (%s).", 31351f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr layer->getName().string(), 31361f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr (p != nullptr) ? p->getName().string() : "no-parent"); 31371f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr return BAD_VALUE; 3138136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr } else if (index < 0) { 3139136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr return NO_ERROR; 3140598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch } 31411f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr 3142c665702cea06c5c42360b7f66fed1693127e6680Chia-I Wu layer->onRemovedFromCurrentState(); 31431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mLayersPendingRemoval.add(layer); 31441f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mLayersRemoved = true; 314598f1c108b016dda77c808f3d099e7a45bdd70768Chia-I Wu mNumLayers -= 1 + layer->getChildrenCount(); 31461f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr setTransactionFlags(eTransactionNeeded); 31471f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr return NO_ERROR; 3148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3150c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglarduint32_t SurfaceFlinger::peekTransactionFlags() { 3151dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian return android_atomic_release_load(&mTransactionFlags); 3152dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian} 3153dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian 31543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { 3155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 3156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { 31592713c30843816d3511b39b85a2c268a2b7682047Dan Stoza return setTransactionFlags(flags, VSyncModulator::TransactionStart::NORMAL); 31602713c30843816d3511b39b85a2c268a2b7682047Dan Stoza} 31612713c30843816d3511b39b85a2c268a2b7682047Dan Stoza 31622713c30843816d3511b39b85a2c268a2b7682047Dan Stozauint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, 31632713c30843816d3511b39b85a2c268a2b7682047Dan Stoza VSyncModulator::TransactionStart transactionStart) { 3164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t old = android_atomic_or(flags, &mTransactionFlags); 31652713c30843816d3511b39b85a2c268a2b7682047Dan Stoza mVsyncModulator.setTransactionStart(transactionStart); 3166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((old & flags)==0) { // wake the server up 316799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 3168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return old; 3170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3172ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviwbool SurfaceFlinger::containsAnyInvalidClientState(const Vector<ComposerState>& states) { 3173ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw for (const ComposerState& state : states) { 3174ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw // Here we need to check that the interface we're given is indeed 3175ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw // one of our own. A malicious client could give us a nullptr 3176ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw // IInterface, or one of its own or even one of our own but a 3177ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw // different type. All these situations would cause us to crash. 3178ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw if (state.client == nullptr) { 3179ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw return true; 3180ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw } 3181ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 3182ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw sp<IBinder> binder = IInterface::asBinder(state.client); 3183ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw if (binder == nullptr) { 3184ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw return true; 3185ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw } 3186ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 3187ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) == nullptr) { 3188ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw return true; 3189ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw } 3190ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw } 3191ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw return false; 3192ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw} 3193ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 31948b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState( 3195ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw const Vector<ComposerState>& states, 31968b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian const Vector<DisplayState>& displays, 31978b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian uint32_t flags) 31988b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{ 31997c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ATRACE_CALL(); 3200698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian Mutex::Autolock _l(mStateLock); 320128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis uint32_t transactionFlags = 0; 3202e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 3203ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw if (containsAnyInvalidClientState(states)) { 3204ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw return; 3205ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw } 3206ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 32072d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 32082d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // For window updates that are part of an animation we must wait for 32092d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // previous animation "frames" to be handled. 32102d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mAnimTransactionPending) { 32117c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 32122d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (CC_UNLIKELY(err != NO_ERROR)) { 32132d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis // just in case something goes wrong in SF, return to the 32147c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis // caller after a few seconds. 32157c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out " 32167c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis "waiting for previous animation frame"); 32172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = false; 32182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis break; 32192d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 32202d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 32212d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 32222d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis 3223ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw for (const DisplayState& display : displays) { 3224ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw transactionFlags |= setDisplayStateLocked(display); 3225b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis } 3226b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis 3227ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw for (const ComposerState& state : states) { 3228ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw transactionFlags |= setClientStateLocked(state); 3229ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw } 3230ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 3231ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw // Iterate through all layers again to determine if any need to be destroyed. Marking layers 3232ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw // as destroyed should only occur after setting all other states. This is to allow for a 3233ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw // child re-parent to happen before marking its original parent as destroyed (which would 3234ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw // then mark the child as destroyed). 3235ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw for (const ComposerState& state : states) { 3236ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw setDestroyStateLocked(state); 3237698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian } 3238386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian 3239bdcf09c4984d47e30e34ff0d3cb1b797ba7fd778Jorim Jaggi // If a synchronous transaction is explicitly requested without any changes, force a transaction 3240bdcf09c4984d47e30e34ff0d3cb1b797ba7fd778Jorim Jaggi // anyway. This can be used as a flush mechanism for previous async transactions. 3241bdcf09c4984d47e30e34ff0d3cb1b797ba7fd778Jorim Jaggi // Empty animation transaction can be used to simulate back-pressure, so also force a 3242bdcf09c4984d47e30e34ff0d3cb1b797ba7fd778Jorim Jaggi // transaction for empty animation transactions. 3243bdcf09c4984d47e30e34ff0d3cb1b797ba7fd778Jorim Jaggi if (transactionFlags == 0 && 3244bdcf09c4984d47e30e34ff0d3cb1b797ba7fd778Jorim Jaggi ((flags & eSynchronous) || (flags & eAnimation))) { 32452a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr transactionFlags = eTransactionNeeded; 32462a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr } 32472a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr 324828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis if (transactionFlags) { 32494d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique if (mInterceptor->isEnabled()) { 32504d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->saveTransaction(states, mCurrentState.displays, displays, flags); 3251ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 3252468051e20be19130572231266db306396a56402bIrvel 3253386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // this triggers the transaction 32542713c30843816d3511b39b85a2c268a2b7682047Dan Stoza const auto start = (flags & eEarlyWakeup) 32552713c30843816d3511b39b85a2c268a2b7682047Dan Stoza ? VSyncModulator::TransactionStart::EARLY 32562713c30843816d3511b39b85a2c268a2b7682047Dan Stoza : VSyncModulator::TransactionStart::NORMAL; 32572713c30843816d3511b39b85a2c268a2b7682047Dan Stoza setTransactionFlags(transactionFlags, start); 3258698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian 3259386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // if this is a synchronous transaction, wait for it to take effect 3260386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // before returning. 3261386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (flags & eSynchronous) { 32622d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = true; 32632d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis } 32642d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis if (flags & eAnimation) { 32652d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mAnimTransactionPending = true; 3266386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 32672d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis while (mTransactionPending) { 3268386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 3269386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian if (CC_UNLIKELY(err != NO_ERROR)) { 3270386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // just in case something goes wrong in SF, return to the 3271386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian // called after a few seconds. 32722d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); 32732d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis mTransactionPending = false; 3274386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian break; 3275386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian } 3276cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 3277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3280e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 3281e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{ 32829a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 32839a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall if (dpyIdx < 0) 32849a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall return 0; 32859a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall 3286e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian uint32_t flags = 0; 32879a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 32883ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian if (disp.isValid()) { 3289e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian const uint32_t what = s.what; 3290e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eSurfaceChanged) { 3291097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) { 3292e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.surface = s.surface; 3293e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 3294e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 3295e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 3296e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (what & DisplayState::eLayerStackChanged) { 3297e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.layerStack != s.layerStack) { 3298e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.layerStack = s.layerStack; 3299e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 3300e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 3301e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 330200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian if (what & DisplayState::eDisplayProjectionChanged) { 3303e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.orientation != s.orientation) { 3304e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.orientation = s.orientation; 3305e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 3306e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 3307e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.frame != s.frame) { 3308e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.frame = s.frame; 3309e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 3310e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 3311e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian if (disp.viewport != s.viewport) { 3312e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian disp.viewport = s.viewport; 3313e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eDisplayTransactionNeeded; 3314e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 3315e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 331647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (what & DisplayState::eDisplaySizeChanged) { 331747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.width != s.width) { 331847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.width = s.width; 331947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 332047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 332147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine if (disp.height != s.height) { 332247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine disp.height = s.height; 332347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine flags |= eDisplayTransactionNeeded; 332447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 332547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine } 3326e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 3327e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 3328e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 3329e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 3330ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviwuint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState) { 3331ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw const layer_state_t& s = composerState.state; 3332ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw sp<Client> client(static_cast<Client*>(composerState.client.get())); 3333ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 333413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(client->getLayerUser(s.surface)); 33358b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer == nullptr) { 33368b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw return 0; 33378b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 33388b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw 33398b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->isPendingRemoval()) { 33408b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw ALOGW("Attempting to set client state on removed layer: %s", layer->getName().string()); 33418b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw return 0; 33428b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 33438b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw 33448b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw uint32_t flags = 0; 33458b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw 33468b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw const uint32_t what = s.what; 33478b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw bool geometryAppliesWithResize = 33488b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw what & layer_state_t::eGeometryAppliesWithResize; 3349dba3273a27fb90f19a73abe7142790ad21387484Jorim Jaggi 3350dba3273a27fb90f19a73abe7142790ad21387484Jorim Jaggi // If we are deferring transaction, make sure to push the pending state, as otherwise the 3351dba3273a27fb90f19a73abe7142790ad21387484Jorim Jaggi // pending state will also be deferred. 3352dba3273a27fb90f19a73abe7142790ad21387484Jorim Jaggi if (what & layer_state_t::eDeferTransaction) { 3353dba3273a27fb90f19a73abe7142790ad21387484Jorim Jaggi layer->pushPendingState(); 3354dba3273a27fb90f19a73abe7142790ad21387484Jorim Jaggi } 3355dba3273a27fb90f19a73abe7142790ad21387484Jorim Jaggi 33568b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::ePositionChanged) { 33578b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) { 33588b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTraversalNeeded; 3359acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos } 33608b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 33618b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eLayerChanged) { 33628b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw // NOTE: index needs to be calculated before we update the state 33638b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw const auto& p = layer->getParent(); 33648b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (p == nullptr) { 3365e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 33668b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setLayer(s.z) && idx >= 0) { 3367e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.removeAt(idx); 3368e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian mCurrentState.layersSortedByZ.add(layer); 3369e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // we need traversal (state changed) 3370e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian // AND transaction (list changed) 3371e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian flags |= eTransactionNeeded|eTraversalNeeded; 3372e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 33738b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } else { 33748b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (p->setChildLayer(layer, s.z)) { 33750617894190ea0c3ee50889bee1d4df0f369b0761chaviw flags |= eTransactionNeeded|eTraversalNeeded; 33760617894190ea0c3ee50889bee1d4df0f369b0761chaviw } 33770617894190ea0c3ee50889bee1d4df0f369b0761chaviw } 33788b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 33798b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eRelativeLayerChanged) { 3380503c7046237f2797a5cf8584064223359d0e6d10Robert Carr // NOTE: index needs to be calculated before we update the state 3381503c7046237f2797a5cf8584064223359d0e6d10Robert Carr const auto& p = layer->getParent(); 3382503c7046237f2797a5cf8584064223359d0e6d10Robert Carr if (p == nullptr) { 3383503c7046237f2797a5cf8584064223359d0e6d10Robert Carr ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 3384503c7046237f2797a5cf8584064223359d0e6d10Robert Carr if (layer->setRelativeLayer(s.relativeLayerHandle, s.z) && idx >= 0) { 3385503c7046237f2797a5cf8584064223359d0e6d10Robert Carr mCurrentState.layersSortedByZ.removeAt(idx); 3386503c7046237f2797a5cf8584064223359d0e6d10Robert Carr mCurrentState.layersSortedByZ.add(layer); 3387503c7046237f2797a5cf8584064223359d0e6d10Robert Carr // we need traversal (state changed) 3388503c7046237f2797a5cf8584064223359d0e6d10Robert Carr // AND transaction (list changed) 3389503c7046237f2797a5cf8584064223359d0e6d10Robert Carr flags |= eTransactionNeeded|eTraversalNeeded; 3390503c7046237f2797a5cf8584064223359d0e6d10Robert Carr } 3391503c7046237f2797a5cf8584064223359d0e6d10Robert Carr } else { 3392503c7046237f2797a5cf8584064223359d0e6d10Robert Carr if (p->setChildRelativeLayer(layer, s.relativeLayerHandle, s.z)) { 3393503c7046237f2797a5cf8584064223359d0e6d10Robert Carr flags |= eTransactionNeeded|eTraversalNeeded; 3394503c7046237f2797a5cf8584064223359d0e6d10Robert Carr } 33958b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 33968b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 33978b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eSizeChanged) { 33988b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setSize(s.w, s.h)) { 33998b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTraversalNeeded; 34008b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34018b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34028b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eAlphaChanged) { 34038b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setAlpha(s.alpha)) 34048b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTraversalNeeded; 34058b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34068b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eColorChanged) { 34078b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setColor(s.color)) 34088b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTraversalNeeded; 34098b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34108b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eMatrixChanged) { 34118b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setMatrix(s.matrix)) 34128b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTraversalNeeded; 34138b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34148b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eTransparentRegionChanged) { 34158b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setTransparentRegionHint(s.transparentRegion)) 34168b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTraversalNeeded; 34178b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34188b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eFlagsChanged) { 34198b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setFlags(s.flags, s.mask)) 34208b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTraversalNeeded; 34218b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34228b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eCropChanged) { 34238b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setCrop(s.crop, !geometryAppliesWithResize)) 34248b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTraversalNeeded; 34258b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34268b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eFinalCropChanged) { 34278b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->setFinalCrop(s.finalCrop, !geometryAppliesWithResize)) 34288b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTraversalNeeded; 34298b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34308b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eLayerStackChanged) { 34318b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 34328b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw // We only allow setting layer stacks for top level layers, 34338b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw // everything else inherits layer stack from its parent. 34348b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->hasParent()) { 34358b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid", 34368b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw layer->getName().string()); 34378b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } else if (idx < 0) { 34388b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw ALOGE("Attempt to set layer stack on layer without parent (%s) that " 34398b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw "that also does not appear in the top level layer list. Something" 34408b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw " has gone wrong.", layer->getName().string()); 34418b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } else if (layer->setLayerStack(s.layerStack)) { 34428b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw mCurrentState.layersSortedByZ.removeAt(idx); 34438b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw mCurrentState.layersSortedByZ.add(layer); 34448b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw // we need traversal (state changed) 34458b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw // AND transaction (list changed) 3446d432a7c40dfa6c5498038ec652db54478df966c1Lloyd Pique flags |= eTransactionNeeded|eTraversalNeeded|eDisplayLayerStackChanged; 34478b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34488b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34498b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eDeferTransaction) { 34508b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (s.barrierHandle != nullptr) { 34518b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw layer->deferTransactionUntil(s.barrierHandle, s.frameNumber); 34528b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } else if (s.barrierGbp != nullptr) { 34538b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw const sp<IGraphicBufferProducer>& gbp = s.barrierGbp; 34548b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (authenticateSurfaceTextureLocked(gbp)) { 34558b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw const auto& otherLayer = 34568b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw (static_cast<MonitoredProducer*>(gbp.get()))->getLayer(); 34578b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw layer->deferTransactionUntil(otherLayer, s.frameNumber); 34588b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } else { 34598b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw ALOGE("Attempt to defer transaction to to an" 34608b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw " unrecognized GraphicBufferProducer"); 34611db73f66624e7d151710483dd58e03eed672f064Robert Carr } 34621db73f66624e7d151710483dd58e03eed672f064Robert Carr } 34638b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw // We don't trigger a traversal here because if no other state is 34648b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw // changed, we don't want this to cause any more work 34658b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34668b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eReparent) { 34678ea97bbe9b5097feaa76926c6ac49120e0fc3649chaviw bool hadParent = layer->hasParent(); 34688b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->reparent(s.parentHandleForChild)) { 34698ea97bbe9b5097feaa76926c6ac49120e0fc3649chaviw if (!hadParent) { 34708ea97bbe9b5097feaa76926c6ac49120e0fc3649chaviw mCurrentState.layersSortedByZ.remove(layer); 34718ea97bbe9b5097feaa76926c6ac49120e0fc3649chaviw } 34728b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTransactionNeeded|eTraversalNeeded; 34739524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr } 34748b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34758b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eReparentChildren) { 34768b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (layer->reparentChildren(s.reparentHandle)) { 34778b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw flags |= eTransactionNeeded|eTraversalNeeded; 3478c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr } 3479e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian } 34808b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eDetachChildren) { 34818b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw layer->detachChildren(); 34828b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 34838b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw if (what & layer_state_t::eOverrideScalingModeChanged) { 34848b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw layer->setOverrideScalingMode(s.overrideScalingMode); 34858b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw // We don't trigger a traversal here because if no other state is 34868b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw // changed, we don't want this to cause any more work 34878b3871addb9bbd5776f4ed59e67af2baa9c583fdchaviw } 3488e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian return flags; 3489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian} 3490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian 3491ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviwvoid SurfaceFlinger::setDestroyStateLocked(const ComposerState& composerState) { 3492ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw const layer_state_t& state = composerState.state; 3493ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw sp<Client> client(static_cast<Client*>(composerState.client.get())); 3494ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 3495ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw sp<Layer> layer(client->getLayerUser(state.surface)); 3496ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw if (layer == nullptr) { 3497ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw return; 3498ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw } 3499ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 3500ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw if (layer->isPendingRemoval()) { 3501ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw ALOGW("Attempting to destroy on removed layer: %s", layer->getName().string()); 3502ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw return; 3503ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw } 3504ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 3505ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw if (state.what & layer_state_t::eDestroySurface) { 3506ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw removeLayerLocked(mStateLock, layer); 3507ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw } 3508ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw} 3509ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7chaviw 35104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer( 35110ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const String8& name, 35120ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian const sp<Client>& client, 35134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 3514ccd348460ca25890a8fb709e82e6f780e3ce878erongliu int32_t windowType, int32_t ownerUid, sp<IBinder>* handle, 3515479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent) 3516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 35176e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian if (int32_t(w|h) < 0) { 3518921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 35196e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian int(w), int(h)); 35204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return BAD_VALUE; 35216e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian } 35228b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber 35234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result = NO_ERROR; 35244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 35254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<Layer> layer; 35264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 3527bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop String8 uniqueName = getUniqueLayerName(name); 3528bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 35293165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 35303165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian case ISurfaceComposerClient::eFXSurfaceNormal: 35310c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman result = createBufferLayer(client, 3532bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop uniqueName, w, h, flags, format, 35334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp, &layer); 35340c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman 3535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 353613fdc49516d17f41e64e62e73c313b0928bf13ccchaviw case ISurfaceComposerClient::eFXSurfaceColor: 353713fdc49516d17f41e64e62e73c313b0928bf13ccchaviw result = createColorLayer(client, 3538bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop uniqueName, w, h, flags, 35390c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman handle, &layer); 35404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian break; 35414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian default: 35424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = BAD_VALUE; 3543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 3544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 35467d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 35477d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 3548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 35497d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 3550ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu // window type is WINDOW_TYPE_DONT_SCREENSHOT from SurfaceControl.java 3551ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu // TODO b/64227542 3552ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu if (windowType == 441731) { 3553ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu windowType = 2024; // TYPE_NAVIGATION_BAR_PANEL 3554ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu layer->setPrimaryDisplayOnly(); 3555ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu } 3556ab0c319824632c463ea624cee6f0bc3c8cd8a779Chia-I Wu 3557479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk layer->setInfo(windowType, ownerUid); 3558479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk 35591f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr result = addClientLayer(client, *handle, *gbp, layer, *parent); 35607d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza if (result != NO_ERROR) { 35617d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza return result; 35627d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza } 35634d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->saveSurfaceCreation(layer); 35647d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza 35657d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza setTransactionFlags(eTransactionNeeded); 35664d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return result; 3567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3569bc7552874052ee33f1b35b4474e20c003d216391Cody NorthropString8 SurfaceFlinger::getUniqueLayerName(const String8& name) 3570bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop{ 3571bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop bool matchFound = true; 3572bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop uint32_t dupeCounter = 0; 3573bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 3574bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop // Tack on our counter whether there is a hit or not, so everyone gets a tag 3575bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop String8 uniqueName = name + "#" + String8(std::to_string(dupeCounter).c_str()); 3576bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 3577bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop // Loop over layers until we're sure there is no matching name 3578bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop while (matchFound) { 3579bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop matchFound = false; 3580bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop mDrawingState.traverseInZOrder([&](Layer* layer) { 3581bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop if (layer->getName() == uniqueName) { 3582bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop matchFound = true; 3583bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop uniqueName = name + "#" + String8(std::to_string(++dupeCounter).c_str()); 3584bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop } 3585bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop }); 3586bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop } 3587bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 3588bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop ALOGD_IF(dupeCounter > 0, "duplicate layer name: changing %s to %s", name.c_str(), uniqueName.c_str()); 3589bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 3590bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop return uniqueName; 3591bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop} 3592bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop 35930c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodmanstatus_t SurfaceFlinger::createBufferLayer(const sp<Client>& client, 35944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, 35954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) 3596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // initialize the surfaces 359892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian switch (format) { 3599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSPARENT: 3600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_TRANSLUCENT: 3601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_RGBA_8888; 3602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 3603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case PIXEL_FORMAT_OPAQUE: 36048f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian format = PIXEL_FORMAT_RGBX_8888; 3605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 3606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 36080c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman sp<BufferLayer> layer = new BufferLayer(this, client, name, w, h, flags); 36090c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman status_t err = layer->setBuffers(w, h, format, flags); 36104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian if (err == NO_ERROR) { 36110c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman *handle = layer->getHandle(); 36120c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman *gbp = layer->getProducer(); 36130c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman *outLayer = layer; 3614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 36154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian 36160c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman ALOGE_IF(err, "createBufferLayer() failed (%s)", strerror(-err)); 36174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return err; 3618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 362013fdc49516d17f41e64e62e73c313b0928bf13ccchaviwstatus_t SurfaceFlinger::createColorLayer(const sp<Client>& client, 36214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian const String8& name, uint32_t w, uint32_t h, uint32_t flags, 36220c69cad13dda09f1df1dbf23810b1c5b7f28ba08David Sodman sp<IBinder>* handle, sp<Layer>* outLayer) 3623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 362413fdc49516d17f41e64e62e73c313b0928bf13ccchaviw *outLayer = new ColorLayer(this, client, name, w, h, flags); 36254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian *handle = (*outLayer)->getHandle(); 36264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian return NO_ERROR; 3627118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 3628118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 3629ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) 36309a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 36319524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr // called by a client when it wants to remove a Layer 36326710604286401d4205c27235a252dd0e5008cc08Mathias Agopian status_t err = NO_ERROR; 36336710604286401d4205c27235a252dd0e5008cc08Mathias Agopian sp<Layer> l(client->getLayerUser(handle)); 3634566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (l != nullptr) { 36354d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->saveSurfaceDeletion(l); 36366710604286401d4205c27235a252dd0e5008cc08Mathias Agopian err = removeLayer(l); 36376710604286401d4205c27235a252dd0e5008cc08Mathias Agopian ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 36386710604286401d4205c27235a252dd0e5008cc08Mathias Agopian "error removing layer=%p (%s)", l.get(), strerror(-err)); 36399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 36409a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return err; 36419a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian} 36429a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 364313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) 3644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 36456710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // called by ~LayerCleaner() when all references to the IBinder (handle) 36466710604286401d4205c27235a252dd0e5008cc08Mathias Agopian // are gone 36479524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr sp<Layer> l = layer.promote(); 36489524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr if (l == nullptr) { 36499524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr // The layer has already been removed, carry on 36509524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr return NO_ERROR; 36519524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr } 3652515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu // If we have a parent, then we can continue to live as long as it does. 3653515dc9c538b8206b746eeb4906ac0b8aed1fb497Chia-I Wu return removeLayer(l, true); 3654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3656b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 3657b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 365813a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() { 365901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall // reset screen orientation and use primary layer stack 366013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<ComposerState> state; 366113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden Vector<DisplayState> displays; 366213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden DisplayState d; 366301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.what = DisplayState::eDisplayProjectionChanged | 366401e29054e672301e4adbbca15b3562a59a20f267Jesse Hall DisplayState::eLayerStackChanged; 3665692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; 366601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall d.layerStack = 0; 366713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden d.orientation = DisplayState::eOrientationDefault; 36684c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.frame.makeInvalid(); 36694c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown d.viewport.makeInvalid(); 367047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.width = 0; 367147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine d.height = 0; 367213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden displays.add(d); 367313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden setTransactionState(state, displays, 0); 3674b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL, 3675b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas /*stateLockHeld*/ false); 36766547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 3677105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 36789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 36796547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.setDisplayRefreshPeriod(period); 36800a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson 3681d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson // Use phase of 0 since phase is not known. 3682d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson // Use latency of 0, which will snap to the ideal latency. 3683d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson setCompositorTimingSnapped(0, period, 0); 368413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 368513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 368613a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() { 368713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden class MessageScreenInitialized : public MessageBase { 368813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden SurfaceFlinger* flinger; 368913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden public: 3690c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 369113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden virtual bool handler() { 369213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden flinger->onInitializeDisplays(); 369313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden return true; 369413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden } 369513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden }; 369613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden sp<MessageBase> msg = new MessageScreenInitialized(this); 369713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden postMessageAsync(msg); // we may be called from main thread, use async message 369813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden} 369913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 37002c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, 3701b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas int mode, bool stateLockHeld) { 37022c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(), 37032c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani this); 37042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int32_t type = hw->getDisplayType(); 37052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int currentMode = hw->getPowerMode(); 370613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden 37072c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (mode == currentMode) { 3708c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden return; 3709c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 3710c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 37112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani hw->setPowerMode(mode); 37122c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { 37132c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Trying to set power mode for virtual display"); 37142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani return; 37152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } 3716c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 37174d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique if (mInterceptor->isEnabled()) { 3718b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas ConditionalLock lock(mStateLock, !stateLockHeld); 3719ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken()); 3720ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel if (idx < 0) { 3721ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel ALOGW("Surface Interceptor SavePowerMode: invalid display token"); 3722ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel return; 3723ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 37244d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode); 3725ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel } 3726ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel 37272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani if (currentMode == HWC_POWER_MODE_OFF) { 3728f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn on the display 37292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 373038d4961eb2c64288a6be252fdce9c40a133e45bdMatthew Bouyack if (type == DisplayDevice::DISPLAY_PRIMARY && 373138d4961eb2c64288a6be252fdce9c40a133e45bdMatthew Bouyack mode != HWC_POWER_MODE_DOZE_SUSPEND) { 3732c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden // FIXME: eventthread only knows about the main display right now 3733c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden mEventThread->onScreenAcquired(); 3734948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall resyncToHardwareVsync(true); 3735c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden } 3736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 37372c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 3738b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza mHasPoweredOff = true; 3739c7a25adf66b138de66814383540905b83cf12a01Dan Stoza repaintEverything(); 3740f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 3741f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 3742f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray param.sched_priority = 1; 3743f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) { 3744f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_FIFO on display on"); 3745f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 37462c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else if (mode == HWC_POWER_MODE_OFF) { 3747f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray // Turn off the display 3748f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray struct sched_param param = {0}; 3749f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray if (sched_setscheduler(0, SCHED_OTHER, ¶m) != 0) { 3750f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray ALOGW("Couldn't set SCHED_OTHER on display off"); 3751f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray } 3752f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray 3753cd9b55c70f081dbd004d347b51a793ce6fe3cacfMatthew Bouyack if (type == DisplayDevice::DISPLAY_PRIMARY && 3754cd9b55c70f081dbd004d347b51a793ce6fe3cacfMatthew Bouyack currentMode != HWC_POWER_MODE_DOZE_SUSPEND) { 3755948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall disableHardwareVsync(true); // also cancels any in-progress resync 3756948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall 3757cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian // FIXME: eventthread only knows about the main display right now 3758cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian mEventThread->onScreenReleased(); 3759cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian } 3760c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden 37612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 37622c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mVisibleRegionsDirty = true; 37632c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani // from this point on, SF will stop drawing on this display 376438d4961eb2c64288a6be252fdce9c40a133e45bdMatthew Bouyack } else if (mode == HWC_POWER_MODE_DOZE || 376538d4961eb2c64288a6be252fdce9c40a133e45bdMatthew Bouyack mode == HWC_POWER_MODE_NORMAL) { 37668a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang // Update display while dozing 37678a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang getHwComposer().setPowerMode(type, mode); 3768cd9b55c70f081dbd004d347b51a793ce6fe3cacfMatthew Bouyack if (type == DisplayDevice::DISPLAY_PRIMARY && 3769cd9b55c70f081dbd004d347b51a793ce6fe3cacfMatthew Bouyack currentMode == HWC_POWER_MODE_DOZE_SUSPEND) { 37708a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang // FIXME: eventthread only knows about the main display right now 37718a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang mEventThread->onScreenAcquired(); 37728a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang resyncToHardwareVsync(true); 37738a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang } 37748a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang } else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) { 37758a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang // Leave display going to doze 37768a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang if (type == DisplayDevice::DISPLAY_PRIMARY) { 37778a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang disableHardwareVsync(true); // also cancels any in-progress resync 37788a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang // FIXME: eventthread only knows about the main display right now 37798a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang mEventThread->onScreenReleased(); 37808a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang } 37818a43fe6af02580b52d7f0b3947b40a9942f7fb86Zheng Zhang getHwComposer().setPowerMode(type, mode); 37822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani } else { 378338d4961eb2c64288a6be252fdce9c40a133e45bdMatthew Bouyack ALOGE("Attempting to set unknown power mode: %d\n", mode); 37842c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani getHwComposer().setPowerMode(type, mode); 3785b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 378605ee4c93fb050fc17b61396ab9ec17bfd7e122b4Alice Sheng ALOGD("Finished set power mode=%d, type=%d", mode, hw->getDisplayType()); 3787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 3788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 37892c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) { 37902c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani class MessageSetPowerMode: public MessageBase { 3791db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian SurfaceFlinger& mFlinger; 3792db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian sp<IBinder> mDisplay; 37932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani int mMode; 3794b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian public: 37952c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani MessageSetPowerMode(SurfaceFlinger& flinger, 37962c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani const sp<IBinder>& disp, int mode) : mFlinger(flinger), 37972c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mDisplay(disp) { mMode = mode; } 3798b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian virtual bool handler() { 37992c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay)); 3800566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (hw == nullptr) { 38012c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGE("Attempt to set power mode = %d for null display %p", 38027306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine mMode, mDisplay.get()); 38039e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { 38042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani ALOGW("Attempt to set power mode = %d for virtual display", 38052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani mMode); 3806db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } else { 3807b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas mFlinger.setPowerModeInternal( 3808b02664ddc146893e6bbe7939ee2b948d54e7166aSteven Thomas hw, mMode, /*stateLockHeld*/ false); 3809db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian } 3810b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian return true; 3811b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian } 3812b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian }; 38132c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode); 3814db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian postMessageSync(msg); 3815b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian} 3816b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 3817b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// --------------------------------------------------------------------------- 3818b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian 3819755e319d6a656dc92bd4f2b486d8f5a44b0e7350Lloyd Piquestatus_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args, bool asProto) 3820755e319d6a656dc92bd4f2b486d8f5a44b0e7350Lloyd Pique NO_THREAD_SAFETY_ANALYSIS { 3821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 result; 382299b49840d309727678b77403d6cc9f920111623fMathias Agopian 3823bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 3824bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int pid = ipc->getCallingPid(); 3825bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian const int uid = ipc->getCallingUid(); 38266a40853e06f5274d84b0fc66e349a36510d1497fVishnu Nair 3827bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian if ((uid != AID_SHELL) && 3828bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian !PermissionCache::checkPermission(sDump, pid, uid)) { 382974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("Permission Denial: " 3830bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); 3831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 3832fcd15b478c20f579388bb1368f05098dca534639Jesse Hall // Try to get the main lock, but give up after one second 38339795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // (this would indicate SF is stuck, but we want to be able to 38349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian // print something in dumpsys). 3835fcd15b478c20f579388bb1368f05098dca534639Jesse Hall status_t err = mStateLock.timedLock(s2ns(1)); 3836fcd15b478c20f579388bb1368f05098dca534639Jesse Hall bool locked = (err == NO_ERROR); 38379795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian if (!locked) { 3838fcd15b478c20f579388bb1368f05098dca534639Jesse Hall result.appendFormat( 3839fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "SurfaceFlinger appears to be unresponsive (%s [%d]), " 3840fcd15b478c20f579388bb1368f05098dca534639Jesse Hall "dumping anyways (no locks held)\n", strerror(-err), err); 38419795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian } 38429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 384382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian bool dumpAll = true; 384482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian size_t index = 0; 384525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian size_t numArgs = args.size(); 3846a3d7bd39d130ec2e711692d045a435657c4bc0aachaviw 384725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (numArgs) { 384825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 384925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--list"))) { 385025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 385174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian listLayersLocked(args, index, result); 385235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 385325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 385425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 385525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 385625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency"))) { 385782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 385874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian dumpStatsLocked(args, index, result); 385935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 386082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 386125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 386225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if ((index < numArgs) && 386325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian (args[index] == String16("--latency-clear"))) { 386425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 386574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian clearStatsLocked(args, index, result); 386635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian dumpAll = false; 386725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 3868c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden 3869c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden if ((index < numArgs) && 3870c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden (args[index] == String16("--dispsync"))) { 3871c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden index++; 3872c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden mPrimaryDispSync.dump(result); 3873c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden dumpAll = false; 3874c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden } 3875b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 3876b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza if ((index < numArgs) && 3877b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza (args[index] == String16("--static-screen"))) { 3878b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza index++; 3879b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 3880b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpAll = false; 3881b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 388240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos 388340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos if ((index < numArgs) && 3884d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson (args[index] == String16("--frame-events"))) { 388540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos index++; 3886d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson dumpFrameEventsLocked(result); 388740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos dumpAll = false; 388840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos } 3889f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 3890f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter if ((index < numArgs) && (args[index] == String16("--wide-color"))) { 3891f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter index++; 3892f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter dumpWideColorInfo(result); 3893f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter dumpAll = false; 3894f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter } 3895068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang 3896068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang if ((index < numArgs) && 3897068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang (args[index] == String16("--enable-layer-stats"))) { 3898068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang index++; 3899068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang mLayerStats.enable(); 3900068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang dumpAll = false; 3901068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang } 3902068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang 3903068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang if ((index < numArgs) && 3904068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang (args[index] == String16("--disable-layer-stats"))) { 3905068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang index++; 3906068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang mLayerStats.disable(); 3907068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang dumpAll = false; 3908068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang } 3909068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang 3910068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang if ((index < numArgs) && 3911068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang (args[index] == String16("--clear-layer-stats"))) { 3912068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang index++; 3913068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang mLayerStats.clear(); 3914068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang dumpAll = false; 3915068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang } 3916068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang 3917068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang if ((index < numArgs) && 3918068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang (args[index] == String16("--dump-layer-stats"))) { 3919068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang index++; 3920068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang mLayerStats.dump(result); 3921068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang dumpAll = false; 3922068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang } 39230102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang 39240102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang if ((index < numArgs) && (args[index] == String16("--timestats"))) { 39250102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang index++; 39260102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang mTimeStats.parseArgs(asProto, args, index, result); 39270102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang dumpAll = false; 39280102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang } 3929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 39301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 393182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (dumpAll) { 39320102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang if (asProto) { 39330102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current); 39340102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang result.append(layersProto.SerializeAsString().c_str(), layersProto.ByteSize()); 39350102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang } else { 39360102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang dumpAllLocked(args, index, result); 39370102ad2d522de255efabd50adf6c6a27811344f4Yiwei Zhang } 393882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 393948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 394082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (locked) { 394182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mStateLock.unlock(); 394248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian } 394382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 394482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian write(fd, result.string(), result.size()); 394582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian return NO_ERROR; 394682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 394748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 3948c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */, 3949c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza size_t& /* index */, String8& result) const 395025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 39512047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 395274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat("%s\n", layer->getName().string()); 39532047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 395425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 395525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 395682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 395774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 395882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 395982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian String8 name; 396082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian if (index < args.size()) { 396182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian name = String8(args[index]); 396282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian index++; 396382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 396448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian 3965105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 39669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza const nsecs_t period = activeConfig->getVsyncPeriod(); 396786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("%" PRId64 "\n", period); 39684b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 39694b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name.isEmpty()) { 3970d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.dumpStats(result); 39714b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } else { 39722047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 39734b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis if (name == layer->getName()) { 3974d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->dumpFrameStats(result); 39754b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis } 39762047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 397782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian } 397882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian} 3979ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian 398025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 3981c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza String8& /* result */) 398225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{ 398325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian String8 name; 398425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (index < args.size()) { 398525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian name = String8(args[index]); 398625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian index++; 398725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 398825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 39892047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 399025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian if (name.isEmpty() || (name == layer->getName())) { 3991d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 399225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian } 39932047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 39944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis 3995d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav mAnimFrameTracker.clearStats(); 399625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian} 399725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian 39986547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread. Otherwise it would need 39996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState. 40006547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() { 40012047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr mDrawingState.traverseInZOrder([&](Layer* layer) { 40026547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis layer->logFrameStats(); 40032047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr }); 40046547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 40056547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis mAnimFrameTracker.logAndResetStats(String8("<win-anim>")); 40066547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis} 40076547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis 400863a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglardvoid SurfaceFlinger::appendSfConfigString(String8& result) const 40094803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{ 401063a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append(" [sf"); 4011c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard 401263a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard if (isLayerTripleBufferingDisabled()) 401363a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append(" DISABLE_TRIPLE_BUFFERING"); 4014c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard 4015c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard result.appendFormat(" PRESENT_TIME_OFFSET=%" PRId64 , dispSyncPresentTimeOffset); 4016a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard result.appendFormat(" FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv); 4017c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard result.appendFormat(" MAX_VIRT_DISPLAY_DIM=%" PRIu64, maxVirtualDisplaySize); 4018cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard result.appendFormat(" RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework); 40191971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard result.appendFormat(" NUM_FRAMEBUFFER_SURFACE_BUFFERS=%" PRId64, 40201971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard maxFrameBufferAcquiredBuffers); 402163a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard result.append("]"); 40224803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden} 40234803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 4024b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const 4025b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{ 4026b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat("Static screen stats:\n"); 40274a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman for (size_t b = 0; b < SurfaceFlingerBE::NUM_BUCKETS - 1; ++b) { 40284a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman float bucketTimeSec = getBE().mFrameBuckets[b] / 1e9; 4029b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 40304a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman static_cast<float>(getBE().mFrameBuckets[b]) / getBE().mTotalTime; 4031b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" < %zd frames: %.3f s (%.1f%%)\n", 4032b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza b + 1, bucketTimeSec, percent); 4033b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza } 40344a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman float bucketTimeSec = getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1] / 1e9; 4035b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza float percent = 100.0f * 40364a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman static_cast<float>(getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1]) / getBE().mTotalTime; 4037b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.appendFormat(" %zd+ frames: %.3f s (%.1f%%)\n", 40384a36e9384d10fe3a1e57599558d68e95ff51279aDavid Sodman SurfaceFlingerBE::NUM_BUCKETS - 1, bucketTimeSec, percent); 4039b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza} 4040b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 4041e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName, 4042e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::vector<OccupancyTracker::Segment>&& history) { 4043cbaf083d0a916ad4b6264d770594d44e411f4674David Sodman Mutex::Autolock lock(getBE().mBufferingStatsMutex); 4044cbaf083d0a916ad4b6264d770594d44e411f4674David Sodman auto& stats = getBE().mBufferingStats[layerName]; 4045e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& segment : history) { 4046e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (!segment.usedThirdBuffer) { 4047e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.twoBufferTime += segment.totalTime; 4048e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 4049e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (segment.occupancyAverage < 1.0f) { 4050e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime += segment.totalTime; 4051e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } else if (segment.occupancyAverage < 2.0f) { 4052e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime += segment.totalTime; 4053e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 4054e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza ++stats.numSegments; 4055e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime += segment.totalTime; 4056e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 4057e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 4058e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 4059d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::dumpFrameEventsLocked(String8& result) { 4060d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson result.appendFormat("Layer frame timestamps:\n"); 4061d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson 4062d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 4063d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson const size_t count = currentLayers.size(); 4064d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson for (size_t i=0 ; i<count ; i++) { 4065d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson currentLayers[i]->dumpFrameEvents(result); 4066d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson } 4067d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson} 4068d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson 4069e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const { 4070e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("Buffering stats:\n"); 4071e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append(" [Layer name] <Active time> <Two buffer> " 4072e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza "<Double buffered> <Triple buffered>\n"); 4073cbaf083d0a916ad4b6264d770594d44e411f4674David Sodman Mutex::Autolock lock(getBE().mBufferingStatsMutex); 4074e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza typedef std::tuple<std::string, float, float, float> BufferTuple; 4075e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::map<float, BufferTuple, std::greater<float>> sorted; 4076cbaf083d0a916ad4b6264d770594d44e411f4674David Sodman for (const auto& statsPair : getBE().mBufferingStats) { 4077e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const char* name = statsPair.first.c_str(); 4078cbaf083d0a916ad4b6264d770594d44e411f4674David Sodman const SurfaceFlingerBE::BufferingStats& stats = statsPair.second; 4079e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza if (stats.numSegments == 0) { 4080e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza continue; 4081e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 4082e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = ns2ms(stats.totalTime) / 1000.0f; 4083e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float twoBufferRatio = static_cast<float>(stats.twoBufferTime) / 4084e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.totalTime; 4085e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float doubleBufferRatio = static_cast<float>( 4086e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.doubleBufferedTime) / stats.totalTime; 4087e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float tripleBufferRatio = static_cast<float>( 4088e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza stats.tripleBufferedTime) / stats.totalTime; 4089e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza sorted.insert({activeTime, {name, twoBufferRatio, 4090e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza doubleBufferRatio, tripleBufferRatio}}); 4091e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 4092e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza for (const auto& sortedPair : sorted) { 4093e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza float activeTime = sortedPair.first; 4094e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza const BufferTuple& values = sortedPair.second; 4095e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.appendFormat(" [%s] %.2f %.3f %.3f %.3f\n", 4096e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<0>(values).c_str(), activeTime, 4097e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<1>(values), std::get<2>(values), 4098e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza std::get<3>(values)); 4099e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza } 4100e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza result.append("\n"); 4101e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza} 4102e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 4103f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchtervoid SurfaceFlinger::dumpWideColorInfo(String8& result) const { 4104f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.appendFormat("hasWideColorDisplay: %d\n", hasWideColorDisplay); 41050d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu result.appendFormat("DisplayColorSetting: %s\n", 41060d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu decodeDisplayColorSetting(mDisplayColorSetting).c_str()); 4107f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 4108f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter // TODO: print out if wide-color mode is active or not 4109f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 4110f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter for (size_t d = 0; d < mDisplays.size(); d++) { 4111f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter const sp<const DisplayDevice>& displayDevice(mDisplays[d]); 4112f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter int32_t hwcId = displayDevice->getHwcDisplayId(); 4113f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) { 4114f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter continue; 4115f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter } 4116f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 4117f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.appendFormat("Display %d color modes:\n", hwcId); 4118a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId); 4119f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter for (auto&& mode : modes) { 4120f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.appendFormat(" %s (%d)\n", decodeColorMode(mode).c_str(), mode); 4121f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter } 4122f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 4123a52f0295622a42849f5ef81c44589b816b2ccacbPeiyong Lin ColorMode currentMode = displayDevice->getActiveColorMode(); 4124f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.appendFormat(" Current color mode: %s (%d)\n", 4125f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter decodeColorMode(currentMode).c_str(), currentMode); 4126f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter } 4127f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.append("\n"); 4128f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter} 4129f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 41308e0af3679ec73e07775142825d592448b255f61cJorim JaggiLayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet) const { 41311d04428c3cff3503212ec3e76775ca5ba20abc18chaviw LayersProto layersProto; 41328e0af3679ec73e07775142825d592448b255f61cJorim Jaggi const bool useDrawing = stateSet == LayerVector::StateSet::Drawing; 41338e0af3679ec73e07775142825d592448b255f61cJorim Jaggi const State& state = useDrawing ? mDrawingState : mCurrentState; 41348e0af3679ec73e07775142825d592448b255f61cJorim Jaggi state.traverseInZOrder([&](Layer* layer) { 41351d04428c3cff3503212ec3e76775ca5ba20abc18chaviw LayerProto* layerProto = layersProto.add_layers(); 41368e0af3679ec73e07775142825d592448b255f61cJorim Jaggi layer->writeToProto(layerProto, stateSet); 41371d04428c3cff3503212ec3e76775ca5ba20abc18chaviw }); 41381d04428c3cff3503212ec3e76775ca5ba20abc18chaviw 41391d04428c3cff3503212ec3e76775ca5ba20abc18chaviw return layersProto; 41401d04428c3cff3503212ec3e76775ca5ba20abc18chaviw} 41411d04428c3cff3503212ec3e76775ca5ba20abc18chaviw 4142068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei ZhangLayersProto SurfaceFlinger::dumpVisibleLayersProtoInfo(int32_t hwcId) const { 4143068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang LayersProto layersProto; 4144068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang const sp<DisplayDevice>& displayDevice(mDisplays[hwcId]); 41457c64f17bd0d70aec63b475c3de850dcf3abaff33Yiwei Zhang 4146068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang SizeProto* resolution = layersProto.mutable_resolution(); 4147068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang resolution->set_w(displayDevice->getWidth()); 4148068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang resolution->set_h(displayDevice->getHeight()); 4149068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang 41507c64f17bd0d70aec63b475c3de850dcf3abaff33Yiwei Zhang layersProto.set_color_mode(decodeColorMode(displayDevice->getActiveColorMode())); 41517c64f17bd0d70aec63b475c3de850dcf3abaff33Yiwei Zhang layersProto.set_color_transform(decodeColorTransform(displayDevice->getColorTransform())); 41527c64f17bd0d70aec63b475c3de850dcf3abaff33Yiwei Zhang layersProto.set_global_transform( 41537c64f17bd0d70aec63b475c3de850dcf3abaff33Yiwei Zhang static_cast<int32_t>(displayDevice->getOrientationTransform())); 41547c64f17bd0d70aec63b475c3de850dcf3abaff33Yiwei Zhang 4155068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang mDrawingState.traverseInZOrder([&](Layer* layer) { 41567c64f17bd0d70aec63b475c3de850dcf3abaff33Yiwei Zhang if (!layer->visibleRegion.isEmpty() && layer->getBE().mHwcLayers.count(hwcId)) { 4157068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang LayerProto* layerProto = layersProto.add_layers(); 4158068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang layer->writeToProto(layerProto, hwcId); 4159068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang } 4160068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang }); 4161068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang 4162068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang return layersProto; 4163068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang} 4164068e31b929b40a1bc9be742c04cbdf5b04f3ce97Yiwei Zhang 416574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, 416674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian String8& result) const 416782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{ 41683e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian bool colorize = false; 41693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian if (index < args.size() 41703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian && (args[index] == String16("--color"))) { 41713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorize = true; 41723e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian index++; 41733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian } 41743e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 41753e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian Colorizer colorizer(colorize); 41763e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 417782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian // figure out if we're stuck somewhere 417882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t now = systemTime(); 417982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 418082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const nsecs_t inTransaction(mDebugInTransaction); 418182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 418282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 4183bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 418482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 41854803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden * Dump library configuration. 41864803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden */ 41873e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian 41883e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 41894803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("Build configuration:"); 41903e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 41914803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendSfConfigString(result); 41924803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendUiConfigString(result); 41934803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden appendGuiConfigString(result); 41944803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden result.append("\n"); 41954803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden 4196f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter result.append("\nWide-Color information:\n"); 4197f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter dumpWideColorInfo(result); 4198f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter 41993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 4200ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("Sync configuration: "); 42013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 4202ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append(SyncFeatures::getInstance().toString()); 4203ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian result.append("\n"); 4204ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 4205105b7dcf6b2e3e4af368cabeec275008b7e73806David Sodman const auto& activeConfig = getBE().mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY); 42069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 420741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.bold(result); 420841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("DispSync configuration: "); 420941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden colorizer.reset(result); 42102713c30843816d3511b39b85a2c268a2b7682047Dan Stoza result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, early sf phase %" PRId64 42112713c30843816d3511b39b85a2c268a2b7682047Dan Stoza " ns, present offset %" PRId64 " ns (refresh %" PRId64 " ns)", 42122713c30843816d3511b39b85a2c268a2b7682047Dan Stoza vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, mVsyncModulator.getEarlyPhaseOffset(), 4213c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard dispSyncPresentTimeOffset, activeConfig->getVsyncPeriod()); 421441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden result.append("\n"); 421541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden 4216b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza // Dump static screen stats 4217b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 4218b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza dumpStaticScreenStats(result); 4219b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza result.append("\n"); 4220b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza 4221e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza dumpBufferingStats(result); 4222e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza 42234803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden /* 422482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump the visible layer list 422582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 42263e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 42271f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr result.appendFormat("Visible layers (count = %zu)\n", mNumLayers); 42280a0158c25c74de41770a9fa2f8d7da234a0daceeDan Stoza result.appendFormat("GraphicBufferProducers: %zu, max %zu\n", 42290a0158c25c74de41770a9fa2f8d7da234a0daceeDan Stoza mGraphicBufferProducerList.size(), mMaxGraphicBufferProducerListSize); 42303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 42311d04428c3cff3503212ec3e76775ca5ba20abc18chaviw 42328e0af3679ec73e07775142825d592448b255f61cJorim Jaggi LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current); 42331d04428c3cff3503212ec3e76775ca5ba20abc18chaviw auto layerTree = LayerProtoParser::generateLayerTree(layersProto); 42347794ec15e59fd6dd389ba05379ff81287c6ab52fchaviw result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str()); 42351e04361db1b65d3998edbf820078ccfaed477cb6Chia-I Wu result.append("\n"); 4236bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian 423782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 42385f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian * Dump Display state 42395f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian */ 42405f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 42413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 424286efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann result.appendFormat("Displays (%zu entries)\n", mDisplays.size()); 42433e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 42445f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 42455f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian const sp<const DisplayDevice>& hw(mDisplays[dpy]); 424674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hw->dump(result); 42475f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian } 42481e04361db1b65d3998edbf820078ccfaed477cb6Chia-I Wu result.append("\n"); 42495f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian 42505f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian /* 425182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump SurfaceFlinger global state 425282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 42531b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 42543e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 425574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("SurfaceFlinger global state:\n"); 42563e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 42571b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian 4258888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian HWComposer& hwc(getHwComposer()); 42597d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked()); 4260ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian 4261bc8152863f81c9af1038d92c9eb8caca1cfd4027David Sodman getBE().mRenderEngine->dump(result); 42629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian 42632ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique if (hw) { 42642ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique hw->undefinedRegion.dump(result, "undefinedRegion"); 42652ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique result.appendFormat(" orientation=%d, isDisplayOn=%d\n", 42662ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique hw->getOrientation(), hw->isDisplayOn()); 42672ae2b3bd5bfbacc3b52f222441bfbbeb9bd54dc7Lloyd Pique } 426874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 426982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last eglSwapBuffers() time: %f us\n" 427082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " last transaction time : %f us\n" 4271c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian " transaction-flags : %08x\n" 427282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " refresh-rate : %f fps\n" 427382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian " x-dpi : %f\n" 4274ed985574148a938bc3af24442eead313cc62521cMathias Agopian " y-dpi : %f\n" 4275ed985574148a938bc3af24442eead313cc62521cMathias Agopian " gpu_to_cpu_unsupported : %d\n" 4276ed985574148a938bc3af24442eead313cc62521cMathias Agopian , 427782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastSwapBufferTime/1000.0, 427882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian mLastTransactionTime/1000.0, 4279c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian mTransactionFlags, 42809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza 1e9 / activeConfig->getVsyncPeriod(), 42819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiX(), 42829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza activeConfig->getDpiY(), 4283ed985574148a938bc3af24442eead313cc62521cMathias Agopian !mGpuToCpuSupported); 428482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 428574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" eglSwapBuffers time: %f us\n", 428682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inSwapBuffersDuration/1000.0); 428782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 428874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat(" transaction time: %f us\n", 428982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian inTransactionDuration/1000.0); 429082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 429182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 429282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * VSYNC state 429382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 429474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian mEventThread->dump(result); 4295e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 4296e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 4297e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza /* 4298e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza * HWC layer minidump 4299e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza */ 4300e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza for (size_t d = 0; d < mDisplays.size(); d++) { 4301e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza const sp<const DisplayDevice>& displayDevice(mDisplays[d]); 4302e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza int32_t hwcId = displayDevice->getHwcDisplayId(); 4303e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) { 4304e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza continue; 4305e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 4306e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza 4307e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.appendFormat("Display %d HWC layers:\n", hwcId); 4308e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza Layer::miniDumpHeader(result); 43091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr mCurrentState.traverseInZOrder([&](Layer* layer) { 4310e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza layer->miniDump(result, hwcId); 43111f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr }); 4312e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza result.append("\n"); 4313e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza } 431482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 431582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 431682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump HWComposer state 431782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 43183e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.bold(result); 431974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.append("h/w composer state:\n"); 43203e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian colorizer.reset(result); 43219f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza bool hwcDisabled = mDebugDisableHWC || mDebugRegion; 43229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza result.appendFormat(" h/w composer %s\n", 43239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza hwcDisabled ? "disabled" : "enabled"); 432474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian hwc.dump(result); 432582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian 432682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian /* 432782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian * Dump gralloc state 432882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian */ 432982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 433082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian alloc.dump(result); 4331171155a55d7a3b7571ea1292f1aad926b6f82509Karthik Ravi Shankar 4332171155a55d7a3b7571ea1292f1aad926b6f82509Karthik Ravi Shankar /* 4333171155a55d7a3b7571ea1292f1aad926b6f82509Karthik Ravi Shankar * Dump VrFlinger state if in use. 4334171155a55d7a3b7571ea1292f1aad926b6f82509Karthik Ravi Shankar */ 4335171155a55d7a3b7571ea1292f1aad926b6f82509Karthik Ravi Shankar if (mVrFlingerRequestsDisplay && mVrFlinger) { 4336171155a55d7a3b7571ea1292f1aad926b6f82509Karthik Ravi Shankar result.append("VrFlinger state:\n"); 4337171155a55d7a3b7571ea1292f1aad926b6f82509Karthik Ravi Shankar result.append(mVrFlinger->Dump().c_str()); 4338171155a55d7a3b7571ea1292f1aad926b6f82509Karthik Ravi Shankar result.append("\n"); 4339171155a55d7a3b7571ea1292f1aad926b6f82509Karthik Ravi Shankar } 4340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 4341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 434213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& 434348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { 4344db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian // Note: mStateLock is held here 434548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall wp<IBinder> dpy; 434648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall for (size_t i=0 ; i<mDisplays.size() ; i++) { 434748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall if (mDisplays.valueAt(i)->getHwcDisplayId() == id) { 434848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = mDisplays.keyAt(i); 434948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall break; 435048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 435148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 4352566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin if (dpy == nullptr) { 435348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); 435448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall // Just use the primary display so we have something to return 435548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); 435648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall } 43577d3dcb9235ec149af2f5139a8a9c6eac859d92e2Stephen Kiazyk return getDisplayDeviceLocked(dpy)->getVisibleLayersSortedByZ(); 4358cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian} 4359cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian 436063f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection() 436163f165fd6b86d04be94d4023e845e98560504a96Keun young Park{ 436263f165fd6b86d04be94d4023e845e98560504a96Keun young Park void* libddmconnection_dso = 436363f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 436463f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!libddmconnection_dso) { 436563f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 436663f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 436763f165fd6b86d04be94d4023e845e98560504a96Keun young Park void (*DdmConnection_start)(const char* name); 436863f165fd6b86d04be94d4023e845e98560504a96Keun young Park DdmConnection_start = 436924cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start"); 437063f165fd6b86d04be94d4023e845e98560504a96Keun young Park if (!DdmConnection_start) { 437163f165fd6b86d04be94d4023e845e98560504a96Keun young Park dlclose(libddmconnection_dso); 437263f165fd6b86d04be94d4023e845e98560504a96Keun young Park return false; 437363f165fd6b86d04be94d4023e845e98560504a96Keun young Park } 437463f165fd6b86d04be94d4023e845e98560504a96Keun young Park (*DdmConnection_start)(getServiceName()); 437563f165fd6b86d04be94d4023e845e98560504a96Keun young Park return true; 437663f165fd6b86d04be94d4023e845e98560504a96Keun young Park} 437763f165fd6b86d04be94d4023e845e98560504a96Keun young Park 437828f320b443106f1656f9720224f579136dcf0c61Chia-I Wuvoid SurfaceFlinger::updateColorMatrixLocked() { 437928f320b443106f1656f9720224f579136dcf0c61Chia-I Wu mat4 colorMatrix; 438028f320b443106f1656f9720224f579136dcf0c61Chia-I Wu if (mGlobalSaturationFactor != 1.0f) { 438128f320b443106f1656f9720224f579136dcf0c61Chia-I Wu // Rec.709 luma coefficients 438228f320b443106f1656f9720224f579136dcf0c61Chia-I Wu float3 luminance{0.213f, 0.715f, 0.072f}; 438328f320b443106f1656f9720224f579136dcf0c61Chia-I Wu luminance *= 1.0f - mGlobalSaturationFactor; 438428f320b443106f1656f9720224f579136dcf0c61Chia-I Wu mat4 saturationMatrix = mat4( 438528f320b443106f1656f9720224f579136dcf0c61Chia-I Wu vec4{luminance.r + mGlobalSaturationFactor, luminance.r, luminance.r, 0.0f}, 438628f320b443106f1656f9720224f579136dcf0c61Chia-I Wu vec4{luminance.g, luminance.g + mGlobalSaturationFactor, luminance.g, 0.0f}, 438728f320b443106f1656f9720224f579136dcf0c61Chia-I Wu vec4{luminance.b, luminance.b, luminance.b + mGlobalSaturationFactor, 0.0f}, 438828f320b443106f1656f9720224f579136dcf0c61Chia-I Wu vec4{0.0f, 0.0f, 0.0f, 1.0f} 438928f320b443106f1656f9720224f579136dcf0c61Chia-I Wu ); 439028f320b443106f1656f9720224f579136dcf0c61Chia-I Wu colorMatrix = mClientColorMatrix * saturationMatrix * mDaltonizer(); 439128f320b443106f1656f9720224f579136dcf0c61Chia-I Wu } else { 439228f320b443106f1656f9720224f579136dcf0c61Chia-I Wu colorMatrix = mClientColorMatrix * mDaltonizer(); 439328f320b443106f1656f9720224f579136dcf0c61Chia-I Wu } 439428f320b443106f1656f9720224f579136dcf0c61Chia-I Wu 439528f320b443106f1656f9720224f579136dcf0c61Chia-I Wu if (mCurrentState.colorMatrix != colorMatrix) { 439628f320b443106f1656f9720224f579136dcf0c61Chia-I Wu mCurrentState.colorMatrix = colorMatrix; 439728f320b443106f1656f9720224f579136dcf0c61Chia-I Wu mCurrentState.colorMatrixChanged = true; 439828f320b443106f1656f9720224f579136dcf0c61Chia-I Wu setTransactionFlags(eTransactionNeeded); 439928f320b443106f1656f9720224f579136dcf0c61Chia-I Wu } 440028f320b443106f1656f9720224f579136dcf0c61Chia-I Wu} 440128f320b443106f1656f9720224f579136dcf0c61Chia-I Wu 44026e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { 4403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 4404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CREATE_CONNECTION: 4405041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian case CREATE_DISPLAY: 4406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case BOOT_FINISHED: 4407d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case CLEAR_ANIMATION_FRAME_STATS: 4408d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav case GET_ANIMATION_FRAME_STATS: 44092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani case SET_POWER_MODE: 4410c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza case GET_HDR_CAPABILITIES: 441190f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu case ENABLE_VSYNC_INJECTIONS: 441290f669f238cdc750483d0961efc61bbf551ae782Chia-I Wu case INJECT_VSYNC: 4413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 4414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // codes that require permission check 4415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipc = IPCThreadState::self(); 4416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int pid = ipc->getCallingPid(); 4417a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian const int uid = ipc->getCallingUid(); 44183bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && 441999b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 44206e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 4421375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 4422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 44231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 44241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 44251db73f66624e7d151710483dd58e03eed672f064Robert Carr /* 44261db73f66624e7d151710483dd58e03eed672f064Robert Carr * Calling setTransactionState is safe, because you need to have been 44271db73f66624e7d151710483dd58e03eed672f064Robert Carr * granted a reference to Client* and Handle* to do anything with it. 44281db73f66624e7d151710483dd58e03eed672f064Robert Carr * 44291db73f66624e7d151710483dd58e03eed672f064Robert Carr * Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h 44301db73f66624e7d151710483dd58e03eed672f064Robert Carr */ 44311db73f66624e7d151710483dd58e03eed672f064Robert Carr case SET_TRANSACTION_STATE: 44321db73f66624e7d151710483dd58e03eed672f064Robert Carr case CREATE_SCOPED_CONNECTION: 44331db73f66624e7d151710483dd58e03eed672f064Robert Carr { 44341db73f66624e7d151710483dd58e03eed672f064Robert Carr return OK; 44351db73f66624e7d151710483dd58e03eed672f064Robert Carr } 44361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian case CAPTURE_SCREEN: 44371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian { 44381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian // codes that require permission check 44391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 44401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int pid = ipc->getCallingPid(); 44411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian const int uid = ipc->getCallingUid(); 444299b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid != AID_GRAPHICS) && 444399b49840d309727678b77403d6cc9f920111623fMathias Agopian !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 44446e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid); 44451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian return PERMISSION_DENIED; 44461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian } 44471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian break; 4448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 4449a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw case CAPTURE_LAYERS: { 4450a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw IPCThreadState* ipc = IPCThreadState::self(); 4451a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const int pid = ipc->getCallingPid(); 4452a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const int uid = ipc->getCallingUid(); 4453a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if ((uid != AID_GRAPHICS) && 4454a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 4455a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid); 4456a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw return PERMISSION_DENIED; 4457a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw } 4458a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw break; 4459a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw } 4460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 44616e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard return OK; 44626e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard} 44636e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard 44646e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact( 44656e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 44666e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{ 44676e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard status_t credentialCheck = CheckTransactCodeCredentials(code); 44686e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard if (credentialCheck != OK) { 44696e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard return credentialCheck; 44706e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard } 44711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 4472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 4473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 4474b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian CHECK_INTERFACE(ISurfaceComposer, data, reply); 44758c6bbd63d8bb06197c671690268c49d20949d8ccRomain Guy IPCThreadState* ipc = IPCThreadState::self(); 44768c6bbd63d8bb06197c671690268c49d20949d8ccRomain Guy const int uid = ipc->getCallingUid(); 44778c6bbd63d8bb06197c671690268c49d20949d8ccRomain Guy if (CC_UNLIKELY(uid != AID_SYSTEM 44788c6bbd63d8bb06197c671690268c49d20949d8ccRomain Guy && !PermissionCache::checkCallingPermission(sHardwareTest))) { 4479375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 4480e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Permission Denial: " 4481375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 4482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; 4483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 4484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n; 4485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch (code) { 448601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 448735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 4488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 4489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1002: // SHOW_UPDATES 4490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project n = data.readInt32(); 4491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 449253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 449353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 4494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 4495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1004:{ // repaint everything 449653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 4497cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 4498cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 4499cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case 1005:{ // force transaction 45006d8110b1708171da278782d18886fa1a21971cd9Steven Thomas Mutex::Autolock _l(mStateLock); 4501e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian setTransactionFlags( 4502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTransactionNeeded| 4503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eDisplayTransactionNeeded| 4504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian eTraversalNeeded); 4505cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 4506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 45074d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian case 1006:{ // send empty update 45084d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian signalRefresh(); 45094d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian return NO_ERROR; 45104d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian } 451153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian case 1008: // toggle use of hw composer 451253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian n = data.readInt32(); 451353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian mDebugDisableHWC = n ? 1 : 0; 451453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian invalidateHwcGeometry(); 451553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian repaintEverything(); 451653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian return NO_ERROR; 4517a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian case 1009: // toggle use of transform hint 4518a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian n = data.readInt32(); 4519a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian mDebugDisableTransformHint = n ? 1 : 0; 4520a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian invalidateHwcGeometry(); 4521a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian repaintEverything(); 4522a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian return NO_ERROR; 4523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1010: // interrogate. 452401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian reply->writeInt32(0); 4525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(0); 4526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(mDebugRegion); 4527b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian reply->writeInt32(0); 452812839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn reply->writeInt32(mDebugDisableHWC); 4529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 4530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case 1013: { 45318722a310c00557195a0703e95564f31d908ab2d5Tomasz Wasilczyk sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 45324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian reply->writeInt32(hw->getPageFlipCount()); 4533ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian return NO_ERROR; 4534ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 4535ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian case 1014: { 453628f320b443106f1656f9720224f579136dcf0c61Chia-I Wu Mutex::Autolock _l(mStateLock); 4537ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian // daltonize 4538ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian n = data.readInt32(); 4539ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian switch (n % 10) { 45409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 1: 45419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Protanomaly); 45429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 45439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 2: 45449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Deuteranomaly); 45459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 45469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza case 3: 45479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::Tritanomaly); 45489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 45499f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza default: 45509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setType(ColorBlindnessType::None); 45519f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza break; 4552ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 4553ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian if (n >= 10) { 45549f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Correction); 4555ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } else { 45569f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza mDaltonizer.setMode(ColorBlindnessMode::Simulation); 4557ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian } 455828f320b443106f1656f9720224f579136dcf0c61Chia-I Wu 455928f320b443106f1656f9720224f579136dcf0c61Chia-I Wu updateColorMatrixLocked(); 45609c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 45619c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 45629c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette case 1015: { 456328f320b443106f1656f9720224f579136dcf0c61Chia-I Wu Mutex::Autolock _l(mStateLock); 45649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette // apply a color matrix 45659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette n = data.readInt32(); 45669c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette if (n) { 45670147a17adb08a155e1d6f72e6ca5e794fc7f5cc4Romain Guy // color matrix is sent as a column-major mat4 matrix 4568794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette for (size_t i = 0 ; i < 4; i++) { 45699f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza for (size_t j = 0; j < 4; j++) { 457028f320b443106f1656f9720224f579136dcf0c61Chia-I Wu mClientColorMatrix[i][j] = data.readFloat(); 45719f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza } 45729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 45739c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } else { 457428f320b443106f1656f9720224f579136dcf0c61Chia-I Wu mClientColorMatrix = mat4(); 45759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette } 457688d37ddac876c75dd5d2e39d33787dbcbf833641Romain Guy 457788d37ddac876c75dd5d2e39d33787dbcbf833641Romain Guy // Check that supplied matrix's last row is {0,0,0,1} so we can avoid 457888d37ddac876c75dd5d2e39d33787dbcbf833641Romain Guy // the division by w in the fragment shader 457928f320b443106f1656f9720224f579136dcf0c61Chia-I Wu float4 lastRow(transpose(mClientColorMatrix)[3]); 458088d37ddac876c75dd5d2e39d33787dbcbf833641Romain Guy if (any(greaterThan(abs(lastRow - float4{0, 0, 0, 1}), float4{1e-4f}))) { 458188d37ddac876c75dd5d2e39d33787dbcbf833641Romain Guy ALOGE("The color transform's last row must be (0, 0, 0, 1)"); 458288d37ddac876c75dd5d2e39d33787dbcbf833641Romain Guy } 458388d37ddac876c75dd5d2e39d33787dbcbf833641Romain Guy 458428f320b443106f1656f9720224f579136dcf0c61Chia-I Wu updateColorMatrixLocked(); 45859c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette return NO_ERROR; 4586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 4587f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // This is an experimental interface 4588f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi // Needs to be shifted to proper binder interface when we productize 4589f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi case 1016: { 4590645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden n = data.readInt32(); 4591645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden mPrimaryDispSync.setRefreshSkipCount(n); 4592f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi return NO_ERROR; 4593f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi } 4594ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza case 1017: { 4595ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza n = data.readInt32(); 4596ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza mForceFullDamage = static_cast<bool>(n); 4597ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza return NO_ERROR; 4598ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza } 4599db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1018: { // Modify Choreographer's phase offset 4600db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 4601db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 4602db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 4603db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 4604db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza case 1019: { // Modify SurfaceFlinger's phase offset 4605db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza n = data.readInt32(); 4606db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); 4607db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza return NO_ERROR; 4608db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza } 4609468051e20be19130572231266db306396a56402bIrvel case 1020: { // Layer updates interceptor 4610468051e20be19130572231266db306396a56402bIrvel n = data.readInt32(); 4611468051e20be19130572231266db306396a56402bIrvel if (n) { 4612468051e20be19130572231266db306396a56402bIrvel ALOGV("Interceptor enabled"); 46134d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->enable(mDrawingState.layersSortedByZ, mDrawingState.displays); 4614468051e20be19130572231266db306396a56402bIrvel } 4615468051e20be19130572231266db306396a56402bIrvel else{ 4616468051e20be19130572231266db306396a56402bIrvel ALOGV("Interceptor disabled"); 46174d2348551e73b4990aedc83db17a336b533316e6Lloyd Pique mInterceptor->disable(); 4618468051e20be19130572231266db306396a56402bIrvel } 4619468051e20be19130572231266db306396a56402bIrvel return NO_ERROR; 4620468051e20be19130572231266db306396a56402bIrvel } 46218cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza case 1021: { // Disable HWC virtual displays 46228cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza n = data.readInt32(); 46238cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza mUseHwcVirtualDisplays = !n; 46248cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza return NO_ERROR; 46258cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza } 46260147a17adb08a155e1d6f72e6ca5e794fc7f5cc4Romain Guy case 1022: { // Set saturation boost 462728f320b443106f1656f9720224f579136dcf0c61Chia-I Wu Mutex::Autolock _l(mStateLock); 4628dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin mGlobalSaturationFactor = std::max(0.0f, std::min(data.readFloat(), 2.0f)); 46290147a17adb08a155e1d6f72e6ca5e794fc7f5cc4Romain Guy 463028f320b443106f1656f9720224f579136dcf0c61Chia-I Wu updateColorMatrixLocked(); 46310147a17adb08a155e1d6f72e6ca5e794fc7f5cc4Romain Guy return NO_ERROR; 46320147a17adb08a155e1d6f72e6ca5e794fc7f5cc4Romain Guy } 463354f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy case 1023: { // Set native mode 46340d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu mDisplayColorSetting = static_cast<DisplayColorSetting>(data.readInt32()); 463554f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy invalidateHwcGeometry(); 463654f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy repaintEverything(); 463754f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy return NO_ERROR; 463854f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy } 463954f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy case 1024: { // Is wide color gamut rendering/color management supported? 464054f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy reply->writeBool(hasWideColorDisplay); 464154f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy return NO_ERROR; 464254f154a28284eabb52ade2689d4a9f8fa190163bRomain Guy } 464387704c94fac81f625ba5b25548fd4ad497500f58Vishnu Nair case 1025: { // Set layer tracing 46441e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos n = data.readInt32(); 46451e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos if (n) { 46461e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos ALOGV("LayerTracing enabled"); 46471e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos mTracing.enable(); 46481e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos doTracing("tracing.enable"); 46491e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos reply->writeInt32(NO_ERROR); 46501e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos } else { 46511e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos ALOGV("LayerTracing disabled"); 46521e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos status_t err = mTracing.disable(); 46531e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos reply->writeInt32(err); 46541e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos } 46551e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos return NO_ERROR; 46561e1a1282846318caa0bfe271500eb3ba24e9a513Adrian Roos } 465787704c94fac81f625ba5b25548fd4ad497500f58Vishnu Nair case 1026: { // Get layer tracing status 465887704c94fac81f625ba5b25548fd4ad497500f58Vishnu Nair reply->writeBool(mTracing.isEnabled()); 465987704c94fac81f625ba5b25548fd4ad497500f58Vishnu Nair return NO_ERROR; 466087704c94fac81f625ba5b25548fd4ad497500f58Vishnu Nair } 4661dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin // Is a DisplayColorSetting supported? 4662dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin case 1027: { 46630d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 46640d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu if (!hw) { 46650d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu return NAME_NOT_FOUND; 46660d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu } 46670d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu 46680d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu DisplayColorSetting setting = static_cast<DisplayColorSetting>(data.readInt32()); 46690d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu switch (setting) { 46700d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu case DisplayColorSetting::MANAGED: 4671dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin reply->writeBool(hasWideColorDisplay); 46720d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu break; 46730d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu case DisplayColorSetting::UNMANAGED: 4674dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin reply->writeBool(true); 46750d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu break; 46760d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu case DisplayColorSetting::ENHANCED: 46770d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu reply->writeBool(hw->hasRenderIntent(RenderIntent::ENHANCE)); 46780d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu break; 46790d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu default: // vendor display color setting 46800d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu reply->writeBool(hw->hasRenderIntent(static_cast<RenderIntent>(setting))); 46810d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu break; 4682dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin } 46830d711268fe57b73a38ec3590b6e67f03ff789fa1Chia-I Wu return NO_ERROR; 4684dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin } 4685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 4686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 4687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 4688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 4689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4690c7a25adf66b138de66814383540905b83cf12a01Dan Stozavoid SurfaceFlinger::repaintEverything() { 469187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian android_atomic_or(1, &mRepaintEverything); 469299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian signalTransaction(); 469353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian} 469453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian 46952b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza// A simple RAII class to disconnect from an ANativeWindow* when it goes out of scope 46962b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stozaclass WindowDisconnector { 46972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic: 46982b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza WindowDisconnector(ANativeWindow* window, int api) : mWindow(window), mApi(api) {} 46992b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza ~WindowDisconnector() { 47002b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza native_window_api_disconnect(mWindow, mApi); 47012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian } 47022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 47032b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stozaprivate: 47042b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza ANativeWindow* mWindow; 47052b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza const int mApi; 47062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian}; 47072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 470840482ff650751819d4104c10a30974838168438cChavi Weingartenstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer, 470940482ff650751819d4104c10a30974838168438cChavi Weingarten Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 471040482ff650751819d4104c10a30974838168438cChavi Weingarten int32_t minLayerZ, int32_t maxLayerZ, 471140482ff650751819d4104c10a30974838168438cChavi Weingarten bool useIdentityTransform, 4712a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw ISurfaceComposer::Rotation rotation) { 47132b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza ATRACE_CALL(); 47142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 4715a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if (CC_UNLIKELY(display == 0)) return BAD_VALUE; 4716a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 4717a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const sp<const DisplayDevice> device(getDisplayDeviceLocked(display)); 47183b1b8affbda97b8414c3015648d7804609f727e6Garfield Tan if (CC_UNLIKELY(device == 0)) return BAD_VALUE; 47193b1b8affbda97b8414c3015648d7804609f727e6Garfield Tan 4720a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw DisplayRenderArea renderArea(device, sourceCrop, reqHeight, reqWidth, rotation); 4721a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 4722a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this, 4723a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw device, minLayerZ, maxLayerZ, std::placeholders::_1); 472440482ff650751819d4104c10a30974838168438cChavi Weingarten return captureScreenCommon(renderArea, traverseLayers, outBuffer, useIdentityTransform); 4725a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw} 4726a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 4727a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviwstatus_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, 472887704c94fac81f625ba5b25548fd4ad497500f58Vishnu Nair sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop, 4729578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr float frameScale, bool childrenOnly) { 4730a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw ATRACE_CALL(); 4731a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 4732a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw class LayerRenderArea : public RenderArea { 4733a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw public: 4734578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop, 4735578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr int32_t reqWidth, int32_t reqHeight, bool childrenOnly) 473650da5043ad224fd6b6024ed73785a9502bf7978dchaviw : RenderArea(reqHeight, reqWidth, CaptureFill::CLEAR), 4737578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr mLayer(layer), 4738578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr mCrop(crop), 4739578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr mFlinger(flinger), 4740578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr mChildrenOnly(childrenOnly) {} 4741dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin const Transform& getTransform() const override { return mTransform; } 4742a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw Rect getBounds() const override { 4743a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const Layer::State& layerState(mLayer->getDrawingState()); 4744a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw return Rect(layerState.active.w, layerState.active.h); 4745a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw } 4746a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw int getHeight() const override { return mLayer->getDrawingState().active.h; } 4747a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw int getWidth() const override { return mLayer->getDrawingState().active.w; } 4748a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw bool isSecure() const override { return false; } 4749a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw bool needsFiltering() const override { return false; } 4750dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin Rect getSourceCrop() const override { 4751dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin if (mCrop.isEmpty()) { 4752dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin return getBounds(); 4753dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin } else { 4754dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin return mCrop; 4755dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin } 4756dd9b2ae8500d85a6aba82de15e8b40d14a921ca6Peiyong Lin } 4757578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr class ReparentForDrawing { 4758578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr public: 4759578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr const sp<Layer>& oldParent; 4760578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr const sp<Layer>& newParent; 4761578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr 4762578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr ReparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent) 4763578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr : oldParent(oldParent), newParent(newParent) { 476415eae09ebb293135dedce203bcb542a2e6e8d43aRobert Carr oldParent->setChildrenDrawingParent(newParent); 4765578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr } 476615eae09ebb293135dedce203bcb542a2e6e8d43aRobert Carr ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); } 4767578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr }; 4768578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr 4769578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr void render(std::function<void()> drawLayers) override { 4770578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr if (!mChildrenOnly) { 4771578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr mTransform = mLayer->getTransform().inverse(); 4772578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr drawLayers(); 4773578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr } else { 4774578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr Rect bounds = getBounds(); 4775578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr screenshotParentLayer = 4776578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr new ContainerLayer(mFlinger, nullptr, String8("Screenshot Parent"), 4777578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr bounds.getWidth(), bounds.getHeight(), 0); 4778578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr 4779578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr ReparentForDrawing reparent(mLayer, screenshotParentLayer); 4780578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr drawLayers(); 4781578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr } 4782578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr } 4783a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 4784a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw private: 47857206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw const sp<Layer> mLayer; 47867206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw const Rect mCrop; 4787578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr 4788578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr // In the "childrenOnly" case we reparent the children to a screenshot 4789578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr // layer which has no properties set and which does not draw. 4790578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr sp<ContainerLayer> screenshotParentLayer; 4791578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr Transform mTransform; 4792578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr 4793578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr SurfaceFlinger* mFlinger; 4794578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr const bool mChildrenOnly; 4795a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw }; 4796a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 4797a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw auto layerHandle = reinterpret_cast<Layer::Handle*>(layerHandleBinder.get()); 4798a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw auto parent = layerHandle->owner.promote(); 4799a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 48007206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw if (parent == nullptr || parent->isPendingRemoval()) { 48017206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw ALOGE("captureLayers called with a removed parent"); 48027206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw return NAME_NOT_FOUND; 48037206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw } 48047206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw 4805578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr const int uid = IPCThreadState::self()->getCallingUid(); 4806578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM; 4807578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) { 4808578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); 4809578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr return PERMISSION_DENIED; 4810578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr } 4811578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr 48127206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw Rect crop(sourceCrop); 48137206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw if (sourceCrop.width() <= 0) { 48147206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw crop.left = 0; 48157206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw crop.right = parent->getCurrentState().active.w; 48167206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw } 48177206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw 48187206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw if (sourceCrop.height() <= 0) { 48197206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw crop.top = 0; 48207206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw crop.bottom = parent->getCurrentState().active.h; 48217206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw } 48227206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw 48237206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw int32_t reqWidth = crop.width() * frameScale; 48247206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw int32_t reqHeight = crop.height() * frameScale; 48257206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw 4826578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, childrenOnly); 48277206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw 4828578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr auto traverseLayers = [parent, childrenOnly](const LayerVector::Visitor& visitor) { 4829a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) { 4830a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if (!layer->isVisible()) { 4831a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw return; 4832578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr } else if (childrenOnly && layer == parent.get()) { 4833578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr return; 4834a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw } 4835a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw visitor(layer); 4836a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw }); 4837a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw }; 483840482ff650751819d4104c10a30974838168438cChavi Weingarten return captureScreenCommon(renderArea, traverseLayers, outBuffer, false); 4839a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw} 4840a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 4841a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviwstatus_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea, 4842a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw TraverseLayersFunction traverseLayers, 484340482ff650751819d4104c10a30974838168438cChavi Weingarten sp<GraphicBuffer>* outBuffer, 4844a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw bool useIdentityTransform) { 4845a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw ATRACE_CALL(); 48462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 48477501ed66a05f530062925011d1342e8651216051Iris Chang renderArea.updateDimensions(mPrimaryDisplayOrientation); 4848a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 484940482ff650751819d4104c10a30974838168438cChavi Weingarten const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | 485040482ff650751819d4104c10a30974838168438cChavi Weingarten GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 485140482ff650751819d4104c10a30974838168438cChavi Weingarten *outBuffer = new GraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(), 485240482ff650751819d4104c10a30974838168438cChavi Weingarten HAL_PIXEL_FORMAT_RGBA_8888, 1, usage, "screenshot"); 48532b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza 48542b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza // This mutex protects syncFd and captureResult for communication of the return values from the 48552b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza // main thread back to this Binder thread 48562b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza std::mutex captureMutex; 48572b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza std::condition_variable captureCondition; 48582b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza std::unique_lock<std::mutex> captureLock(captureMutex); 48592b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza int syncFd = -1; 48602b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza std::optional<status_t> captureResult; 48612b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza 486203480e23a6abd6c25aa3b689f736eb9c051eb8c3Robert Carr const int uid = IPCThreadState::self()->getCallingUid(); 486303480e23a6abd6c25aa3b689f736eb9c051eb8c3Robert Carr const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM; 486403480e23a6abd6c25aa3b689f736eb9c051eb8c3Robert Carr 48652b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza sp<LambdaMessage> message = new LambdaMessage([&]() { 48662b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza // If there is a refresh pending, bug out early and tell the binder thread to try again 48672b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza // after the refresh. 48682b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza if (mRefreshPending) { 48692b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza ATRACE_NAME("Skipping screenshot for now"); 48702b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza std::unique_lock<std::mutex> captureLock(captureMutex); 48712b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza captureResult = std::make_optional<status_t>(EAGAIN); 48722b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza captureCondition.notify_one(); 48732b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza return; 48742a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 48752b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza 48762b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza status_t result = NO_ERROR; 48772b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza int fd = -1; 48782b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza { 48792b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza Mutex::Autolock _l(mStateLock); 4880578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr renderArea.render([&]() { 4881578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr result = captureScreenImplLocked(renderArea, traverseLayers, (*outBuffer).get(), 4882578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr useIdentityTransform, forSystem, &fd); 4883578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr }); 48842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 48852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian 48862b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza { 48872b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza std::unique_lock<std::mutex> captureLock(captureMutex); 48882b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza syncFd = fd; 48892b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza captureResult = std::make_optional<status_t>(result); 48902b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza captureCondition.notify_one(); 48912b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza } 48922b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza }); 48932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 489440482ff650751819d4104c10a30974838168438cChavi Weingarten status_t result = postMessageAsync(message); 48952b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza if (result == NO_ERROR) { 48962b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza captureCondition.wait(captureLock, [&]() { return captureResult; }); 48972b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza while (*captureResult == EAGAIN) { 48982b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza captureResult.reset(); 48992b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza result = postMessageAsync(message); 49002b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza if (result != NO_ERROR) { 49012b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza return result; 49022b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza } 49032b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza captureCondition.wait(captureLock, [&]() { return captureResult; }); 49042b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza } 49052b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza result = *captureResult; 49062b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza } 49072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian 49082b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza if (result == NO_ERROR) { 490940482ff650751819d4104c10a30974838168438cChavi Weingarten sync_wait(syncFd, -1); 491040482ff650751819d4104c10a30974838168438cChavi Weingarten close(syncFd); 49112a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian } 491240482ff650751819d4104c10a30974838168438cChavi Weingarten 49132b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza return result; 4914118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian} 4915118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian 4916a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviwvoid SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, 4917a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw TraverseLayersFunction traverseLayers, bool yswap, 4918a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw bool useIdentityTransform) { 4919180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian ATRACE_CALL(); 4920a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 4921144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique auto& engine(getRenderEngine()); 4922180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4923180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // get screen geometry 4924a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const auto raWidth = renderArea.getWidth(); 4925a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const auto raHeight = renderArea.getHeight(); 4926a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 4927a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const auto reqWidth = renderArea.getReqWidth(); 4928a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const auto reqHeight = renderArea.getReqHeight(); 4929a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw Rect sourceCrop = renderArea.getSourceCrop(); 4930a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 49317501ed66a05f530062925011d1342e8651216051Iris Chang bool filtering = false; 49327501ed66a05f530062925011d1342e8651216051Iris Chang if (mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) { 49337501ed66a05f530062925011d1342e8651216051Iris Chang filtering = static_cast<int32_t>(reqWidth) != raHeight || 49347501ed66a05f530062925011d1342e8651216051Iris Chang static_cast<int32_t>(reqHeight) != raWidth; 49357501ed66a05f530062925011d1342e8651216051Iris Chang } else { 49367501ed66a05f530062925011d1342e8651216051Iris Chang filtering = static_cast<int32_t>(reqWidth) != raWidth || 49377501ed66a05f530062925011d1342e8651216051Iris Chang static_cast<int32_t>(reqHeight) != raHeight; 49387501ed66a05f530062925011d1342e8651216051Iris Chang } 4939180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 4940c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // if a default or invalid sourceCrop is passed in, set reasonable values 4941a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || !sourceCrop.isValid()) { 4942c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza sourceCrop.setLeftTop(Point(0, 0)); 4943a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw sourceCrop.setRightBottom(Point(raWidth, raHeight)); 49447501ed66a05f530062925011d1342e8651216051Iris Chang } else if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) { 49457501ed66a05f530062925011d1342e8651216051Iris Chang Transform tr; 49467501ed66a05f530062925011d1342e8651216051Iris Chang uint32_t flags = 0x00; 49477501ed66a05f530062925011d1342e8651216051Iris Chang switch (mPrimaryDisplayOrientation) { 49487501ed66a05f530062925011d1342e8651216051Iris Chang case DisplayState::eOrientation90: 49497501ed66a05f530062925011d1342e8651216051Iris Chang flags = Transform::ROT_90; 49507501ed66a05f530062925011d1342e8651216051Iris Chang break; 49517501ed66a05f530062925011d1342e8651216051Iris Chang case DisplayState::eOrientation180: 49527501ed66a05f530062925011d1342e8651216051Iris Chang flags = Transform::ROT_180; 49537501ed66a05f530062925011d1342e8651216051Iris Chang break; 49547501ed66a05f530062925011d1342e8651216051Iris Chang case DisplayState::eOrientation270: 49557501ed66a05f530062925011d1342e8651216051Iris Chang flags = Transform::ROT_270; 49567501ed66a05f530062925011d1342e8651216051Iris Chang break; 49577501ed66a05f530062925011d1342e8651216051Iris Chang } 49587501ed66a05f530062925011d1342e8651216051Iris Chang tr.set(flags, raWidth, raHeight); 49597501ed66a05f530062925011d1342e8651216051Iris Chang sourceCrop = tr.transform(sourceCrop); 4960c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4961c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 4962c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza // ensure that sourceCrop is inside screen 4963c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.left < 0) { 4964c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); 4965c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4966a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if (sourceCrop.right > raWidth) { 4967a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, raWidth); 4968c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4969c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza if (sourceCrop.top < 0) { 4970c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); 4971c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4972a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if (sourceCrop.bottom > raHeight) { 4973a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, raHeight); 4974c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza } 4975c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza 497636574d99f78bb533db4eaeb35998bb96f2e69193Chia-I Wu // assume ColorMode::SRGB / RenderIntent::COLORIMETRIC 497736574d99f78bb533db4eaeb35998bb96f2e69193Chia-I Wu engine.setOutputDataSpace(Dataspace::SRGB); 497836574d99f78bb533db4eaeb35998bb96f2e69193Chia-I Wu engine.setDisplayMaxLuminance(DisplayDevice::sDefaultMaxLumiance); 497988d37ddac876c75dd5d2e39d33787dbcbf833641Romain Guy 4980180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // make sure to clear all GL error flags 49813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.checkErrors(); 4982180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 49837501ed66a05f530062925011d1342e8651216051Iris Chang Transform::orientation_flags rotation = renderArea.getRotationFlags(); 49847501ed66a05f530062925011d1342e8651216051Iris Chang if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) { 49857501ed66a05f530062925011d1342e8651216051Iris Chang // convert hw orientation into flag presentation 49867501ed66a05f530062925011d1342e8651216051Iris Chang // here inverse transform needed 49877501ed66a05f530062925011d1342e8651216051Iris Chang uint8_t hw_rot_90 = 0x00; 49887501ed66a05f530062925011d1342e8651216051Iris Chang uint8_t hw_flip_hv = 0x00; 49897501ed66a05f530062925011d1342e8651216051Iris Chang switch (mPrimaryDisplayOrientation) { 49907501ed66a05f530062925011d1342e8651216051Iris Chang case DisplayState::eOrientation90: 49917501ed66a05f530062925011d1342e8651216051Iris Chang hw_rot_90 = Transform::ROT_90; 49927501ed66a05f530062925011d1342e8651216051Iris Chang hw_flip_hv = Transform::ROT_180; 49937501ed66a05f530062925011d1342e8651216051Iris Chang break; 49947501ed66a05f530062925011d1342e8651216051Iris Chang case DisplayState::eOrientation180: 49957501ed66a05f530062925011d1342e8651216051Iris Chang hw_flip_hv = Transform::ROT_180; 49967501ed66a05f530062925011d1342e8651216051Iris Chang break; 49977501ed66a05f530062925011d1342e8651216051Iris Chang case DisplayState::eOrientation270: 49987501ed66a05f530062925011d1342e8651216051Iris Chang hw_rot_90 = Transform::ROT_90; 49997501ed66a05f530062925011d1342e8651216051Iris Chang break; 50007501ed66a05f530062925011d1342e8651216051Iris Chang } 50017501ed66a05f530062925011d1342e8651216051Iris Chang 50027501ed66a05f530062925011d1342e8651216051Iris Chang // transform flags operation 50037501ed66a05f530062925011d1342e8651216051Iris Chang // 1) flip H V if both have ROT_90 flag 50047501ed66a05f530062925011d1342e8651216051Iris Chang // 2) XOR these flags 50057501ed66a05f530062925011d1342e8651216051Iris Chang uint8_t rotation_rot_90 = rotation & Transform::ROT_90; 50067501ed66a05f530062925011d1342e8651216051Iris Chang uint8_t rotation_flip_hv = rotation & Transform::ROT_180; 50077501ed66a05f530062925011d1342e8651216051Iris Chang if (rotation_rot_90 & hw_rot_90) { 50087501ed66a05f530062925011d1342e8651216051Iris Chang rotation_flip_hv = (~rotation_flip_hv) & Transform::ROT_180; 50097501ed66a05f530062925011d1342e8651216051Iris Chang } 50107501ed66a05f530062925011d1342e8651216051Iris Chang rotation = static_cast<Transform::orientation_flags> 50117501ed66a05f530062925011d1342e8651216051Iris Chang ((rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv)); 50127501ed66a05f530062925011d1342e8651216051Iris Chang } 50137501ed66a05f530062925011d1342e8651216051Iris Chang 5014180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // set-up our viewport 5015a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, raHeight, yswap, 50167501ed66a05f530062925011d1342e8651216051Iris Chang rotation); 50173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine.disableTexturing(); 5018180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 501950da5043ad224fd6b6024ed73785a9502bf7978dchaviw const float alpha = RenderArea::getCaptureFillValue(renderArea.getCaptureFill()); 5020180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian // redraw the screen entirely... 502150da5043ad224fd6b6024ed73785a9502bf7978dchaviw engine.clearWithColor(0, 0, 0, alpha); 5022180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 5023a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw traverseLayers([&](Layer* layer) { 5024a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if (filtering) layer->setFiltering(true); 5025a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw layer->draw(renderArea, useIdentityTransform); 5026a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if (filtering) layer->setFiltering(false); 5027a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw }); 5028180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian} 5029180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 5030a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviwstatus_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea, 5031a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw TraverseLayersFunction traverseLayers, 5032a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw ANativeWindowBuffer* buffer, 503340482ff650751819d4104c10a30974838168438cChavi Weingarten bool useIdentityTransform, 503403480e23a6abd6c25aa3b689f736eb9c051eb8c3Robert Carr bool forSystem, 5035a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw int* outSyncFd) { 5036fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian ATRACE_CALL(); 5037180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian 5038b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos bool secureLayerIsVisible = false; 5039a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 5040a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw traverseLayers([&](Layer* layer) { 5041a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() && layer->isSecure()); 5042a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw }); 5043b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 504403480e23a6abd6c25aa3b689f736eb9c051eb8c3Robert Carr // We allow the system server to take screenshots of secure layers for 504503480e23a6abd6c25aa3b689f736eb9c051eb8c3Robert Carr // use in situations like the Screen-rotation animation and place 504603480e23a6abd6c25aa3b689f736eb9c051eb8c3Robert Carr // the impetus on WindowManager to not persist them. 504703480e23a6abd6c25aa3b689f736eb9c051eb8c3Robert Carr if (secureLayerIsVisible && !forSystem) { 5048b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos ALOGW("FB is protected: PERMISSION_DENIED"); 5049b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos return PERMISSION_DENIED; 5050b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos } 5051b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos 5052a9b1aa0b0dded03256a4deae50b4e94393506547Dan Stoza // this binds the given EGLImage as a framebuffer for the 5053a9b1aa0b0dded03256a4deae50b4e94393506547Dan Stoza // duration of this scope. 5054144e116f45f196396f0d59d5fc09766ab618f885Lloyd Pique RE::BindNativeBufferAsFramebuffer bufferBond(getRenderEngine(), buffer); 5055eadbaa68dbf0f674b2a5260fc813b408cb42fee3Chia-I Wu if (bufferBond.getStatus() != NO_ERROR) { 5056eadbaa68dbf0f674b2a5260fc813b408cb42fee3Chia-I Wu ALOGE("got ANWB binding error while taking screenshot"); 5057abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza return INVALID_OPERATION; 5058abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza } 5059d555684cb36dfb959694db76962e570184f98838Mathias Agopian 5060abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza // this will in fact render into our dequeued buffer 5061abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza // via an FBO, which means we didn't have to create 5062abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza // an EGLSurface and therefore we're not 5063abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza // dependent on the context's EGLConfig. 5064a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw renderScreenImplLocked(renderArea, traverseLayers, true, useIdentityTransform); 50658ec6ff22dc56e7447991557075d19f9edb2d5aa8Romain Guy 5066abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza if (DEBUG_SCREENSHOTS) { 5067767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu getRenderEngine().finish(); 5068767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu *outSyncFd = -1; 5069767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu 5070a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const auto reqWidth = renderArea.getReqWidth(); 5071a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const auto reqHeight = renderArea.getReqHeight(); 5072a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 5073abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza uint32_t* pixels = new uint32_t[reqWidth*reqHeight]; 5074abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels); 5075a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw checkScreenshot(reqWidth, reqHeight, reqWidth, pixels, traverseLayers); 5076abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza delete [] pixels; 5077767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu } else { 5078767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu base::unique_fd syncFd = getRenderEngine().flush(); 5079767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu if (syncFd < 0) { 5080767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu getRenderEngine().finish(); 5081767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu } 5082767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu *outSyncFd = syncFd.release(); 5083a9b1aa0b0dded03256a4deae50b4e94393506547Dan Stoza } 5084abcda352f126016ce4dd227d34088e8c7957c32eDan Stoza 50852b6d38e8eca1fe7137757b8269c6c19c6d1a04e4Dan Stoza return NO_ERROR; 508674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian} 508774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian 5088d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr, 5089a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw TraverseLayersFunction traverseLayers) { 5090fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (DEBUG_SCREENSHOTS) { 5091a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw for (size_t y = 0; y < h; y++) { 5092a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw uint32_t const* p = (uint32_t const*)vaddr + y * s; 5093a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw for (size_t x = 0; x < w; x++) { 5094fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian if (p[x] != 0xFF000000) return; 5095fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 5096fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 5097a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw ALOGE("*** we just took a black screenshot ***"); 50981f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr 50992047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr size_t i = 0; 5100a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw traverseLayers([&](Layer* layer) { 5101fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian const Layer::State& state(layer->getDrawingState()); 5102a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f", 5103a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw layer->isVisible() ? '+' : '-', i, layer->getName().string(), 5104a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw layer->getLayerStack(), state.z, layer->isVisible(), state.flags, 5105a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw static_cast<float>(state.color.a)); 5106a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw i++; 5107a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw }); 5108fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian } 5109ce796e78a57018f186b062199c75d94545318acaPablo Ceballos} 5110ce796e78a57018f186b062199c75d94545318acaPablo Ceballos 51111b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// --------------------------------------------------------------------------- 51121b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian 5113412903fce3a93f411c85c54375a1851bfb370400Dan Stozavoid SurfaceFlinger::State::traverseInZOrder(const LayerVector::Visitor& visitor) const { 5114412903fce3a93f411c85c54375a1851bfb370400Dan Stoza layersSortedByZ.traverseInZOrder(stateSet, visitor); 5115921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 5116921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 5117412903fce3a93f411c85c54375a1851bfb370400Dan Stozavoid SurfaceFlinger::State::traverseInReverseZOrder(const LayerVector::Visitor& visitor) const { 5118412903fce3a93f411c85c54375a1851bfb370400Dan Stoza layersSortedByZ.traverseInReverseZOrder(stateSet, visitor); 5119921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian} 5120921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian 5121a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviwvoid SurfaceFlinger::traverseLayersInDisplay(const sp<const DisplayDevice>& hw, int32_t minLayerZ, 5122a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw int32_t maxLayerZ, 5123a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const LayerVector::Visitor& visitor) { 5124a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw // We loop through the first level of layers without traversing, 5125a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw // as we need to interpret min/max layer Z in the top level Z space. 5126a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw for (const auto& layer : mDrawingState.layersSortedByZ) { 5127a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if (!layer->belongsToDisplay(hw->getLayerStack(), false)) { 5128a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw continue; 5129a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw } 5130a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw const Layer::State& state(layer->getDrawingState()); 5131ec2d9855acb6b2dd4507bca28eaf3c5b41573c44Chia-I Wu // relative layers are traversed in Layer::traverseInZOrder 5132ec2d9855acb6b2dd4507bca28eaf3c5b41573c44Chia-I Wu if (state.zOrderRelativeOf != nullptr || state.z < minLayerZ || state.z > maxLayerZ) { 5133a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw continue; 5134a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw } 5135a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) { 51368acf5a0acc2d45d090bbc25fa8bbb07ce1076e40Adrian Roos if (!layer->belongsToDisplay(hw->getLayerStack(), false)) { 51378acf5a0acc2d45d090bbc25fa8bbb07ce1076e40Adrian Roos return; 51388acf5a0acc2d45d090bbc25fa8bbb07ce1076e40Adrian Roos } 5139a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw if (!layer->isVisible()) { 5140a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw return; 5141a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw } 5142a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw visitor(layer); 5143a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw }); 5144a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw } 5145a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw} 5146a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw 5147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 51483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 51493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 51503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_) 51513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file" 51523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif 51533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 51543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_) 51553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file" 5156767fcf7ef21a2db44ead9e685ebe48f638f3e651Chia-I Wu#endif 5157