SurfaceFlinger.cpp revision 5c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27
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>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
24c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju#include <mutex>
2563f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h>
2686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h>
27b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h>
28921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
29921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
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>
47e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
48f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy#include <gui/GraphicBufferAlloc.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
643e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
663e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
680f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
69faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
70d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
71d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
731f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr#include "LayerVector.h"
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
751db73f66624e7d151710483dd58e03eed672f064Robert Carr#include "MonitoredProducer.h"
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
78a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
79a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
8099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
82ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
83ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
84875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
85ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
86875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
874b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
884351857c9de86df9f418b3df28aebb1239ca35ddJaesoo Lee#include <configstore/Utils.h>
894b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
92fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
93fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
94fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
95fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
96fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
97fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
98ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
99ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
102c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard
1034351857c9de86df9f418b3df28aebb1239ca35ddJaesoo Leeusing namespace android::hardware::configstore;
1044b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Parkusing namespace android::hardware::configstore::V1_0;
1054b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
10999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
11099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
11199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
11299b49840d309727678b77403d6cc9f920111623fMathias Agopian
11399b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
1140cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglardint64_t SurfaceFlinger::vsyncPhaseOffsetNs;
1150cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglardint64_t SurfaceFlinger::sfVsyncPhaseOffsetNs;
116c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglardbool SurfaceFlinger::useContextPriority;
117c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglardint64_t SurfaceFlinger::dispSyncPresentTimeOffset;
118a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglardbool SurfaceFlinger::useHwcForRgbToYuv;
119c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglarduint64_t SurfaceFlinger::maxVirtualDisplaySize;
120cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglardbool SurfaceFlinger::hasSyncFramework;
121050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasbool SurfaceFlinger::useVrFlinger;
1221971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglardint64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
1235d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchterbool SurfaceFlinger::hasWideColorDisplay;
12499b49840d309727678b77403d6cc9f920111623fMathias Agopian
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1264f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1282d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1292d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
130076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
1311f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded(false),
13252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
13387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mHwc(nullptr),
13487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mRealHwc(nullptr),
13587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mVrHwc(nullptr),
13687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        mRenderEngine(nullptr),
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
1389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mBuiltinDisplays(),
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
1409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid(false),
1414b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1438afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14473d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
145a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1489795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1499795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
150ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
151ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        mForceFullDamage(false),
1520d48072f6047140119ff194c1194ce402fca2c0bRobert Carr        mInterceptor(this),
1534a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mPrimaryDispSync("PrimaryDispSync"),
154faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
155948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
156b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasColorMatrix(false),
157b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff(false),
158b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mFrameBuckets(),
159b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime(0),
1601f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLastSwapTime(0),
161050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        mNumLayers(0),
162050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        mVrFlingerRequestsDisplay(false)
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
164cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    ALOGI("SurfaceFlinger is starting");
1650cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard
1660cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard    vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
1670cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard            &ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);
1680cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard
1690cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard    sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
1700cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard            &ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000);
1710cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard
172cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    hasSyncFramework = getBool< ISurfaceFlingerConfigs,
173cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard            &ISurfaceFlingerConfigs::hasSyncFramework>(true);
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
175c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard    useContextPriority = getBool< ISurfaceFlingerConfigs,
176c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard            &ISurfaceFlingerConfigs::useContextPriority>(false);
177c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard
178c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard    dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs,
179c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard            &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0);
180c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard
181a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard    useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs,
182a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard            &ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false);
183a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard
184c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard    maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs,
185c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard            &ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);
186c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard
187050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    // Vr flinger is only enabled on Daydream ready devices.
188050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    useVrFlinger = getBool< ISurfaceFlingerConfigs,
189050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            &ISurfaceFlingerConfigs::useVrFlinger>(false);
190050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
1911971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard    maxFrameBufferAcquiredBuffers = getInt64< ISurfaceFlingerConfigs,
1921971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard            &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2);
1931971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard
1945d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    hasWideColorDisplay =
1955d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
1965d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1998afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
200b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
20150210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
202b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
2058afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
2068afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
2078afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
2088afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
20963f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
21063f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
21163f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
21263f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
2138afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
214c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
215c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
216c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
217c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    property_get("debug.sf.disable_backpressure", value, "0");
218c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    mPropagateBackpressure = !atoi(value);
219c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
2208cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
221642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard    property_get("debug.sf.enable_hwc_vds", value, "0");
222642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard    mUseHwcVirtualDisplays = atoi(value);
223642b23d70f7b513e88680c1d8400c1c1cfe6edd3Fabien Sanglard    ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");
22463a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard
225c65dafa95467f52e7f65350b38e94ab217c008daFabien Sanglard    property_get("ro.sf.disable_triple_buffer", value, "1");
226c65dafa95467f52e7f65350b38e94ab217c008daFabien Sanglard    mLayerTripleBufferingDisabled = atoi(value);
22763a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
23199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
23299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
23399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
23499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
237a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
238a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
239a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
242c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
24399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
24499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
24599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
24613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
24713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
24899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
24999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
250a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
25199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
25299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2531db73f66624e7d151710483dd58e03eed672f064Robert Carrstatic sp<ISurfaceComposerClient> initClient(const sp<Client>& client) {
25496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
25596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
2561db73f66624e7d151710483dd58e03eed672f064Robert Carr        return client;
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2581db73f66624e7d151710483dd58e03eed672f064Robert Carr    return nullptr;
2591db73f66624e7d151710483dd58e03eed672f064Robert Carr}
2601db73f66624e7d151710483dd58e03eed672f064Robert Carr
2611db73f66624e7d151710483dd58e03eed672f064Robert Carrsp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
2621db73f66624e7d151710483dd58e03eed672f064Robert Carr    return initClient(new Client(this));
2631db73f66624e7d151710483dd58e03eed672f064Robert Carr}
2641db73f66624e7d151710483dd58e03eed672f064Robert Carr
2651db73f66624e7d151710483dd58e03eed672f064Robert Carrsp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection(
2661db73f66624e7d151710483dd58e03eed672f064Robert Carr        const sp<IGraphicBufferProducer>& gbp) {
2671db73f66624e7d151710483dd58e03eed672f064Robert Carr    if (authenticateSurfaceTexture(gbp) == false) {
2681db73f66624e7d151710483dd58e03eed672f064Robert Carr        return nullptr;
2691db73f66624e7d151710483dd58e03eed672f064Robert Carr    }
2701db73f66624e7d151710483dd58e03eed672f064Robert Carr    const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
2711db73f66624e7d151710483dd58e03eed672f064Robert Carr    if (layer == nullptr) {
2721db73f66624e7d151710483dd58e03eed672f064Robert Carr        return nullptr;
2731db73f66624e7d151710483dd58e03eed672f064Robert Carr    }
2741db73f66624e7d151710483dd58e03eed672f064Robert Carr
2751db73f66624e7d151710483dd58e03eed672f064Robert Carr   return initClient(new Client(this, layer));
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
278dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
279dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
280e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
281e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
282e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
283e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
284e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
285e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
286e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
287e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
288e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
289e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
290c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit DisplayToken(const sp<SurfaceFlinger>& flinger)
291e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
292e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
293e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
294e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
295e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
296e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
297e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
29853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
2998dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
300e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
301ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
302e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
303e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
304e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
3056c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
3066c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
3076c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
3086c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
3096c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
3106c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
3116c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
3126c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
3136c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
3146c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
3156c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
3166c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
3176c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
3186c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
319ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayDeletion(info.displayId);
3206c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
3216c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
3226c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
3236c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
324692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
3259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("createBuiltinDisplayLocked(%d)", type);
326692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
327692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
328692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
329692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
33053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(type, true);
331692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
332ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
333692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
334692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
335e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
3369e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
337e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
338e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
339e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
340692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
342e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
343f8b4ca51111cd2e566d1774ac464da859db78976Romain Guysp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
344f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy{
345f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
346f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy    return gba;
347f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy}
348f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
351b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    if (mStartBootAnimThread->join() != NO_ERROR) {
352b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang        ALOGE("Join StartBootAnimThread failed!");
353b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    }
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
356a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
3573330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
3581f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3591f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
3601f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
3611f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
3621f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
363921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
3641f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
3651f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
366050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (mVrFlinger) {
367050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      mVrFlinger->OnBootFinished();
368050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    }
369050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
3701f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
371a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
372a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
373a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
3740a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato
3750a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
3760a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
3770a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
381921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
384921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
387921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
388921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
390921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
391921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
392921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3933f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
394921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
395921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
396faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
397faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3985167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3994a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        const char* name) :
4004a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mName(name),
4010a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
4020a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
4034a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
4044a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncEventLabel(String8::format("VSYNC-%s", name)),
405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mDispSync(dispSync),
406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallbackMutex(),
407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallback(),
408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mVsyncMutex(),
409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mPhaseOffset(phaseOffset),
410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mEnabled(false) {}
411faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
412faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
413faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
414faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
415db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
416faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
4174a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
418faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
419faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
420faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
421faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
422faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
4235167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
424faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
425faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
426faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
427faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
428faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
429faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
430faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
4315167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
432faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
433db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mEnabled = enable;
434faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
435faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
436faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
437db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mCallbackMutex);
438faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
439faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
440faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
441db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    virtual void setPhaseOffset(nsecs_t phaseOffset) {
442db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
443db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
444db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Normalize phaseOffset to [0, period)
445db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        auto period = mDispSync->getPeriod();
446db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        phaseOffset %= period;
447db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (phaseOffset < 0) {
448db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // If we're here, then phaseOffset is in (-period, 0). After this
449db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // operation, it will be in (0, period)
450db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            phaseOffset += period;
451db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
452db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mPhaseOffset = phaseOffset;
453db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
454db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // If we're not enabled, we don't need to mess with the listeners
455db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (!mEnabled) {
456db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            return;
457db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
458db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
459db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Remove the listener with the old offset
460db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        status_t err = mDispSync->removeEventListener(
461db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
462db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
463db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error unregistering vsync callback: %s (%d)",
464db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
465db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
466db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
467db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Add a listener with the new offset
4684a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        err = mDispSync->addEventListener(mName, mPhaseOffset,
469db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
470db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
471db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error registering vsync callback: %s (%d)",
472db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
473db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
474db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    }
475db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
476faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
477faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
478faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
479faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
480db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            Mutex::Autolock lock(mCallbackMutex);
481faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
482a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4830a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
4840a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
4855167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
4860a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
487faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
488faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
489faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
490faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
491faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
492faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
493faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4944a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    const char* const mName;
4954a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
496faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
497faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4980a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
4995167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
5005167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
5010a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
502faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
503db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
504db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mCallbackMutex; // Protects the following
505faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
506db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
507db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mVsyncMutex; // Protects the following
508db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    nsecs_t mPhaseOffset;
509db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    bool mEnabled;
510faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
511faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
512c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuclass InjectVSyncSource : public VSyncSource {
513c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjupublic:
514c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    InjectVSyncSource() {}
515c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
516c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual ~InjectVSyncSource() {}
517c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
518c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
519c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
520c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback = callback;
521c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
522c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
523c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void onInjectSyncEvent(nsecs_t when) {
524c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
525c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback->onVSyncEvent(when);
526c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
527c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
528c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setVSyncEnabled(bool) {}
529c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setPhaseOffset(nsecs_t) {}
530c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
531c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuprivate:
532c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    std::mutex mCallbackMutex; // Protects the following
533c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    sp<VSyncSource::Callback> mCallback;
534c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju};
535c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
536faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
537a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
538a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
539a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
5404b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park    ALOGI("Phase offest NS: %" PRId64 "", vsyncPhaseOffsetNs);
5414b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park
5429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    { // Autolock scope
5439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mStateLock);
5449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
5459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // initialize EGL for the default display
5469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
5479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        eglInitialize(mEGLDisplay, NULL, NULL);
548692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
5499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // start the EventThread
5509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
5519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                vsyncPhaseOffsetNs, true, "app");
552ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mEventThread = new EventThread(vsyncSrc, *this, false);
5539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
5549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                sfVsyncPhaseOffsetNs, true, "sf");
555ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
5569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEventQueue.setEventThread(mSFEventThread);
557a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
558acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray        // set SFEventThread to SCHED_FIFO to minimize jitter
55941a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        struct sched_param param = {0};
56035520634e298f53bd8433825640d6999760f25b3Tim Murray        param.sched_priority = 2;
56141a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
56241a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray            ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
56341a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        }
56441a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray
5659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Get a RenderEngine for the given display / config (can't fail)
5669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mRenderEngine = RenderEngine::create(mEGLDisplay,
5679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HAL_PIXEL_FORMAT_RGBA_8888);
5689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
569f9481058101c4e2b38c74048feac383664691d03Saurabh Shah
5709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Drop the state lock while we initialize the hardware composer. We drop
5719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // the lock because on creation, it will call back into SurfaceFlinger to
5729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // initialize the primary display.
573050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
574050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        "Starting with vr flinger active is not currently supported.");
5753cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    mRealHwc = new HWComposer(false);
57687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    mHwc = mRealHwc;
5779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
578b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
5799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mStateLock);
580875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
5815c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott    // Inform native graphics APIs whether the present timestamp is supported:
5825c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott    if (getHwComposer().hasCapability(
5835c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott            HWC2::Capability::PresentFenceIsNotReliable)) {
5845c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott        property_set(kTimestampProperty, "0");
5855c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott    } else {
5865c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott        property_set(kTimestampProperty, "1");
5875c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott    }
5885c34de2c12ab2638fd6b16f1b77dedd0ffa3ab27Ian Elliott
589050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (useVrFlinger) {
590050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
591050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            mVrFlingerRequestsDisplay = requestDisplay;
592050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            signalTransaction();
593050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        };
594050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
595050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas                                            vrFlingerRequestDisplayCallback);
596050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        if (!mVrFlinger) {
597050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            ALOGE("Failed to start vrflinger");
598050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        }
599050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    }
600050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
601875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
602875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
603a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
604da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
605da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
606da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
6079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // make the GLContext current so that we can create textures when creating
6089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layers (which may happens before we render something)
6098d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
610a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
611d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
612d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
613d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
61492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
61592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
6168630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
61713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
61813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
61913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
6204e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza    mRenderEngine->primeCache();
6214e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza
622b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    mStartBootAnimThread = new StartBootAnimThread();
623b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    if (mStartBootAnimThread->Start() != NO_ERROR) {
624b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang        ALOGE("Run StartBootAnimThread failed!");
625b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    }
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Done initializing");
6283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
6293ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
630a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
631b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    // Start boot animation service by setting a property mailbox
632b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    // if property setting thread is already running, Start() will be just a NOP
633b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    mStartBootAnimThread->Start();
634b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    // Wait until property was set
635b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    if (mStartBootAnimThread->join() != NO_ERROR) {
636b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang        ALOGE("Join StartBootAnimThread failed!");
637b254fa3a9eccd5ad7d853d687cf50a68dd8ee41cWei Wang    }
638a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
639a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
640875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
641875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
642a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
643a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
644875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
645875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
646a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
647a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
649d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
650582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
6512adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
652134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
6530d48072f6047140119ff194c1194ce402fca2c0bRobert Carr    return authenticateSurfaceTextureLocked(bufferProducer);
6540d48072f6047140119ff194c1194ce402fca2c0bRobert Carr}
6550d48072f6047140119ff194c1194ce402fca2c0bRobert Carr
6560d48072f6047140119ff194c1194ce402fca2c0bRobert Carrbool SurfaceFlinger::authenticateSurfaceTextureLocked(
6570d48072f6047140119ff194c1194ce402fca2c0bRobert Carr        const sp<IGraphicBufferProducer>& bufferProducer) const {
658097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
6596710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
660134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
661134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
6626b376713907086c9642e7b7e66e51ddfa531b003Brian Andersonstatus_t SurfaceFlinger::getSupportedFrameTimestamps(
6636b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        std::vector<FrameEvent>* outSupported) const {
6646b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    *outSupported = {
6656b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::REQUESTED_PRESENT,
6666b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::ACQUIRE,
6676b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::LATCH,
6686b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::FIRST_REFRESH_START,
6696b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::LAST_REFRESH_START,
6706b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::GPU_COMPOSITION_DONE,
6716b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::DEQUEUE_READY,
6726b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        FrameEvent::RELEASE,
6736b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    };
6746b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    if (!getHwComposer().hasCapability(
6756b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            HWC2::Capability::PresentFenceIsNotReliable)) {
6766b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        outSupported->push_back(FrameEvent::DISPLAY_PRESENT);
6776b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    }
6786b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    return NO_ERROR;
6796b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson}
6806b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson
6817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
6827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
68323e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa    if ((configs == NULL) || (display.get() == NULL)) {
6847f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
6857f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
6867f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6877aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
6887aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
6897aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
690692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
6919e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
692692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
6931604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
6941604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
6951604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6961604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
6971604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6981604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
6991604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
700c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
7018b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
7028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
7038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
7048b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
7058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
7068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
7078b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
7088b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
7098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
7108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
7118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
7128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
7138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
7148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
7158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
7168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
7178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
7181604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
7197f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
7207f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
7227f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
7237f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float xdpi = hwConfig->getDpiX();
7259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float ydpi = hwConfig->getDpiY();
7267f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7277f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
7287f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
7297f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
7307f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
7317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
7327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
7337f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
7347f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
7357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
7367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
7377f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
7387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
7397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
7407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
7417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
7427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
7448d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            {
7458d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                Mutex::Autolock _l(mStateLock);
7468d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
7478d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                info.orientation = hw->getOrientation();
7488d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            }
7497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
7507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
7517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
7527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
7537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
7541604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
7557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.w = hwConfig->getWidth();
7579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.h = hwConfig->getHeight();
7587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
7597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
7609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.fps = 1e9 / hwConfig->getVsyncPeriod();
7614b20c2ee8e51006db51bbe1391f9173230bb73d2Jiyong Park        info.appVsyncOffset = vsyncPhaseOffsetNs;
7629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
76391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
76491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
76591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
76691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
76791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
76891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
76991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
77091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
77191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
77291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
77391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
77491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
7759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.presentationDeadline = hwConfig->getVsyncPeriod() -
7760cc1938871edd6659d6783404a3523abc6b98d92Fabien Sanglard                sfVsyncPhaseOffsetNs + 1000000;
7777f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
7787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
7797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
7807f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
78128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        configs->push_back(info);
7828b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
7838b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
7847f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
7857f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
786dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
78789fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
78867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
78967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
79067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
79167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
79267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
79367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
79467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
79567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
79667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
79767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
79867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
79967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
8006c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
8019f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    if (display == NULL) {
8029f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        ALOGE("%s : display is NULL", __func__);
8039f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong        return BAD_VALUE;
8049f8b9ae2a95eec78e676a11a719deafea4952190Jinguang Dong    }
8058d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
8068d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    Mutex::Autolock _l(mStateLock);
80724a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    sp<DisplayDevice> device(getDisplayDevice(display));
80824a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
80924a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
81024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
8118d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
81224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
8137f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
814dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
8156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
8166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
8176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
8186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
8196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
8206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
8216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
8226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
8236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
8246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
8256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
8266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
8276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
8286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
8296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
8306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
8316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
8326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
8336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
8346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
8356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
8366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
8376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
8386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
8396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
8406c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
8416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
8426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
8436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
8446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
8457306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
8467306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
847784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
8489ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
8497306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
85028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
8517306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
8526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
8536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
8546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
8557306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
8566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
8576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
8586c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
8596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
8606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
8616c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
8626c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
8636c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
8646c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
8656c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
8666c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
867888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
868c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
86928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
87028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        Vector<android_color_mode_t>* outColorModes) {
87128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if ((outColorModes == nullptr) || (display.get() == nullptr)) {
87228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return BAD_VALUE;
87328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
87428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
87528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (!display.get()) {
87628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return NAME_NOT_FOUND;
87728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
87828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
87928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = NAME_NOT_FOUND;
88028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
88128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        if (display == mBuiltinDisplays[i]) {
88228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            type = i;
88328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            break;
88428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
88528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
88628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
88728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type < 0) {
88828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return type;
88928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
89028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
89128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
89228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    outColorModes->clear();
89328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
89428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
89528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
89628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
89728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
89828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
8998d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    Mutex::Autolock _l(mStateLock);
90028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<DisplayDevice> device(getDisplayDevice(display));
90128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (device != nullptr) {
90228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return device->getActiveColorMode();
90328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
90428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return static_cast<android_color_mode_t>(BAD_VALUE);
90528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
90628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
90728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
90828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mode) {
90928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = hw->getDisplayType();
91028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t currentMode = hw->getActiveColorMode();
91128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
91228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (mode == currentMode) {
91328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
91428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
91528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
91628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
91728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGW("Trying to set config for virtual display");
91828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
91928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
92028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
9215d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    ALOGD("Set active color mode: %s (%d), type=%d", decodeColorMode(mode).c_str(), mode,
9225d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter          hw->getDisplayType());
9235d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
92428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    hw->setActiveColorMode(mode);
92528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    getHwComposer().setActiveColorMode(type, mode);
92628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
92728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
92828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
92928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
93028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t colorMode) {
93128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    class MessageSetActiveColorMode: public MessageBase {
93228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        SurfaceFlinger& mFlinger;
93328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        sp<IBinder> mDisplay;
93428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mMode;
93528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    public:
93628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
93728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                               android_color_mode_t mode) :
93828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
93928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        virtual bool handler() {
94028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            Vector<android_color_mode_t> modes;
94128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger.getDisplayColorModes(mDisplay, &modes);
94228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
94328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (mMode < 0 || !exists) {
9445d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                ALOGE("Attempt to set invalid active color mode %s (%d) for display %p",
9455d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      decodeColorMode(mMode).c_str(), mMode, mDisplay.get());
94628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
94728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
94828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
94928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (hw == nullptr) {
9505d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                ALOGE("Attempt to set active color mode %s (%d) for null display %p",
9515d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      decodeColorMode(mMode).c_str(), mMode, mDisplay.get());
95228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
9535d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                ALOGW("Attempt to set active color mode %s %d for virtual display",
9545d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      decodeColorMode(mMode).c_str(), mMode);
95528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else {
95628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                mFlinger.setActiveColorModeInternal(hw, mMode);
95728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
95828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return true;
95928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
96028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    };
96128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode);
96228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    postMessageSync(msg);
96328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
96428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
965c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
966d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
967d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
968d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
969d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
970d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
971d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
972d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
973d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
974d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
975d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
976d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
977d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
978c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display,
979c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        HdrCapabilities* outCapabilities) const {
980c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    Mutex::Autolock _l(mStateLock);
981c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
982c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    sp<const DisplayDevice> displayDevice(getDisplayDevice(display));
983c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (displayDevice == nullptr) {
984c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get());
985c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
986c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
987c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
988c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities =
989c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza            mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
990c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (capabilities) {
991c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        std::swap(*outCapabilities, *capabilities);
992c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    } else {
993c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
994c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
995c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
996c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return NO_ERROR;
997c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
998c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
999c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) {
1000c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable == mInjectVSyncs) {
1001c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return NO_ERROR;
1002c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
1003c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
1004c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable) {
1005c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
1006c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections enabled");
1007c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        if (mVSyncInjector.get() == nullptr) {
1008c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju            mVSyncInjector = new InjectVSyncSource();
1009ab04685578b254c2eaf43bf5da85e5e922787825Irvel            mInjectorEventThread = new EventThread(mVSyncInjector, *this, false);
1010c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        }
1011c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mInjectorEventThread);
1012c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    } else {
1013c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
1014c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections disabled");
1015c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mSFEventThread);
1016c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector.clear();
1017c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
1018c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
1019c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
1020c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
1021c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) {
1022c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (!mInjectVSyncs) {
1023c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGE("VSync Injections not enabled");
1024c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return BAD_VALUE;
1025c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
1026c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) {
1027c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("Injecting VSync inside SurfaceFlinger");
1028c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector->onInjectSyncEvent(when);
1029c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
1030c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
1031c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
1032c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
1033d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
1034d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
1035d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
10368aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
1037bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
1038bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
104099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
104199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
104299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
104399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
104499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
104599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
104699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
104799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
104899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
104999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
105099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
105199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
105299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
105399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
105499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
105599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
105699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
105799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
1058c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
105999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
106099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
106199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
106299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
1063c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
106499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
106599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
106699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
106799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
106899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
106999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10714f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
10724f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
10734f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
10744f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
107599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1077faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
1078faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1079948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
1080faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
1081d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
1082d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
1083faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
108443601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
1085faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1086faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1087948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
1088faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1089faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1090948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
1091948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
1092948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
10930a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // Hardware vsync is not currently available, so abort the resync
10940a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // attempt for now
1095948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
1096948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1097948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
10989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
10999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
1100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
1102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
1103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
1105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
1106d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
1107d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
1108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
1109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1112948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
1113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
1115d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
1116d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
1117faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
1118faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
1119faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1120948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
1121948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
1122948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1123faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1124faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
11254a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() {
11264a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
11274a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    if (systemTime() - mLastSwapTime > kIgnoreDelay) {
11280a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        resyncToHardwareVsync(false);
11294a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    }
11304a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray}
11314a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
11323cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type,
11333cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas                                     nsecs_t timestamp) {
11343cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    Mutex::Autolock lock(mStateLock);
11353cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    // Ignore any vsyncs from the non-active hardware composer.
11363cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    if (composer != mHwc) {
11373cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        return;
11383cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    }
11393cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas
1140d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
1141faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1142d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
1143d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
1144d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
1145d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
1146faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1147148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
1148d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
1149d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
1150d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
1151d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
1152d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
1153d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
1154148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
1155148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
11560a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
1157d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
11580a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    *compositorTiming = mCompositorTiming;
11590a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
11600a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
11618d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazykvoid SurfaceFlinger::createDefaultDisplayDevice() {
11628d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    const int32_t type = DisplayDevice::DISPLAY_PRIMARY;
11638d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    wp<IBinder> token = mBuiltinDisplays[type];
11645d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
11658d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    // All non-virtual displays are currently considered secure.
11668d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    const bool isSecure = true;
11678d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
11688d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    sp<IGraphicBufferProducer> producer;
11698d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    sp<IGraphicBufferConsumer> consumer;
11708d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    BufferQueue::createBufferQueue(&producer, &consumer, new GraphicBufferAlloc());
11718d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
11728d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);
11738d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
11748d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    bool hasWideColorModes = false;
11758d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(
11768d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        type);
11778d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    for (android_color_mode_t colorMode : modes) {
11788d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        switch (colorMode) {
11798d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            case HAL_COLOR_MODE_DISPLAY_P3:
11808d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            case HAL_COLOR_MODE_ADOBE_RGB:
11818d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            case HAL_COLOR_MODE_DCI_P3:
11828d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                hasWideColorModes = true;
11838d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                break;
11848d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            default:
11858d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                break;
11865d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        }
11878d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    }
11888d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,
11898d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                                             token, fbs, producer, mRenderEngine->getEGLConfig(),
11908d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                                             hasWideColorModes && hasWideColorDisplay);
11918d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    mDisplays.add(token, hw);
11928d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
11938d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    if (hasWideColorModes && hasWideColorDisplay) {
11948d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        defaultColorMode = HAL_COLOR_MODE_SRGB;
11958d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    }
11968d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    setActiveColorModeInternal(hw, defaultColorMode);
11978d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk}
11985576a555a14edd8c76addce2cee37b9b9ced2c3fStephen Kiazyk
11998d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazykvoid SurfaceFlinger::onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) {
12008d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
120180c02320c49f5f6e1cb2651620fa31de551502a7Polina Bondarenko
12028d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    if (composer->isUsingVrComposer()) {
12038d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        // We handle initializing the primary display device for the VR
12048d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        // window manager hwc explicitly at the time of transition.
12058d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        if (disp != DisplayDevice::DISPLAY_PRIMARY) {
12068d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            ALOGE("External displays are not supported by the vr hardware composer.");
120780c02320c49f5f6e1cb2651620fa31de551502a7Polina Bondarenko        }
12088d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        return;
12098d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    }
12108d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
12118d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    if (disp == DisplayDevice::DISPLAY_PRIMARY) {
12128d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        Mutex::Autolock lock(mStateLock);
12138d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
12148d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        createDefaultDisplayDevice();
12159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
12169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto type = DisplayDevice::DISPLAY_EXTERNAL;
12179e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
1218692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
12199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            createBuiltinDisplayLocked(type);
12209e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
1221692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
1222692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
12239e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
12249e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
12259e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
12269e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
12273ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
12288630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
12298630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
12303cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid SurfaceFlinger::onInvalidateReceived(HWComposer* composer) {
12313cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    Mutex::Autolock lock(mStateLock);
12323cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    if (composer == mHwc) {
12333cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        repaintEverything();
12343cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    } else {
12353cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        // This isn't from our current hardware composer. If it's a callback
12363cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        // from the real composer, forward the refresh request to vr
12373cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        // flinger. Otherwise ignore it.
12383cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        if (!composer->isUsingVrComposer()) {
12393cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas            mVrFlinger->OnHardwareComposerRefresh();
12403cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas        }
12413cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas    }
12423cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas}
12433cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas
12449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
1245faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
12469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    getHwComposer().setVsyncEnabled(disp,
12479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
12488630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
12498630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
125087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaarvoid SurfaceFlinger::clearHwcLayers(const LayerVector& layers) {
125187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    for (size_t i = 0; i < layers.size(); ++i) {
125287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        layers[i]->clearHwcLayers();
125387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    }
125487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
125587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12568d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk// Note: it is assumed the caller holds |mStateLock| when this is called
125787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaarvoid SurfaceFlinger::resetHwc() {
125887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    disableHardwareVsync(true);
125987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    clearHwcLayers(mDrawingState.layersSortedByZ);
126087670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    clearHwcLayers(mCurrentState.layersSortedByZ);
126187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // Clear the drawing state so that the logic inside of
126287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // handleTransactionLocked will fire. It will determine the delta between
126387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // mCurrentState and mDrawingState and re-apply all changes when we make the
126487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    // transition.
126587670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    mDrawingState.displays.clear();
126687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    mDisplays.clear();
1267050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    initializeDisplays();
126887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
126987670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
1270050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid SurfaceFlinger::updateVrFlinger() {
1271050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (!mVrFlinger)
1272050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        return;
1273050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay;
1274050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
1275209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        return;
1276209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus    }
12778d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
12788d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    bool vrHwcNewlyInitialized = false;
12798d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
1280050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (vrFlingerRequestsDisplay && !mVrHwc) {
1281209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        // Construct new HWComposer without holding any locks.
1282209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        mVrHwc = new HWComposer(true);
12838d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        vrHwcNewlyInitialized = true;
1284209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus        ALOGV("Vr HWC created");
1285209beca0f051ff56654c2027f2e281c8a73d1686Mark Urbanus    }
128687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12878d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    Mutex::Autolock _l(mStateLock);
128887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12898d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    if (vrFlingerRequestsDisplay) {
12908d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        resetHwc();
129187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12928d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        mHwc = mVrHwc;
12938d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        mVrFlinger->GrantDisplayOwnership();
129487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
12958d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        if (vrHwcNewlyInitialized) {
12968d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            mVrHwc->setEventHandler(
12978d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                static_cast<HWComposer::EventHandler*>(this));
129887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar        }
12998d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    } else {
13008d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        mVrFlinger->SeizeDisplayOwnership();
130187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
13028d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        resetHwc();
13038d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
13048d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        mHwc = mRealHwc;
13058d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk        enableHardwareVsync();
130687670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar    }
13078d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
13088d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    mVisibleRegionsDirty = true;
13098d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    invalidateHwcGeometry();
13108d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
13118d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    // Explicitly re-initialize the primary display. This is because some other
13128d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    // parts of this class rely on the primary display always being available.
13138d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    createDefaultDisplayDevice();
13148d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
13158d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    android_atomic_or(1, &mRepaintEverything);
13168d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    setTransactionFlags(eDisplayTransactionNeeded);
131787670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar}
131887670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
13194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
13201c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
132199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
13226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
13235018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            bool frameMissed = !mHadClientComposition &&
13245018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence != Fence::NO_FENCE &&
13250a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                    (mPreviousPresentFence->getSignalTime() ==
13260a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson                            Fence::SIGNAL_TIME_PENDING);
13275018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
1328c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza            if (mPropagateBackpressure && frameMissed) {
1329af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                ALOGD("Backpressure trigger, skipping transaction & refresh!");
13305018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                signalLayerUpdate();
13315018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                break;
13325018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            }
13335018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza
1334050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            // Now that we're going to make it to the handleMessageTransaction()
1335050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            // call below it's safe to call updateVrFlinger(), which will
1336050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            // potentially trigger a display handoff.
1337050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            updateVrFlinger();
1338050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
13396b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
13406b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
13415878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
13426b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
13435878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
13445878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
13455878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
13466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
13476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
13486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
13496b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
13506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
13516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
13526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
13536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
13544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
13554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13576b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
1358c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglard    uint32_t transactionFlags = peekTransactionFlags();
13594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
136087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
13616b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
13624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
13636b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
13644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13666b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
1367cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
13686b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
13694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
13703a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
13714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
1372cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
137314cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
137440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
137505dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
1376d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    preComposition(refreshStartTime);
137705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    rebuildLayerStacks();
137805dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    setUpHWComposer();
137905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doDebugFlashRegions();
138005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doComposition();
13810a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    postComposition(refreshStartTime);
138205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
138311d0fc38ad8d2e5bb5bc0a282336cabe28dbf9d6Fabien Sanglard    mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
1384bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza
1385bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    mHadClientComposition = false;
1386bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
1387bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
1388bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        mHadClientComposition = mHadClientComposition ||
1389bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
1390bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    }
139114cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
13929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mLayersWithQueuedFrames.clear();
1393cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1394cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1395cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
1396cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
1397cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
1398cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
1399cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
1400cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1401cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
1402cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1403cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
14042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1405cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1406cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
1407cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
1408cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
1409cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
1410cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1411cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
1412cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
14133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
14143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
14153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1416da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
1417cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
1418cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1419cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1420cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1421cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
1422cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1423cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
1424cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
1425cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1426bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
14279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14287bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
14297bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
14307bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
14317bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
14327bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
14337bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
14349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
14359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
1436bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
1437cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1438cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1439d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
1440cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
14419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
14429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("preComposition");
14439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1444cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
14452047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
14462047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        if (layer->onPreComposition(refreshStartTime)) {
1447cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
1448cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
14492047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
14502047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
1451cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
1452cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
1453cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1454cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1455a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
14560a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::updateCompositorTiming(
14570a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
14580a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        std::shared_ptr<FenceTime>& presentFenceTime) {
14590a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Update queue of past composite+present times and determine the
14600a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // most recently known composite to present latency.
14610a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    mCompositePresentTimes.push({compositeTime, presentFenceTime});
14620a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t compositeToPresentLatency = -1;
14630a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    while (!mCompositePresentTimes.empty()) {
14640a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        CompositePresentTime& cpt = mCompositePresentTimes.front();
14650a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // Cached values should have been updated before calling this method,
14660a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        // which helps avoid duplicate syscalls.
14670a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        nsecs_t displayTime = cpt.display->getCachedSignalTime();
14680a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        if (displayTime == Fence::SIGNAL_TIME_PENDING) {
14690a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            break;
14700a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        }
14710a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        compositeToPresentLatency = displayTime - cpt.composite;
14720a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        mCompositePresentTimes.pop();
14730a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
14740a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
14750a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Don't let mCompositePresentTimes grow unbounded, just in case.
14760a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    while (mCompositePresentTimes.size() > 16) {
14770a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        mCompositePresentTimes.pop();
14780a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    }
14790a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
1480d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    setCompositorTimingSnapped(
1481d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson            vsyncPhase, vsyncInterval, compositeToPresentLatency);
1482d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson}
1483d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson
1484d001058145c2186f454a3fb043388d6d9b84c9d8Brian Andersonvoid SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
1485d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) {
14860a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Integer division and modulo round toward 0 not -inf, so we need to
14870a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // treat negative and positive offsets differently.
1488d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ?
14890a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) :
14900a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson            ((-sfVsyncPhaseOffsetNs) % vsyncInterval);
14910a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
1492d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval.
1493d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    if (idealLatency <= 0) {
1494d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        idealLatency = vsyncInterval;
1495d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    }
1496d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson
14970a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Snap the latency to a value that removes scheduling jitter from the
14980a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // composition and present times, which often have >1ms of jitter.
14990a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Reducing jitter is important if an app attempts to extrapolate
15000a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // something (such as user input) to an accurate diasplay time.
15010a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs
15020a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // with (presentLatency % interval).
1503d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    nsecs_t bias = vsyncInterval / 2;
1504d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    int64_t extraVsyncs =
1505d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson            (compositeToPresentLatency - idealLatency + bias) / vsyncInterval;
1506d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
1507d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson            idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
15080a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
1509d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
15100a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    mCompositorTiming.deadline = vsyncPhase - idealLatency;
15110a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    mCompositorTiming.interval = vsyncInterval;
1512d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
15130a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson}
15140a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
15150a61b0c813f5991bf462e36a2314dda062727a10Brian Andersonvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
1516cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
15179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
15189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postComposition");
15199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
15203546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    // Release any buffers which were replaced this frame
1521f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson    nsecs_t dequeueReadyTime = systemTime();
15223546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    for (auto& layer : mLayersWithQueuedFrames) {
1523f6386862dffb0fb9cb39343d959104a32e5e95b7Brian Anderson        layer->releasePendingBuffer(dequeueReadyTime);
15243546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson    }
15253546a3f08ad84099db4006d651c656d58d2ed566Brian Anderson
15268d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    // |mStateLock| not needed as we are on the main thread
15278d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    const sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
15283d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
15293d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
15303d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
15313d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime =
15323d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson                std::make_shared<FenceTime>(hw->getClientTargetAcquireFence());
15333d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
15343d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    } else {
15353d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson        glCompositionDoneFenceTime = FenceTime::NO_FENCE;
15363d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    }
15373d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mGlCompositionDoneTimeline.updateSignalTimes();
15383d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
15394e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    sp<Fence> presentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
15404e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    auto presentFenceTime = std::make_shared<FenceTime>(presentFence);
15414e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    mDisplayTimeline.push(presentFenceTime);
15423d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson    mDisplayTimeline.updateSignalTimes();
15433d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson
15440a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
15450a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod();
15460a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
15470a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // We use the refreshStartTime which might be sampled a little later than
15480a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // when we started doing work for this frame, but that should be okay
15490a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    // since updateCompositorTiming has snapping logic.
15500a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson    updateCompositorTiming(
15514e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson        vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime);
1552d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    CompositorTiming compositorTiming;
1553d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    {
1554d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        std::lock_guard<std::mutex> lock(mCompositorTimingLock);
1555d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson        compositorTiming = mCompositorTiming;
1556d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    }
15570a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
15582047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
15592047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
15604e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson                presentFenceTime, compositorTiming);
1561e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (frameLatched) {
15622047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            recordBufferingStats(layer->getName().string(),
15632047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                    layer->getOccupancyHistory(false));
1564e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
15652047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
15664b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
15674e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson    if (presentFence->isValid()) {
15684e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson        if (mPrimaryDispSync.addPresentFence(presentFence)) {
1569faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1570faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
1571948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
1572faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1573faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1574faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1575cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    if (!hasSyncFramework) {
15762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1577faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1578faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1579faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1580faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
15814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
15824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
15834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
15844e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson        if (presentFenceTime->isValid()) {
15853d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson            mAnimFrameTracker.setActualPresentFence(
15864e606e3901b500bdd0f3ea21b8cb63734087bf0aBrian Anderson                    std::move(presentFenceTime));
15874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
15884b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
15894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
15909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            nsecs_t presentTime =
15919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
15924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
15934b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
15944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
15954b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
1596b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1597b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
1598b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        return;
1599b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1600b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1601b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    nsecs_t currentTime = systemTime();
1602b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (mHasPoweredOff) {
1603b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = false;
1604b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    } else {
1605b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t elapsedTime = currentTime - mLastSwapTime;
16060a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson        size_t numPeriods = static_cast<size_t>(elapsedTime / vsyncInterval);
1607b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        if (numPeriods < NUM_BUCKETS - 1) {
1608b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[numPeriods] += elapsedTime;
1609b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        } else {
1610b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
1611b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        }
1612b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime += elapsedTime;
1613b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1614b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    mLastSwapTime = currentTime;
1615cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1616cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1617cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
16189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
16199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("rebuildLayerStacks");
16209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1621cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
1622764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
1623764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        ATRACE_CALL();
1624764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        mVisibleRegionsDirty = false;
1625764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        invalidateHwcGeometry();
1626ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
1627764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1628764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            Region opaqueRegion;
1629764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            Region dirtyRegion;
1630764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            Vector<sp<Layer>> layersSortedByZ;
1631764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
1632764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            const Transform& tr(displayDevice->getTransform());
1633764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            const Rect bounds(displayDevice->getBounds());
1634764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            if (displayDevice->isDisplayOn()) {
1635764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                computeVisibleRegions(
1636764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        displayDevice->getLayerStack(), dirtyRegion,
1637764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        opaqueRegion);
1638764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey
1639764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                mDrawingState.traverseInZOrder([&](Layer* layer) {
1640764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                    if (layer->getLayerStack() == displayDevice->getLayerStack()) {
1641764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        Region drawRegion(tr.transform(
1642764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                                layer->visibleNonTransparentRegion));
1643764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        drawRegion.andSelf(bounds);
1644764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        if (!drawRegion.isEmpty()) {
1645764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            layersSortedByZ.add(layer);
1646764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        } else {
1647764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            // Clear out the HWC layer if this layer was
1648764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            // previously visible, but no longer is
1649764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                            layer->setHwcLayer(displayDevice->getHwcDisplayId(),
1650764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                                    nullptr);
1651764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                        }
165206a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard                    } else {
16538226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard                        // WM changes displayDevice->layerStack upon sleep/awake.
16548226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard                        // Here we make sure we delete the HWC layers even if
16558226051f627aa976700885cda28c26c5a5b8bc7bFabien Sanglard                        // WM changed their layer stack.
165606a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard                        layer->setHwcLayer(displayDevice->getHwcDisplayId(),
165706a76c022fcb87602e160ffa97b26a27cc1a5481Fabien Sanglard                                nullptr);
165887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
1659764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                });
1660764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            }
1661764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
1662764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->undefinedRegion.set(bounds);
1663764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->undefinedRegion.subtractSelf(
1664764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey                    tr.transform(opaqueRegion));
1665764881145a75987d3e832aa0b850d8ed381e7ccaJeff Sharkey            displayDevice->dirtyRegion.orSelf(dirtyRegion);
16663b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
16673b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1668cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
16693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
16705d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter// pickColorMode translates a given dataspace into the best available color mode.
16715d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter// Currently only support sRGB and Display-P3.
16725d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchterandroid_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) {
16735d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    switch (dataSpace) {
16745d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        // treat Unknown as regular SRGB buffer, since that's what the rest of the
16755d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        // system expects.
16765d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        case HAL_DATASPACE_UNKNOWN:
16775d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        case HAL_DATASPACE_SRGB:
16785d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        case HAL_DATASPACE_V0_SRGB:
16795d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            return HAL_COLOR_MODE_SRGB;
16805d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            break;
16815d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
16825d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        case HAL_DATASPACE_DISPLAY_P3:
16835d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            return HAL_COLOR_MODE_DISPLAY_P3;
16845d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            break;
16855d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
16865d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        default:
16875d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            // TODO (courtneygo): Do we want to assert an error here?
16885d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            ALOGE("No color mode mapping for %s (%#x)", dataspaceDetails(dataSpace).c_str(),
16895d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                  dataSpace);
16905d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            return HAL_COLOR_MODE_SRGB;
16915d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            break;
16925d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    }
16935d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter}
16945d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
16955d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchterandroid_dataspace SurfaceFlinger::bestTargetDataSpace(android_dataspace a, android_dataspace b) {
16965d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    // Only support sRGB and Display-P3 right now.
16975d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    if (a == HAL_DATASPACE_DISPLAY_P3 || b == HAL_DATASPACE_DISPLAY_P3) {
16985d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        return HAL_DATASPACE_DISPLAY_P3;
16995d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    }
17005d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter    return HAL_DATASPACE_V0_SRGB;
17015d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter}
17025d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
1703cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
17049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
17059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setUpHWComposer");
17069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1707028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1708b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1709b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1710b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1711b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1712b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1713b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1714b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1715b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1716b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1717b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1718b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1719b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1720b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1721b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1722b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1723b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1724b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1725b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1726b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1727b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1728b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
17297143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1730b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1731b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1732b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1733b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1734028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1735028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
17369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // build the h/w work list
17379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (CC_UNLIKELY(mGeometryInvalid)) {
17389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid = false;
17399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
17409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
17419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const auto hwcId = displayDevice->getHwcDisplayId();
17429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (hwcId >= 0) {
17439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const Vector<sp<Layer>>& currentLayers(
17449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getVisibleLayersSortedByZ());
1745ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                for (size_t i = 0; i < currentLayers.size(); i++) {
17461f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    const auto& layer = currentLayers[i];
17479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (!layer->hasHwcLayer(hwcId)) {
17489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        auto hwcLayer = mHwc->createLayer(hwcId);
17499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (hwcLayer) {
17509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(hwcId, std::move(hwcLayer));
17519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
17529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->forceClientComposition(hwcId);
17539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            continue;
1754a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1755a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1756a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
1757ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                    layer->setGeometry(displayDevice, i);
17589f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    if (mDebugDisableHWC || mDebugRegion) {
17599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->forceClientComposition(hwcId);
176003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
176103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
176203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
176303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
17649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
176503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
17669f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
17679f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 colorMatrix = mColorMatrix * mDaltonizer();
17689f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
17699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Set the per-frame data
17709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
17719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
17729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
17735d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
17749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId < 0) {
17759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            continue;
17769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
17779f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        if (colorMatrix != mPreviousColorMatrix) {
17789f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
17799f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
17809f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    "display %zd: %d", displayId, result);
17819f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        }
17829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
17839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setPerFrameData(displayDevice);
178438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
17855d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
17865d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        if (hasWideColorDisplay) {
17875d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            android_color_mode newColorMode;
17885d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB;
17895d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
17905d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
17915d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace);
17925d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)",
17935d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(),
17945d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                      layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace);
17955d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            }
17965d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            newColorMode = pickColorMode(newDataSpace);
17975d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter
17985d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter            setActiveColorModeInternal(displayDevice, newColorMode);
17995d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        }
180052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
18019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
18029f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mPreviousColorMatrix = colorMatrix;
18039f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
18049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
18057bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
18067bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
18077bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
18087bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
18097bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
18107bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
18119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
18129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
18139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1814cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
181552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1816cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1817cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
18189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposition");
18199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
182052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
182192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
18224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
18232c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1824cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1825cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
182602b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
182702b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
182802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
182902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1830cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1831cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1832cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
183387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
18344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
183552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1840841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
18419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postFramebuffer");
1842b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1843a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1844a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1845c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
18469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
18479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
18487bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
18497bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
18507bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
18519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
18529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
1853a87aa7bb5e44fd4b352e34d3cd745aa7e038d19fFabien Sanglard            mHwc->presentAndGetReleaseFences(hwcId);
18549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
18552dc3be88bd85791556ab0e6df6a080989886749eDan Stoza        displayDevice->onSwapBuffersCompleted();
1856b2c838b7add20c4515966a80de809b0a1d315001Season Li        displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
18579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
18589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<Fence> releaseFence = Fence::NO_FENCE;
18599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
18609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = displayDevice->getClientTargetAcquireFence();
18619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
18629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto hwcLayer = layer->getHwcLayer(hwcId);
18639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
186452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
18659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->onLayerDisplayed(releaseFence);
18669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
18679e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
18689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->clearReleaseFences(hwcId);
1869ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1870e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1871e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1872a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1873a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
18746547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
18758d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    // |mStateLock| not needed as we are on the main thread
18768d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount();
18776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
18786547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
18796547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
188287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1884841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1885841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
18867cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
18877cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
18887cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
18897cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
18907cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
18917cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1892ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1893ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1894ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1895ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1896ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1897ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1898ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1899ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1900ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1901ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1902e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
190387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1904ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1905ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1906ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1907ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1908ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
19093d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
191187baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
19123d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
19137dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // Notify all layers of available frames
19142047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([](Layer* layer) {
19152047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        layer->notifyAvailableFrames();
19162047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
19177dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
19242047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
1925edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
19262047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            if (!trFlags) return;
1927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1928edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1930edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
19312047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
1932edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1933edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1934edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
19353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1937edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1938e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
193992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
194092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
194192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1942e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1943e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
194492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
194692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
194793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
194892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
194992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
195092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
195192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
195292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
195392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1954e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1955e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
195692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
19573ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
195827ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
195927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
196027ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
19618d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
1962875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
196302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
196402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
196502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
19669e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
19677adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
196802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
196992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
197092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
197192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
197292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
197392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1974e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
19753ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1976097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
1977097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
19781474f8864faafebc92ff79959bb5c698bd29b704Dan Albert                    if (state_binder != draw_binder) {
1979e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
198093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
198193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
198293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
198302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
198402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
198502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
198693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
198793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
198893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
198993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
199093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
199192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
199293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1993db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
199493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
199593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
199693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
199793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
199800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
199900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
200000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
200100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
200200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
20034fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
200493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
200547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
200647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
200747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
200892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
200992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
201092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
201192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
201292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
201392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
201492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
2015e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
2016e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
2017cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
201899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
2019db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
2020b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
2021b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
2022f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
2023f8b4ca51111cd2e566d1774ac464da859db78976Romain Guy                            new GraphicBufferAlloc());
2024db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
20259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    int32_t hwcId = -1;
202699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
202702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
202802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
202902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
203099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
2031db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
20325cee136dd4f9ee18ea600f0dc6e6f45f786cd097Alex Sakhartchouk                            // Allow VR composer to use virtual displays.
20335cee136dd4f9ee18ea600f0dc6e6f45f786cd097Alex Sakhartchouk                            if (mUseHwcVirtualDisplays || mHwc == mVrHwc) {
20348cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int width = 0;
20358cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int status = state.surface->query(
20368cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_WIDTH, &width);
20378cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
20388cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query width (%d)", status);
20398cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int height = 0;
20408cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
20418cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_HEIGHT, &height);
20428cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
20438cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query height (%d)", status);
20448cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int intFormat = 0;
20458cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
20468cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_FORMAT, &intFormat);
20478cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
20488cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query format (%d)", status);
20498cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                auto format = static_cast<android_pixel_format_t>(
20508cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        intFormat);
20518cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
20528cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                mHwc->allocateVirtualDisplay(width, height, &format,
20538cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        &hwcId);
20548cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                            }
20559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
20565cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            // TODO: Plumb requested format back up to consumer
20575cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza
20589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            sp<VirtualDisplaySurface> vds =
20599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    new VirtualDisplaySurface(*mHwc,
20609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            hwcId, state.surface, bqProducer,
20619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            bqConsumer, state.displayName);
2062db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
2063db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
206447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
206599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
206699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
2067cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
2068cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
2069cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
2070cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
207187670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar
207287670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar                        hwcId = state.type;
207387670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar                        dispSurface = new FramebufferSurface(*mHwc, hwcId, bqConsumer);
207487670ffe26079eb50b62f698eb0f7bfa8ee51debHendrik Wagenaar                        producer = bqProducer;
2075cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
2076cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
2077cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
207899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
20795d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                        sp<DisplayDevice> hw =
20805d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                                new DisplayDevice(this, state.type, hwcId, state.isSecure, display,
20815d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                                                  dispSurface, producer,
20825d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                                                  mRenderEngine->getEGLConfig(),
20835d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter                                                  hasWideColorDisplay);
2084cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
2085cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
20864fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
20878dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
2088cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
20899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (!state.isVirtualDisplay()) {
20907adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
20911c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
209293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
209392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
209492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
2095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
20963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
2097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
20998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
21008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
21018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
21028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
21038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
21048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
21058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
21068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
21078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
21088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
21098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
21108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
21118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
21128430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
21138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
21148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
21158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
21168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
21178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
21188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
21198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
21202047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        bool first = true;
21212047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
21228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
21238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
21248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
21251f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            uint32_t layerStack = layer->getLayerStack();
21262047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            if (first || currentlayerStack != layerStack) {
21278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
21288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
21298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
21308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
21318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
21328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
21338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
21348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
21358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
21368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
21378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
213891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
21398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
21408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
21418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
21428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
21438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
214491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
214591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
214691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
214791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
214891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
214991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
215091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
21518d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                disp = getDefaultDisplayDeviceLocked();
21528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
215391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
21542047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
21552047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            first = false;
21562047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
21578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
21588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
21598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
21603559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
21613559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
21623559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
21631f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
21641f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    if (mLayersAdded) {
21651f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded = false;
21661f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        // Layers have been added.
21673559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
21683559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
21693559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
21703559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
21713559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
21723559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
21733559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
21743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
21752047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mDrawingState.traverseInZOrder([&](Layer* layer) {
21761f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (mLayersPendingRemoval.indexOf(layer) >= 0) {
21773559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
21783559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
21793559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
21803559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
21811f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                Region visibleReg;
21821f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                visibleReg.set(layer->computeScreenBounds());
21831f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                invalidateLayerStack(layer->getLayerStack(), visibleReg);
21840aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
21852047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
2186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
218903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
219003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
219103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
219203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
219303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
219403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
21959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
21969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
21979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getHwcDisplayId() < 0) {
219803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
219903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
22009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
22019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
22029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->updateCursorPosition(displayDevice);
220303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
220403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
22054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
22064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
22074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
22084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
2209598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    if (!mLayersPendingRemoval.isEmpty()) {
22104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
22111f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        for (const auto& l : mLayersPendingRemoval) {
22121f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            recordBufferingStats(l->getName().string(),
22131f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    l->getOccupancyHistory(true));
22141f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            l->onRemoved();
22154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
22164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
22174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
22184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
22194b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
22204b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
22214b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
22224b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
22234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
22241f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mDrawingState.traverseInZOrder([](Layer* layer) {
22251f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->commitChildList();
22261f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    });
22272d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
22282d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
22294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
2230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22322047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
223387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
2234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2235841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
22369e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("computeVisibleRegions");
2237841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
2238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
2240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
2241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
224287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
2243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22442047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
2245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
22461eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
2247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
224801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
22491f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (layer->getLayerStack() != layerStack)
22502047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr            return;
225187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2252ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
2253ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
2254ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
2255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
2256ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2257ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
2258ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
2259ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
2260ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
2261ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
2262ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
2263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
2264ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2265ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
2266ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
2267ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
2268ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
2269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
2270ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2271a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
2272a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
2273a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
2274a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
2275a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
2276a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
2277a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
2278a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
2279a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
2280a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
2281ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2282ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
2283da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
22844125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
22851f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            Rect bounds(layer->computeScreenBounds());
2286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
22871f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            Transform tr = layer->getTransform();
2288ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
2289ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
2290ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
229122f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                    if (tr.preserveRects()) {
229222f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transform the transparent region
229322f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion = tr.transform(s.activeTransparentRegion);
22944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
229522f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transformation too complex, can't do the
229622f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transparent region optimization.
229722f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion.clear();
22984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
2299ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
2300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2301ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
23021f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                const int32_t layerOrientation = tr.getOrientation();
23039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (s.alpha == 1.0f && !translucent &&
2304ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
2305ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
2306ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
2307ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
2308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2311ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
2312ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
2313ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2314ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
2315ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
2316ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
2317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
2318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
2319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
2321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
2322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
2323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
2324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
23254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
2326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
2327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
2328a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
2329ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
2330ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
2331ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
2332ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
2333ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
2334ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
2335ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
2336ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
2337ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
2338ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
2339a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
2340ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
23414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
23424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
2343ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
2344ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
2345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
2347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
234987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
2350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2351ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
2352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
23538b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
2354a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
2355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
2356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
2357a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
2358a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
23592047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
2360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
236187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
2362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
236487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
236587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
236692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
23674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
23684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
23694297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
237092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
237192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
237287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
237387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
23746b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
2375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
23769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("handlePageFlip");
23779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
2378d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    nsecs_t latchTime = systemTime();
237999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
23804fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
23816b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
238251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
238351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
238451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
238551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
238651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
238751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
238851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
238951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
239051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
239151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
23922047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
23936b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
23946b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
23956b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
23962047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr                mLayersWithQueuedFrames.push_back(layer);
2397ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
2398ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
23996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
2400ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
2401ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
24026b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
24032047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
24042047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr
24059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
2406d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
2407ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
24081f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        invalidateLayerStack(layer->getLayerStack(), dirty);
24094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
24104da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
24113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
24126b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
24136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
24146b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
24156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
24169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (frameQueued && mLayersWithQueuedFrames.empty()) {
24176b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
24186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
24196b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
24206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
24219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !mLayersWithQueuedFrames.empty();
2422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2424ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
2425ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
24269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mGeometryInvalid = true;
2427ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
2428ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
242999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2430830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::doDisplayComposition(
2431830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        const sp<const DisplayDevice>& displayDevice,
243287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
2433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24347143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
24357143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
24367143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
24377143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
2438830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    bool isHwcDisplay = displayDevice->getHwcDisplayId() >= 0;
24397143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
24409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("Skipping display composition");
24417143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
24427143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
24437143316af216fa92c31a60d4407b707637382da1Dan Stoza
24449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doDisplayComposition");
24459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
244687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
244787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2448b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
2449830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2451830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    uint32_t flags = displayDevice->getFlags();
24520f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
245329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
245429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
245529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
2456830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard        dirtyRegion.set(displayDevice->swapRegion.bounds());
2457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
24580f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
245929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
2460df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
246195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
24620f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
2463830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->swapRegion.bounds());
2464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
246529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
2466830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            dirtyRegion.set(displayDevice->bounds());
2467830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard            displayDevice->swapRegion = dirtyRegion;
2468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2471830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    if (!doComposeSurfaces(displayDevice, dirtyRegion)) return;
2472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24739c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
2474830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapRegion.orSelf(dirtyRegion);
2475da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
2476da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
2477830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    displayDevice->swapBuffers(getHwComposer());
2478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces(
24819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<const DisplayDevice>& displayDevice, const Region& dirty)
2482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
24839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposeSurfaces");
24849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
24859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
24869f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
24879f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 oldColorMatrix;
24889f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
24899f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
24909f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
24919f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        mat4 colorMatrix = mColorMatrix * mDaltonizer();
24929f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
24939f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
24949f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
24959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool hasClientComposition = mHwc->hasClientComposition(hwcId);
24969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hasClientComposition) {
24979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("hasClientComposition");
2498a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
24995d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter#ifdef USE_HWC2
25005d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        mRenderEngine->setColorMode(displayDevice->getActiveColorMode());
25015d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter        mRenderEngine->setWideColor(displayDevice->getWideColorSupport());
25025d94389241cc651e6bd327ab80eba3ad476f3724Courtney Goeltzenleuchter#endif
25039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
2504c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
25059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                  displayDevice->getDisplayName().string());
25063f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
25078d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk
25088d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            // |mStateLock| not needed as we are on the main thread
25098d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk            if(!getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext)) {
25103f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
25113f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
25123f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
2513c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
2514a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2515a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
25169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
25179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hasDeviceComposition) {
2518b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
2519b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
2520b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
25213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
2522b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
25239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mRenderEngine->clearWithColor(0, 0, 0, 0);
2524b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
2525766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
25269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region bounds(displayDevice->getBounds());
2527766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2528766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
2529766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
2530766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
25319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region letterbox(bounds.subtract(displayDevice->getScissor()));
2532766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2533766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
25349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Region region(displayDevice->undefinedRegion.merge(letterbox));
2535766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2536766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
2537766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
2538766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2539b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
254087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
2541b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
25429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                drawWormhole(displayDevice, region);
2543b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
2544a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
2545f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
25469e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
2547766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
2548f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
2549f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
25509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& bounds(displayDevice->getBounds());
25519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& scissor(displayDevice->getScissor());
2552f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
2553f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
2554f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
2555f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
25563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2557f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
25589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const uint32_t height = displayDevice->getHeight();
25599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
25603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
2561f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
2562f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
256385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
25644b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
256585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
256685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
256785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
25684b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
25699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Rendering client layers");
25709e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& displayTransform = displayDevice->getTransform();
25719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcId >= 0) {
257285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
25739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool firstLayer = true;
25749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
25759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region clip(dirty.intersect(
25769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
25779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("Layer: %s", layer->getName().string());
25789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("  Composition type: %s",
25799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(layer->getCompositionType(hwcId)).c_str());
258085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
25819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                switch (layer->getCompositionType(hwcId)) {
25829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Cursor:
25839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Device:
2584267ab79b22f9d0b995ff787e36aca9c39497c489Gray Huang                    case HWC2::Composition::Sideband:
25859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::SolidColor: {
2586ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
25879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (layer->getClearClientTarget(hwcId) && !firstLayer &&
25889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                layer->isOpaque(state) && (state.alpha == 1.0f)
25899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                && hasClientComposition) {
2590cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
2591cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
25921748719ea1b69cc7ad111d8c6149d692b9f056f8Fabien Sanglard                            layer->clearWithOpenGL(displayDevice);
2593cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
259485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
259585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
25969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Client: {
25979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->draw(displayDevice, clip);
259885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
2599a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
26009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    default:
2601da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
2602cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
26039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
26049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGV("  Skipping for empty clip");
2605a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
26069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            firstLayer = false;
260785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
260885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
260985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
26109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
261185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
26129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
261385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
26149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layer->draw(displayDevice, clip);
261585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
26164b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
26174b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
2618f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
26199f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
26209f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        getRenderEngine().setupColorTransform(oldColorMatrix);
26219f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
26229f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
2623f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
26249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mRenderEngine->disableScissor();
26253f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
2626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2628830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglardvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& displayDevice, const Region& region) const {
2629830b84704b0f33030d0e391a0ea2e7faa5646e2eFabien Sanglard    const int32_t height = displayDevice->getHeight();
26303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
26313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
2632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26347d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
2635ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
26366710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
26371f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        const sp<Layer>& lbc,
26381f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        const sp<Layer>& parent)
26391b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
26407d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    // add this layer to the current state list
26417d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    {
26427d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        Mutex::Autolock _l(mStateLock);
26431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (mNumLayers >= MAX_LAYERS) {
26447d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza            return NO_MEMORY;
26457d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        }
26461f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (parent == nullptr) {
26471f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            mCurrentState.layersSortedByZ.add(lbc);
26481f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        } else {
26491f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            parent->addChild(lbc);
26501f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
26517d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
26521f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mLayersAdded = true;
26531f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mNumLayers++;
26547d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
26557d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
265696f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
2657ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
26584f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
26597d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    return NO_ERROR;
266096f0819f81293076e652792794a961543e6750d7Mathias Agopian}
266196f0819f81293076e652792794a961543e6750d7Mathias Agopian
26629524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carrstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
26637f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr    Mutex::Autolock _l(mStateLock);
26647f9b899c33c5d69597bc676c0bee828819c97a0fRobert Carr
26651f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    const auto& p = layer->getParent();
26661f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
26671f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mCurrentState.layersSortedByZ.remove(layer);
26681f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
2669136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // As a matter of normal operation, the LayerCleaner will produce a second
2670136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // attempt to remove the surface. The Layer will be kept alive in mDrawingState
2671136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // so we will succeed in promoting it, but it's already been removed
2672136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // from mCurrentState. As long as we can find it in mDrawingState we have no problem
2673136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    // otherwise something has gone wrong and we are leaking the layer.
2674136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    if (index < 0 && mDrawingState.layersSortedByZ.indexOf(layer) < 0) {
26751f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        ALOGE("Failed to find layer (%s) in layer parent (%s).",
26761f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                layer->getName().string(),
26771f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                (p != nullptr) ? p->getName().string() : "no-parent");
26781f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        return BAD_VALUE;
2679136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr    } else if (index < 0) {
2680136e2f6570d68e86dca1b2bfa23fc61abcee149eRobert Carr        return NO_ERROR;
2681598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    }
26821f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
26831f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mLayersPendingRemoval.add(layer);
26841f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mLayersRemoved = true;
26851f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    mNumLayers--;
26861f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    setTransactionFlags(eTransactionNeeded);
26871f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    return NO_ERROR;
2688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2690c8251eb7a6ecfdd16b3e4cfbfb442aa4c789c039Fabien Sanglarduint32_t SurfaceFlinger::peekTransactionFlags() {
2691dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
2692dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
2693dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
26943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
270199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
2704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27068b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
27078b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
27088b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
27098b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
27108b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
27117c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2712698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
271328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2714e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
27152d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
27162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
27172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
27182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
27197c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
27202d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
27212d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
27227c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
27237c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
27247c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
27252d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
27262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
27272d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
27282d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
27292d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
27302d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2731e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2732e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2733e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2734e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2735b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2736b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2737e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2738698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2739698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2740d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2741d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2742d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2743d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2744d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2745d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2746d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2747d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2748097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2749d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
27502ae83f4f628d4da96f363d0668380ba1f753b867Fabien Sanglard                if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != NULL) {
2751d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2752d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2753d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2754d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2755d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2756698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2757386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
27582a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // If a synchronous transaction is explicitly requested without any changes,
27592a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // force a transaction anyway. This can be used as a flush mechanism for
27602a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // previous async transactions.
27612a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    if (transactionFlags == 0 && (flags & eSynchronous)) {
27622a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr        transactionFlags = eTransactionNeeded;
27632a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    }
27642a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr
276528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2766ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (mInterceptor.isEnabled()) {
2767ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags);
2768ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
2769468051e20be19130572231266db306396a56402bIrvel
2770386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
277128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2772698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2773386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2774386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2775386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
27762d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
27772d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
27782d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
27792d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2780386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
27812d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2782386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2783386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2784386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2785386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
27862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
27872d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2788386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2789386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2790cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2794e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2795e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
27969a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
27979a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
27989a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
27999a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2800e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
28019a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
28023ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2803e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2804e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2805097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2806e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2807e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2808e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2809e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2810e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2811e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2812e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2813e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2814e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2815e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
281600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2817e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2818e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2819e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2820e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2821e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2822e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2823e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2824e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2825e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2826e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2827e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2828e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2829e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
283047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
283147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
283247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
283347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
283447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
283547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
283647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
283747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
283847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
283947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2840e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2841e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2842e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2843e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2845e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2846e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2847e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2848e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
284913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2850e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2851e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
285299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        bool geometryAppliesWithResize =
285399e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                what & layer_state_t::eGeometryAppliesWithResize;
2854e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
285599e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
2856e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
285782364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            }
2858e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2859e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2860e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
28611f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            const auto& p = layer->getParent();
28621f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (p == nullptr) {
28631f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
28641f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                if (layer->setLayer(s.z) && idx >= 0) {
28651f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    mCurrentState.layersSortedByZ.removeAt(idx);
28661f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    mCurrentState.layersSortedByZ.add(layer);
28671f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    // we need traversal (state changed)
28681f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    // AND transaction (list changed)
28691f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    flags |= eTransactionNeeded|eTraversalNeeded;
28701f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                }
28711f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else {
28721f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                if (p->setChildLayer(layer, s.z)) {
28731f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    flags |= eTransactionNeeded|eTraversalNeeded;
28741f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                }
2875e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2876e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2877e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2878e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2879e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2880e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2881e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2882e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
28839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->setAlpha(s.alpha))
2884e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2885e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2886e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2887e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2888e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2890e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2891e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2892e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2893e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2894231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        if (what & layer_state_t::eFlagsChanged) {
2895e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2896e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2897e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2898e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
289999e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
2900e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2901e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2902acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (what & layer_state_t::eFinalCropChanged) {
29038d5227b8416b099c884429312daf2d60496fa484Robert Carr            if (layer->setFinalCrop(s.finalCrop, !geometryAppliesWithResize))
2904acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                flags |= eTraversalNeeded;
2905acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
2906e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2907e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
29081f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            // We only allow setting layer stacks for top level layers,
29091f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            // everything else inherits layer stack from its parent.
29101f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (layer->hasParent()) {
29111f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid",
29121f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        layer->getName().string());
29131f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else if (idx < 0) {
29141f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                ALOGE("Attempt to set layer stack on layer without parent (%s) that "
29151f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        "that also does not appear in the top level layer list. Something"
29161f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                        " has gone wrong.", layer->getName().string());
29171f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            } else if (layer->setLayerStack(s.layerStack)) {
2918e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2919e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2920e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2921e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2922e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2923e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2924e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
29257dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (what & layer_state_t::eDeferTransaction) {
29260d48072f6047140119ff194c1194ce402fca2c0bRobert Carr            if (s.barrierHandle != nullptr) {
29270d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
29280d48072f6047140119ff194c1194ce402fca2c0bRobert Carr            } else if (s.barrierGbp != nullptr) {
29290d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
29300d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                if (authenticateSurfaceTextureLocked(gbp)) {
29310d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                    const auto& otherLayer =
29320d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                        (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
29330d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                    layer->deferTransactionUntil(otherLayer, s.frameNumber);
29340d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                } else {
29350d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                    ALOGE("Attempt to defer transaction to to an"
29360d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                            " unrecognized GraphicBufferProducer");
29370d48072f6047140119ff194c1194ce402fca2c0bRobert Carr                }
29380d48072f6047140119ff194c1194ce402fca2c0bRobert Carr            }
29397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // We don't trigger a traversal here because if no other state is
29407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // changed, we don't want this to cause any more work
29417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
29421db73f66624e7d151710483dd58e03eed672f064Robert Carr        if (what & layer_state_t::eReparentChildren) {
29431db73f66624e7d151710483dd58e03eed672f064Robert Carr            if (layer->reparentChildren(s.reparentHandle)) {
29441db73f66624e7d151710483dd58e03eed672f064Robert Carr                flags |= eTransactionNeeded|eTraversalNeeded;
29451db73f66624e7d151710483dd58e03eed672f064Robert Carr            }
29461db73f66624e7d151710483dd58e03eed672f064Robert Carr        }
29479524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        if (what & layer_state_t::eDetachChildren) {
29489524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr            layer->detachChildren();
29499524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        }
2950c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        if (what & layer_state_t::eOverrideScalingModeChanged) {
2951c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            layer->setOverrideScalingMode(s.overrideScalingMode);
2952c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // We don't trigger a traversal here because if no other state is
2953c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // changed, we don't want this to cause any more work
2954c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        }
2955e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2956e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2957e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2958e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
29594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
29600ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
29610ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
29624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
2963479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk        uint32_t windowType, uint32_t ownerUid, sp<IBinder>* handle,
2964479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk        sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
2965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
29666e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2967921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
29686e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
29694d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
29706e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
29718b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
29724d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
29734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
29744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
29754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
2976bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    String8 uniqueName = getUniqueLayerName(name);
2977bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
29783165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
29793165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
29804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
2981bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop                    uniqueName, w, h, flags, format,
29824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
29843165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
29854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
2986bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop                    uniqueName, w, h, flags,
29874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
29884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
29894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
29904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29947d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
29957d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
2996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
29977d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
2998479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk    layer->setInfo(windowType, ownerUid);
2999479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk
30001f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    result = addClientLayer(client, *handle, *gbp, layer, *parent);
30017d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
30027d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
30037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
3004ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveSurfaceCreation(layer);
30057d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
30067d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    setTransactionFlags(eTransactionNeeded);
30074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
3008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3010bc7552874052ee33f1b35b4474e20c003d216391Cody NorthropString8 SurfaceFlinger::getUniqueLayerName(const String8& name)
3011bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop{
3012bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    bool matchFound = true;
3013bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    uint32_t dupeCounter = 0;
3014bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
3015bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    // Tack on our counter whether there is a hit or not, so everyone gets a tag
3016bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    String8 uniqueName = name + "#" + String8(std::to_string(dupeCounter).c_str());
3017bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
3018bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    // Loop over layers until we're sure there is no matching name
3019bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    while (matchFound) {
3020bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop        matchFound = false;
3021bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop        mDrawingState.traverseInZOrder([&](Layer* layer) {
3022bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop            if (layer->getName() == uniqueName) {
3023bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop                matchFound = true;
3024bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop                uniqueName = name + "#" + String8(std::to_string(++dupeCounter).c_str());
3025bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop            }
3026bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop        });
3027bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    }
3028bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
3029bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    ALOGD_IF(dupeCounter > 0, "duplicate layer name: changing %s to %s", name.c_str(), uniqueName.c_str());
3030bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
3031bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop    return uniqueName;
3032bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop}
3033bc7552874052ee33f1b35b4474e20c003d216391Cody Northrop
30344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
30354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
30364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
3037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
303992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
3040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
3041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
3042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
3043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
3044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
30458f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
3046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
3047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
30504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
30514d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
30524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
3053b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
3054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
30554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
30564d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
30574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
3058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3059edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
30614d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
30624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
3063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
30644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
30654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
3066b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
30674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
3068118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3069118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3070ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
30719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
30729524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    // called by a client when it wants to remove a Layer
30736710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
30746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
30756710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
3076ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.saveSurfaceDeletion(l);
30776710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
30786710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
30796710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
30809a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
30819a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
30829a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
30839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
308413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
3085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
30866710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
30876710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
30889524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    sp<Layer> l = layer.promote();
30899524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    if (l == nullptr) {
30909524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        // The layer has already been removed, carry on
30919524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        return NO_ERROR;
30929524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    } if (l->getParent() != nullptr) {
30939524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        // If we have a parent, then we can continue to live as long as it does.
30949524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        return NO_ERROR;
30959524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    }
30969524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr    return removeLayer(l);
3097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3099b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
3100b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
310113a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
310201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
310313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
310413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
310513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
310601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
310701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
3108692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
310901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
311013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
31114c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
31124c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
311347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
311447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
311513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
311613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
31172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
31186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
31199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
31209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
31216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
31220a61b0c813f5991bf462e36a2314dda062727a10Brian Anderson
3123d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    // Use phase of 0 since phase is not known.
3124d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    // Use latency of 0, which will snap to the ideal latency.
3125d001058145c2186f454a3fb043388d6d9b84c9d8Brian Anderson    setCompositorTimingSnapped(0, period, 0);
312613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
312713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
312813a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
312913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
313013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
313113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
3132c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
313313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
313413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
313513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
313613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
313713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
313813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
313913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
314013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
314113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
31422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
31432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
31442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
31452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
31462c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
31472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
314813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
31492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
3150c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
3151c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
3152c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
31532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
31542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
31552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
31562c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
31572c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
3158c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
3159ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    if (mInterceptor.isEnabled()) {
3160ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        Mutex::Autolock _l(mStateLock);
3161ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken());
3162ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (idx < 0) {
3163ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            ALOGW("Surface Interceptor SavePowerMode: invalid display token");
3164ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            return;
3165ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
3166ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode);
3167ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    }
3168ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel
31692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
3170f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn on the display
31712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
3172c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
3173c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
3174c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
3175948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
3176c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
3177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
3179b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = true;
31802c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
3181f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
3182f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
3183f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        param.sched_priority = 1;
3184f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
3185f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_FIFO on display on");
3186f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
31872c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
3188f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn off the display
3189f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
3190f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_OTHER, &param) != 0) {
3191f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_OTHER on display off");
3192f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
3193f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
3194c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
3195948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
3196948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
3197cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
3198cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
3199cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
3200c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
32012c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
32022c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
32032c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
32042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
32052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
3206b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
3207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
32102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
3211db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
3212db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
32132c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
3214b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
32152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
32162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
32172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
3218b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
32192c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
3220db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
32212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
32227306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
32239e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
32242c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
32252c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
3226db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
32272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
3228db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
3229b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
3230b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
3231b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
32322c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
3233db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
3234b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
3235b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
3236b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
3237b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
3238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
3239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
324199b49840d309727678b77403d6cc9f920111623fMathias Agopian
3242bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
3243bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
3244bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
3245bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
3246bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
324774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
3248bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
3249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
3250fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
32519795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
32529795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
3253fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
3254fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
32559795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
3256fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
3257fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
3258fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
32599795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
32609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
326182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
326282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
326325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
326425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
326525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
326625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
326725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
326874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
326935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
327025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
327125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
327225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
327325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
327482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
327574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
327635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
327782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
327825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
327925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
328025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
328125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
328274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
328335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
328425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
3285c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
3286c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
3287c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
3288c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
3289c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
3290c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
3291c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
3292b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3293b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            if ((index < numArgs) &&
3294b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                    (args[index] == String16("--static-screen"))) {
3295b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                index++;
3296b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpStaticScreenStats(result);
3297b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpAll = false;
3298b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            }
329940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
330040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            if ((index < numArgs) &&
3301d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                    (args[index] == String16("--frame-events"))) {
330240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                index++;
3303d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson                dumpFrameEventsLocked(result);
330440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                dumpAll = false;
330540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            }
3306f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3307f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter            if ((index < numArgs) && (args[index] == String16("--wide-color"))) {
3308f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter                index++;
3309f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter                dumpWideColorInfo(result);
3310f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter                dumpAll = false;
3311f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter            }
3312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
33131b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
331482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
331574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
331682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
331748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
331882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
331982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
332048b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
332182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
332282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
332382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
332482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
332548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
3326c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
3327c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
332825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
33292047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
333074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
33312047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
333225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
333325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
333482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
333574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
333682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
333782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
333882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
333982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
334082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
334182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
334248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
33439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
33449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
334586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
33464b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
33474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
3348d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
33494b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
33502047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
33514b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
3352d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
33534b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
33542047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        });
335582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
335682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
3357ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
335825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
3359c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
336025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
336125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
336225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
336325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
336425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
336525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
336625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
33672047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
336825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
3369d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
337025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
33712047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
33724b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
3373d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
337425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
337525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
33766547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
33776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
33786547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
33792047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mDrawingState.traverseInZOrder([&](Layer* layer) {
33806547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
33812047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
33826547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
33836547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
33846547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
33856547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
338663a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglardvoid SurfaceFlinger::appendSfConfigString(String8& result) const
33874803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
338863a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append(" [sf");
3389c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard    result.appendFormat(" HAS_CONTEXT_PRIORITY=%d", useContextPriority);
3390c93afd54a05497c4ae42db99ea0310ee69cca492Fabien Sanglard
339163a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    if (isLayerTripleBufferingDisabled())
339263a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard        result.append(" DISABLE_TRIPLE_BUFFERING");
3393c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard
3394c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard    result.appendFormat(" PRESENT_TIME_OFFSET=%" PRId64 , dispSyncPresentTimeOffset);
3395a34ed639c3057b99da0fb703beb12827e30aa508Fabien Sanglard    result.appendFormat(" FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv);
3396c8e387edfcead55b6e6fb1d05db279c264b644faFabien Sanglard    result.appendFormat(" MAX_VIRT_DISPLAY_DIM=%" PRIu64, maxVirtualDisplaySize);
3397cbf153bedf2eafc1443bbc97c4e74f97e7973eddFabien Sanglard    result.appendFormat(" RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework);
33981971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard    result.appendFormat(" NUM_FRAMEBUFFER_SURFACE_BUFFERS=%" PRId64,
33991971b63aa4d82db37794f19e0eb01feb1826e422Fabien Sanglard                        maxFrameBufferAcquiredBuffers);
340063a5fcd2aa55c8eb0ccba621517a4215d8504df6Fabien Sanglard    result.append("]");
34014803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
34024803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
3403b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const
3404b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{
3405b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("Static screen stats:\n");
3406b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
3407b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float bucketTimeSec = mFrameBuckets[b] / 1e9;
3408b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float percent = 100.0f *
3409b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
3410b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
3411b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                b + 1, bucketTimeSec, percent);
3412b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
3413b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
3414b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float percent = 100.0f *
3415b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
3416b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
3417b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            NUM_BUCKETS - 1, bucketTimeSec, percent);
3418b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza}
3419b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3420e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName,
3421e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::vector<OccupancyTracker::Segment>&& history) {
3422e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
3423e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    auto& stats = mBufferingStats[layerName];
3424e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& segment : history) {
3425e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (!segment.usedThirdBuffer) {
3426e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.twoBufferTime += segment.totalTime;
3427e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3428e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (segment.occupancyAverage < 1.0f) {
3429e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.doubleBufferedTime += segment.totalTime;
3430e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        } else if (segment.occupancyAverage < 2.0f) {
3431e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.tripleBufferedTime += segment.totalTime;
3432e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3433e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ++stats.numSegments;
3434e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        stats.totalTime += segment.totalTime;
3435e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3436e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3437e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3438d6927fb1143398370c0885844bfb58923ef740b7Brian Andersonvoid SurfaceFlinger::dumpFrameEventsLocked(String8& result) {
3439d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    result.appendFormat("Layer frame timestamps:\n");
3440d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
3441d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
3442d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    const size_t count = currentLayers.size();
3443d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    for (size_t i=0 ; i<count ; i++) {
3444d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson        currentLayers[i]->dumpFrameEvents(result);
3445d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson    }
3446d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson}
3447d6927fb1143398370c0885844bfb58923ef740b7Brian Anderson
3448e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const {
3449e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("Buffering stats:\n");
3450e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("  [Layer name] <Active time> <Two buffer> "
3451e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            "<Double buffered> <Triple buffered>\n");
3452e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
3453e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    typedef std::tuple<std::string, float, float, float> BufferTuple;
3454e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::map<float, BufferTuple, std::greater<float>> sorted;
3455e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& statsPair : mBufferingStats) {
3456e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const char* name = statsPair.first.c_str();
3457e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferingStats& stats = statsPair.second;
3458e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (stats.numSegments == 0) {
3459e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            continue;
3460e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
3461e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = ns2ms(stats.totalTime) / 1000.0f;
3462e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float twoBufferRatio = static_cast<float>(stats.twoBufferTime) /
3463e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.totalTime;
3464e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float doubleBufferRatio = static_cast<float>(
3465e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.doubleBufferedTime) / stats.totalTime;
3466e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float tripleBufferRatio = static_cast<float>(
3467e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.tripleBufferedTime) / stats.totalTime;
3468e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        sorted.insert({activeTime, {name, twoBufferRatio,
3469e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                doubleBufferRatio, tripleBufferRatio}});
3470e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3471e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& sortedPair : sorted) {
3472e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = sortedPair.first;
3473e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferTuple& values = sortedPair.second;
3474e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        result.appendFormat("  [%s] %.2f %.3f %.3f %.3f\n",
3475e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<0>(values).c_str(), activeTime,
3476e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<1>(values), std::get<2>(values),
3477e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<3>(values));
3478e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3479e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("\n");
3480e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3481e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3482f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchtervoid SurfaceFlinger::dumpWideColorInfo(String8& result) const {
3483f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    result.appendFormat("hasWideColorDisplay: %d\n", hasWideColorDisplay);
3484f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3485f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    // TODO: print out if wide-color mode is active or not
3486f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3487f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    for (size_t d = 0; d < mDisplays.size(); d++) {
3488f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
3489f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        int32_t hwcId = displayDevice->getHwcDisplayId();
3490f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
3491f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter            continue;
3492f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        }
3493f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3494f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        result.appendFormat("Display %d color modes:\n", hwcId);
3495f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(hwcId);
3496f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        for (auto&& mode : modes) {
3497f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter            result.appendFormat("    %s (%d)\n", decodeColorMode(mode).c_str(), mode);
3498f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        }
3499f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
3500f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        android_color_mode_t currentMode = displayDevice->getActiveColorMode();
3501f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter        result.appendFormat("    Current color mode: %s (%d)\n",
3502f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter                            decodeColorMode(currentMode).c_str(), currentMode);
3503f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    }
3504f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    result.append("\n");
3505f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter}
3506f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
350774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
350874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
350982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
35103e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
35113e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
35123e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
35133e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
35143e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
35153e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
35163e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
35173e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
35183e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
351982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
352082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
352182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
352282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
352382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
352482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
3525bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
352682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
35274803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
35284803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
35293e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
35303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
35314803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
35323e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
35334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
35344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
35354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
35364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
35374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
3538f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    result.append("\nWide-Color information:\n");
3539f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter    dumpWideColorInfo(result);
3540f3b2de10caa2a96e65f3e8ebecb2730ff28aeeb1Courtney Goeltzenleuchter
35413e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
3542ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
35433e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
3544ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
3545ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
3546ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
35479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
35489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
354941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
355041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
355141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
355224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
3553c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard            "present offset %" PRId64 " ns (refresh %" PRId64 " ns)",
35549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
3555c45a7d9dfdefa07512c5acc07bcbee5362b34e3dFabien Sanglard        dispSyncPresentTimeOffset, activeConfig->getVsyncPeriod());
355641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
355741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
3558b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    // Dump static screen stats
3559b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3560b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    dumpStaticScreenStats(result);
3561b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3562b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3563e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    dumpBufferingStats(result);
3564e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
35654803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
356682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
356782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
35683e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
35691f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    result.appendFormat("Visible layers (count = %zu)\n", mNumLayers);
35703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
35712047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    mCurrentState.traverseInZOrder([&](Layer* layer) {
35723e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
35732047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    });
3574bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
357582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
35765f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
35775f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
35785f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
35793e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
358086efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
35813e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
35825f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
35835f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
358474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
35855f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
35865f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
35875f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
358882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
358982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
35901b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
35913e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
359274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
35933e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
35941b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
3595888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
35968d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk    sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
3597ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
35983e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
35993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
36003e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
36013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
36023e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
3603ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
3604ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
3605875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
36069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
36074297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
36082c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
36092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
361074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
361182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
361282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
3613c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
361482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
361582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
3616ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
3617ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
3618ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
361982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
362082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
3621c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
36229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            1e9 / activeConfig->getVsyncPeriod(),
36239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiX(),
36249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiY(),
3625ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
362682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
362774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
362882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
362982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
363074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
363182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
363282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
363382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
363482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
363582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
363674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
3637e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("\n");
3638e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3639e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    /*
3640e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     * HWC layer minidump
3641e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     */
3642e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    for (size_t d = 0; d < mDisplays.size(); d++) {
3643e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
3644e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        int32_t hwcId = displayDevice->getHwcDisplayId();
3645e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
3646e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            continue;
3647e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3648e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3649e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.appendFormat("Display %d HWC layers:\n", hwcId);
3650e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        Layer::miniDumpHeader(result);
36511f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        mCurrentState.traverseInZOrder([&](Layer* layer) {
3652e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            layer->miniDump(result, hwcId);
36531f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
3654e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.append("\n");
3655e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
365682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
365782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
365882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
365982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
36603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
366174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
36623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
36639f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool hwcDisabled = mDebugDisableHWC || mDebugRegion;
36649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.appendFormat("  h/w composer %s\n",
36659e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            hwcDisabled ? "disabled" : "enabled");
366674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
366782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
366882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
366982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
367082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
367182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
367282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
3673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
367513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
367648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
3677db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
367848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
367948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
368048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
368148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
368248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
368348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
368448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
368548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
368648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
368748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
368848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
368948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
369048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
3691cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
3692cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
369363f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
369463f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
369563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
369663f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
369763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
369863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
369963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
370063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
370163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
370224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
370363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
370463f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
370563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
370663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
370763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
370863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
370963f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
371063f165fd6b86d04be94d4023e845e98560504a96Keun young Park
37116e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
3712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
3713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
3714041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
3715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
3716d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
3717d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
37182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
3719c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        case GET_HDR_CAPABILITIES:
3720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
3721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
3722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
3723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
3724a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
37253bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
372699b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
37276e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3728375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
3729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
37301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
37311b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
37321db73f66624e7d151710483dd58e03eed672f064Robert Carr        /*
37331db73f66624e7d151710483dd58e03eed672f064Robert Carr         * Calling setTransactionState is safe, because you need to have been
37341db73f66624e7d151710483dd58e03eed672f064Robert Carr         * granted a reference to Client* and Handle* to do anything with it.
37351db73f66624e7d151710483dd58e03eed672f064Robert Carr         *
37361db73f66624e7d151710483dd58e03eed672f064Robert Carr         * Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h
37371db73f66624e7d151710483dd58e03eed672f064Robert Carr         */
37381db73f66624e7d151710483dd58e03eed672f064Robert Carr        case SET_TRANSACTION_STATE:
37391db73f66624e7d151710483dd58e03eed672f064Robert Carr        case CREATE_SCOPED_CONNECTION:
37401db73f66624e7d151710483dd58e03eed672f064Robert Carr        {
37411db73f66624e7d151710483dd58e03eed672f064Robert Carr            return OK;
37421db73f66624e7d151710483dd58e03eed672f064Robert Carr        }
37431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
37441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
37451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
37461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
37471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
37481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
374999b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
375099b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
37516e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid);
37521b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
37531b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
37541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
3755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
37576e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    return OK;
37586e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard}
37596e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard
37606e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact(
37616e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
37626e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{
37636e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    status_t credentialCheck = CheckTransactCodeCredentials(code);
37646e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    if (credentialCheck != OK) {
37656e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard        return credentialCheck;
37666e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    }
37671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
3769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
3770b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
377199ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
3772375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
3773375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
3774375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
3775e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
3776375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
3778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
3780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
378101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
378235b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
3783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
3785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
3786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
378753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
378853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
379153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3792cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3793cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
3794cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
3795e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
3796e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
3797e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
3798e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
3799cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
38014d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
38024d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
38034d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
38044d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
380553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
380653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
380753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
380853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
380953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
381053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
3811a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
3812a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
3813a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
3814a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
3815a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
3816a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
3817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
381801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
3819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
3820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
3821b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
382212839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
3823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
3825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
38268d6c16dc3dc8b88a0046f53668a4e3be074507ffStephen Kiazyk                sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
38274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
3828ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
3829ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
3830ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
3831ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
3832ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
3833ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
38349f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 1:
38359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Protanomaly);
38369f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
38379f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 2:
38389f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
38399f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
38409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 3:
38419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
38429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
38439f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    default:
38449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::None);
38459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
3846ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3847ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
38489f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Correction);
3849ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
38509f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Simulation);
3851ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3852ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
3853ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
38549c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
38559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
38569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
38579c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
38589c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
38599c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
38609c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
38619c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
38629c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
3863794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
38649f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        for (size_t j = 0; j < 4; j++) {
38659f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                            mColorMatrix[i][j] = data.readFloat();
38669f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        }
38679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
38689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
38699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
38709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
38719c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
38729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
38739c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
3874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
3875f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
3876f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
3877f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
3878645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
3879645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
3880f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
3881f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
3882ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
3883ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
3884ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
3885ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
3886ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
3887db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1018: { // Modify Choreographer's phase offset
3888db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3889db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3890db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3891db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3892db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1019: { // Modify SurfaceFlinger's phase offset
3893db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3894db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3895db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3896db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3897468051e20be19130572231266db306396a56402bIrvel            case 1020: { // Layer updates interceptor
3898468051e20be19130572231266db306396a56402bIrvel                n = data.readInt32();
3899468051e20be19130572231266db306396a56402bIrvel                if (n) {
3900468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor enabled");
3901ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel                    mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays);
3902468051e20be19130572231266db306396a56402bIrvel                }
3903468051e20be19130572231266db306396a56402bIrvel                else{
3904468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor disabled");
3905468051e20be19130572231266db306396a56402bIrvel                    mInterceptor.disable();
3906468051e20be19130572231266db306396a56402bIrvel                }
3907468051e20be19130572231266db306396a56402bIrvel                return NO_ERROR;
3908468051e20be19130572231266db306396a56402bIrvel            }
39098cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            case 1021: { // Disable HWC virtual displays
39108cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                n = data.readInt32();
39118cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                mUseHwcVirtualDisplays = !n;
39128cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                return NO_ERROR;
39138cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            }
3914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
3917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
391953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
392087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
392199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
392253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
392353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
392459119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
39252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
39262a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
392759119e658a12279e8fff508f8773843de2d90917Mathias Agopian
39282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
39292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
39302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
3931b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
3932b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
3933b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
3934b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
39352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
39362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
3937b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
3938b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
3939b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
3940b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3941b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
3942b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
3943b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
3944b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
3945b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3946b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
3947b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
3948b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
3949b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
3950b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
39512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
39522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
39532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
39542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
39552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
3956b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
39572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
39582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
39592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
39602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
39612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
39622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
39632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
39642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
39652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
39662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3967b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
3968b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
3969b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
39702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
39712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
3972c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
39732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
39742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
39752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
39762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
3977b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
3978b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
3979b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
3980b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
39812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
39822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
39832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
3984b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
3985b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
3986b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
39872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
39882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
39892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
3990c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
39912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
39922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
39932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3994b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
39952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
39962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
39972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
3998b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
3999b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
4000b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
4001b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
4002097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
40032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
4004b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
40052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
40062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
40072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
40082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
40092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
4010c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh    explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
4011b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
4012b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
401353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        result(NO_ERROR),
4014b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
401553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        exitRequested(false),
401653390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        code(0),
401753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        data(NULL),
401853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        reply(NULL)
4019b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
4020b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
4021b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
40222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
40232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
40242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
40252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
40262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
40272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
40282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
4029b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
40302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
4031aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
40322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
4033b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
4034b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
4035b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
40362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
40372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
40382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
40392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
40402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
40412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
40422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
4043c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
4044ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
4045c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
40462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
40472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
40482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
40492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
40502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
40512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
40522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
40535ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
40545ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
40555ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
4056b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
40575ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
4058c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
4059c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
4060c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
4061c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
4062c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
4063c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4064c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
4065c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
4066c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4067c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
4068c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
4069c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4070c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
4071c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
4072c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4073c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
4074c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
4075c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
4076c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
4077c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
4078c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
40792a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
40802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
40812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
40822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
4083c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
40842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
40852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
4086c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
4087c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
40882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
4089b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot;
40902a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
40912a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
40922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
40932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
4094c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
4095ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                int32_t minLayerZ, int32_t maxLayerZ,
4096b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool useIdentityTransform,
4097b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                Transform::orientation_flags rotation,
4098b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool isLocalScreenshot)
40992a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
4100c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
41012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
4102c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
4103b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              rotation(rotation), result(PERMISSION_DENIED),
4104b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              isLocalScreenshot(isLocalScreenshot)
41052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
41062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
41072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
41082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
41092a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
41102a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
41112a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
41122a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
4113c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
4114c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
4115b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                    useIdentityTransform, rotation, isLocalScreenshot);
4116097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
41172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
41182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
41192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
41202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
41212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
41222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
41232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
41242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
41252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
41262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
41272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
41282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
41292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
4130c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
4131b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            useIdentityTransform, rotationFlags, isLocalScreenshot);
41322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
41332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
41342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
41352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
41362a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
41372a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
4138118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
4139118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
4140180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4141180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
4142180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
4143c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
4144ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
4145c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
4146180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
4147180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
41483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
4149180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4150180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
415189fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
415289fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
415389fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
41540e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
4155180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4156c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
4157c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
4158c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
4159c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
4160c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
4161c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4162c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
4163c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
4164c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
4165c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
4166c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4167be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
4168be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
4169c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4170c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
4171c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
4172c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4173be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
4174be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
4175c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
4176c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
4177180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
41783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
4179180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4180180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
4181c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
4182c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
41833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
4184180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4185180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
41863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
4187180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
41881f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    // We loop through the first level of layers without traversing,
41891f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    // as we need to interpret min/max layer Z in the top level Z space.
41901f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    for (const auto& layer : mDrawingState.layersSortedByZ) {
41911f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (layer->getLayerStack() != hw->getLayerStack()) {
41921f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
41931f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
41941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
41951f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (state.z < minLayerZ || state.z > maxLayerZ) {
41961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
4197180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
41981f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->traverseInZOrder([&](Layer* layer) {
41991f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (!layer->isVisible()) {
42001f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                return;
42011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            }
42021f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (filtering) layer->setFiltering(true);
42031f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            layer->draw(hw, useIdentityTransform);
42041f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (filtering) layer->setFiltering(false);
42051f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
42061f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    }
4207180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4208931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
4209180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
4210180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4211180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
42122a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
42132a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
42142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
4215c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
4216ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        int32_t minLayerZ, int32_t maxLayerZ,
4217b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool useIdentityTransform, Transform::orientation_flags rotation,
4218b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot)
421974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
4220fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
4221fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
4222180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
42233502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_w = hw->getWidth();
42243502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_h = hw->getHeight();
42253502416204d9dbd905012ee586d8bd145323809fDan Stoza
42263502416204d9dbd905012ee586d8bd145323809fDan Stoza    if (rotation & Transform::ROT_90) {
42273502416204d9dbd905012ee586d8bd145323809fDan Stoza        std::swap(hw_w, hw_h);
42283502416204d9dbd905012ee586d8bd145323809fDan Stoza    }
4229180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4230180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
4231180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
4232180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
4233180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
4234180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
4235180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4236180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
4237180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
4238180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
4239b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool secureLayerIsVisible = false;
42401f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    for (const auto& layer : mDrawingState.layersSortedByZ) {
4241b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const Layer::State& state(layer->getDrawingState());
42421f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if ((layer->getLayerStack() != hw->getLayerStack()) ||
42431f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                (state.z < minLayerZ || state.z > maxLayerZ)) {
42441f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            continue;
4245b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        }
42461f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        layer->traverseInZOrder([&](Layer *layer) {
42471f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() &&
42481f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    layer->isSecure());
42491f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        });
42501f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    }
4251b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
4252b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    if (!isLocalScreenshot && secureLayerIsVisible) {
4253b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        ALOGW("FB is protected: PERMISSION_DENIED");
4254b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        return PERMISSION_DENIED;
4255b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
4256b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
42570aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
42580aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
425983cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
4260605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
4261605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Put the screenshot Surface into async mode so that
4262605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Layer::headFenceHasSignaled will always return true and we'll latch the
4263605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // first buffer regardless of whether or not its acquire fence has
4264605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // signaled. This is needed to avoid a race condition in the rotation
4265605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // animation. See b/30209608
4266605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    sur->setAsyncMode(true);
4267605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
42680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
426974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
42705a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
42715a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    if (result == NO_ERROR) {
42723ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
42733ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
42742a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
42750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
42760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
42774ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
42780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
42790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
42802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
42810aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
42820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
42830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
42840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
42850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
42860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
42870aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
4288866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
42890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
42900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
42910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
42920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
42930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
42943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
42953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
42963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
42973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
42980aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
42990aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
43000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
43010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
4302c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
4303c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
4304c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
4305d555684cb36dfb959694db76962e570184f98838Mathias Agopian
4306866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
4307866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
4308866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
4309866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
4310866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
4311866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
43129707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
43139707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
4314866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
4315866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
4316866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
43172d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
4318866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
4319866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
4320866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
4321866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
4322866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
4323866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
43242d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
4325866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
4326866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
4327866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
4328866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
4329866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
4330866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
4331866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
4332866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
4333866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
4334866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
4335866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
4336866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
4337866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
4338866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
43392d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
4340866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
43412d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
43422d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
4343d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
4344d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
4345d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
4346d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
4347d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
4348d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
4349d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
4350d555684cb36dfb959694db76962e570184f98838Mathias Agopian
43510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
43520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
43530aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
4354f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        window->cancelBuffer(window, buffer, syncFd);
4355f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        buffer = NULL;
43560aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
43570aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
43580aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
43590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
43600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
436174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
4362f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                if (buffer) {
4363f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    // queueBuffer takes ownership of syncFd
4364f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    result = window->queueBuffer(window, buffer, syncFd);
4365f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                }
436674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
43670aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
43680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
436974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
43700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
437174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
437274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
437374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
437474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
437574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
4376d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
4377ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr        const sp<const DisplayDevice>& hw, int32_t minLayerZ, int32_t maxLayerZ) {
4378fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
4379d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
4380d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
4381d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
4382fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
4383fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
4384fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
4385fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
4386fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
4387fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
43881f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
43892047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr        size_t i = 0;
43901f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        for (const auto& layer : mDrawingState.layersSortedByZ) {
4391fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
43921f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            if (layer->getLayerStack() == hw->getLayerStack() && state.z >= minLayerZ &&
43931f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    state.z <= maxLayerZ) {
43941f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                layer->traverseInZOrder([&](Layer* layer) {
43951f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
43961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                            layer->isVisible() ? '+' : '-',
43971f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                            i, layer->getName().string(), layer->getLayerStack(), state.z,
4398fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
43991f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                    i++;
44001f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                });
44011f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            }
44021f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
4403fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
4404ce796e78a57018f186b062199c75d94545318acaPablo Ceballos}
4405ce796e78a57018f186b062199c75d94545318acaPablo Ceballos
44061b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
44071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
44082047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInZOrder(const std::function<void(Layer*)>& consume) const {
44092047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    layersSortedByZ.traverseInZOrder(consume);
4410921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
4411921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
44122047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carrvoid SurfaceFlinger::State::traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const {
44132047fae0cfed99c425dc7333f31d309e5b8ee1baRobert Carr    layersSortedByZ.traverseInReverseZOrder(consume);
4414921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
4415921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
4416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
44173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
44183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
44193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
44203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
44213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
44223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
44233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
44243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
44253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
4426