SurfaceFlinger.cpp revision 6e8e98a23592c2522396b673145814a4bbee69db
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/log.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
34c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
35c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3799b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
387303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
39c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
4067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h>
41c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
42921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
451a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
46e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
47392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h>
48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
49921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
50921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
52d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
53cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
570a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato#include <utils/Timers.h>
581c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
61ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
653e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
670f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
68faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
69d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
70d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
75a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
76a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
79ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
80ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
81875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
82ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
83875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
89fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
90fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
91fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
92ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
93ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
9422819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov// Workaround for b/30067360: /proc/self/environ inaccessible in SurfaceFlinger
9522819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov// => ASan fails to read ASAN_OPTIONS => alloc-dealloc-mismatch bug is not
9622819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov// suppressed and prevents the device from booting.
9722819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#ifndef __has_feature
9822819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#define __has_feature(x) 0
9922819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#endif
10022819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#if __has_feature(address_sanitizer)
10122819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov__attribute__((visibility("default")))
10222819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanovextern "C" const char* __asan_default_options() {
10322819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov  return "alloc_dealloc_mismatch=0";
10422819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov}
10522819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov#endif
10622819276b147e34a80e8ca696be5b3fda68764b9Evgenii Stepanov
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event
110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer.  The software vsync
111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each
112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame.
113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application
115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window
116faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed.  This value may be either positive (after the HW vsync)
117faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync).  Setting it to 0 will result in a
118faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger
119faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync.  Setting it to a positive number will
120faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being:
121faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
122faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
123faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
124faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications
125faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time.  When this happens
126faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations
127faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup.  Therefore, this latency should be tuned somewhat
128faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made).
129faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
130faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1310a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs.
1320a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
1330a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13699b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
13799b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
13899b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
13999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
14099b49840d309727678b77403d6cc9f920111623fMathias Agopian
14199b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
14299b49840d309727678b77403d6cc9f920111623fMathias Agopian
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1444f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1462d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1472d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
148076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
14952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
150875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mRenderEngine(NULL),
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
1529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mBuiltinDisplays(),
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
1549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid(false),
1554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1578afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
15873d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
159a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1609795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1619795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1629795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1639795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
164ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
165ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        mForceFullDamage(false),
166468051e20be19130572231266db306396a56402bIrvel        mInterceptor(),
1674a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        mPrimaryDispSync("PrimaryDispSync"),
168faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
169948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
170b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasColorMatrix(false),
171b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff(false),
172b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mFrameBuckets(),
173b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime(0),
174b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mLastSwapTime(0)
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
176a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1808afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
181b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
18250210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
183b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1868afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1878afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1888afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1898afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
19063f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
19163f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
19263f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
19363f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1948afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
195c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
196c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
197c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza
198c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    property_get("debug.sf.disable_backpressure", value, "0");
199c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    mPropagateBackpressure = !atoi(value);
200c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza    ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
2018cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
2028cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza    property_get("debug.sf.disable_hwc_vds", value, "0");
2038cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza    mUseHwcVirtualDisplays = !atoi(value);
2048cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza    ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
20899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
20999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
21099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
21199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
214a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
215a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
216a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
219c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
22099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
22199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
22299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
22313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
22413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
22599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
22699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
227a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
22899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
22999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2307e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
23296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
23396f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
23496f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
23596f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
23696f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
241dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
242dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
246e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
247e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
249e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
250e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
251e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
252e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
253c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit DisplayToken(const sp<SurfaceFlinger>& flinger)
254e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
255e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
256e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
257e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
258e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
259e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
260e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
26153390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
2628dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
263e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
264ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
265e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
266e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
267e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2686c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2696c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2706c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2716c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2726c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2736c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2746c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2756c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2766c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2776c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2786c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2796c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2806c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2816c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
282ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayDeletion(info.displayId);
2836c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2846c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2856c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2866c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
287692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
2889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("createBuiltinDisplayLocked(%d)", type);
289692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
290692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
291692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
292692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
29353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos    DisplayDeviceState info(type, true);
294692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
295ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveDisplayCreation(info);
296692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
297692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
298e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2999e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
300e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
301e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
302e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
303692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
304e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
305e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
3069a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
3079a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
3089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
3099a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
3109a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
316a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
3173330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
3181f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3191f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
3201f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
3211f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
3221f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
323921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
3241f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
3251f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3261f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
327a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
328a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
329a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
3300a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato
3310a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
3320a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
3330a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
337921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
340921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
343921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
344921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
346921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
347921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
348921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
350921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
351921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3545167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3554a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        const char* name) :
3564a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mName(name),
3570a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3580a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3594a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
3604a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            mVsyncEventLabel(String8::format("VSYNC-%s", name)),
361db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mDispSync(dispSync),
362db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallbackMutex(),
363db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallback(),
364db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mVsyncMutex(),
365db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mPhaseOffset(phaseOffset),
366db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mEnabled(false) {}
367faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
371db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3734a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
377faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
378faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3795167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
380faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
381faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3875167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
388faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mEnabled = enable;
390faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
391faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
392faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mCallbackMutex);
394faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
395faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
396faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    virtual void setPhaseOffset(nsecs_t phaseOffset) {
398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Normalize phaseOffset to [0, period)
401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        auto period = mDispSync->getPeriod();
402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        phaseOffset %= period;
403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (phaseOffset < 0) {
404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // If we're here, then phaseOffset is in (-period, 0). After this
405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // operation, it will be in (0, period)
406db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            phaseOffset += period;
407db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
408db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mPhaseOffset = phaseOffset;
409db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // If we're not enabled, we don't need to mess with the listeners
411db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (!mEnabled) {
412db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            return;
413db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
414db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
415db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Remove the listener with the old offset
416db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        status_t err = mDispSync->removeEventListener(
417db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
418db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
419db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error unregistering vsync callback: %s (%d)",
420db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
421db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
422db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
423db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Add a listener with the new offset
4244a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray        err = mDispSync->addEventListener(mName, mPhaseOffset,
425db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
426db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
427db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error registering vsync callback: %s (%d)",
428db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
429db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
430db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    }
431db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
432faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
433faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
434faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
435faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
436db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            Mutex::Autolock lock(mCallbackMutex);
437faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
438a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4390a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
4400a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
4415167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
4420a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
443faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
444faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
445faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
446faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
447faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
448faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
449faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4504a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    const char* const mName;
4514a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
453faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4540a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
4555167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
4565167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
4570a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
458faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
459db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
460db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mCallbackMutex; // Protects the following
461faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
462db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
463db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mVsyncMutex; // Protects the following
464db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    nsecs_t mPhaseOffset;
465db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    bool mEnabled;
466faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
467faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
468c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuclass InjectVSyncSource : public VSyncSource {
469c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjupublic:
470c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    InjectVSyncSource() {}
471c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
472c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual ~InjectVSyncSource() {}
473c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
474c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
475c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
476c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback = callback;
477c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
478c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
479c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void onInjectSyncEvent(nsecs_t when) {
480c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        std::lock_guard<std::mutex> lock(mCallbackMutex);
481c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mCallback->onVSyncEvent(when);
482c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
483c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
484c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setVSyncEnabled(bool) {}
485c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    virtual void setPhaseOffset(nsecs_t) {}
486c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
487c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjuprivate:
488c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    std::mutex mCallbackMutex; // Protects the following
489c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    sp<VSyncSource::Callback> mCallback;
490c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju};
491c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
492faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
493a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
495a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    { // Autolock scope
4979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock _l(mStateLock);
4989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
4999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // initialize EGL for the default display
5009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
5019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        eglInitialize(mEGLDisplay, NULL, NULL);
502692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
5039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // start the EventThread
5049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
5059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                vsyncPhaseOffsetNs, true, "app");
506ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mEventThread = new EventThread(vsyncSrc, *this, false);
5079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
5089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                sfVsyncPhaseOffsetNs, true, "sf");
509ab04685578b254c2eaf43bf5da85e5e922787825Irvel        mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
5109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mEventQueue.setEventThread(mSFEventThread);
511a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
512acff43dca6a3c8a29f449706967d4de21c373d26Tim Murray        // set SFEventThread to SCHED_FIFO to minimize jitter
51341a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        struct sched_param param = {0};
51435520634e298f53bd8433825640d6999760f25b3Tim Murray        param.sched_priority = 2;
51541a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
51641a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray            ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
51741a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray        }
51841a3853cea0cffede422fc2692b9c8e1674fc5ebTim Murray
5199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // Get a RenderEngine for the given display / config (can't fail)
5209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mRenderEngine = RenderEngine::create(mEGLDisplay,
5219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                HAL_PIXEL_FORMAT_RGBA_8888);
5229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
523f9481058101c4e2b38c74048feac383664691d03Saurabh Shah
5249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Drop the state lock while we initialize the hardware composer. We drop
5259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // the lock because on creation, it will call back into SurfaceFlinger to
5269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // initialize the primary display.
5279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc = new HWComposer(this);
5289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
529b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
5309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    Mutex::Autolock _l(mStateLock);
531875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
532875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
533875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
534a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
535da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
536da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
537da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
5389e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // make the GLContext current so that we can create textures when creating
5399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Layers (which may happens before we render something)
540a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
541a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
542d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
543d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
544d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
54592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
54692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
5478630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
54813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
54913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
55013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
5514e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza    mRenderEngine->primeCache();
5524e63777f75e9756c74352e62e79dfa8a994de2b3Dan Stoza
553a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
554a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Done initializing");
5573ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
5583ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
559a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
560a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
561a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
562a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
563a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
564a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
565875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
566875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
567a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
568a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
569875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
570875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
571a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
572a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
574d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
575582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
5762adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
577134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
578097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
5796710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
580134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
581134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
5837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
58423e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa    if ((configs == NULL) || (display.get() == NULL)) {
5857f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
5867f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
5877f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5887aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
5897aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
5907aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
591692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
5929e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
593692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
5941604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
5951604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
5961604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5971604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
5981604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5991604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
6001604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
601c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
6028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
6048b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
6058b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
6068b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
6078b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
6088b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
6098b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
6108b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
6118b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
6128b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
6138b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
6148b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
6158b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
6168b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
6178b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
6188b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
6191604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
6207f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
6217f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
6237f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
6247f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float xdpi = hwConfig->getDpiX();
6269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        float ydpi = hwConfig->getDpiY();
6277f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6287f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
6297f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
6307f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
6317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
6327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
6337f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
6347f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
6357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
6367f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6377f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
6387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
6397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
6407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
6417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
6437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
6457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
6467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
6477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
6487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
6497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
6507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
6517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
6521604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.w = hwConfig->getWidth();
6559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.h = hwConfig->getHeight();
6567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
6577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
6589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.fps = 1e9 / hwConfig->getVsyncPeriod();
65991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
6609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
66191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
66291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
66391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
66491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
66591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
66691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
66791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
66891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
66991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
67091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
67191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
67291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
6739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        info.presentationDeadline = hwConfig->getVsyncPeriod() -
6749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
6757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6767f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
6777f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
6787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
67928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        configs->push_back(info);
6808b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6818b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6827f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
6837f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
684dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
68589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
68667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
68767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
68867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
68967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
69067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
69167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
69267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
69367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
69467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
69567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
69667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
69767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
6986c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
69924a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    sp<DisplayDevice> device(getDisplayDevice(display));
70024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
70124a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
70224a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
70324a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
7047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
705dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
7066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
7076c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
7086c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
7096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
7106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
7116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
7136c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
7146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
7156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
7166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
7186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
7196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
7206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
7216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
7236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
7246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
7256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
7276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
7286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
7296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
7306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
7316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
7326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
7336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
7346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
7356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
7367306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
7377306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
738784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
7399ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
7407306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
74128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
7427306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
7436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
7446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
7456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
7467306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
7476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
7486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
7496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
7506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
7516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
7526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
7536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
7546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
7556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
7566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
7576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
758888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
759c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
76028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
76128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        Vector<android_color_mode_t>* outColorModes) {
76228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if ((outColorModes == nullptr) || (display.get() == nullptr)) {
76328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return BAD_VALUE;
76428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
76528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
76628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (!display.get()) {
76728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return NAME_NOT_FOUND;
76828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
76928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
77028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = NAME_NOT_FOUND;
77128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
77228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        if (display == mBuiltinDisplays[i]) {
77328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            type = i;
77428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            break;
77528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
77628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
77728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
77828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type < 0) {
77928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return type;
78028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
78128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
78228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
78328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    outColorModes->clear();
78428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
78528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
78628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
78728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
78828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
78928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightandroid_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
79028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<DisplayDevice> device(getDisplayDevice(display));
79128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (device != nullptr) {
79228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return device->getActiveColorMode();
79328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
79428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return static_cast<android_color_mode_t>(BAD_VALUE);
79528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
79628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
79728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightvoid SurfaceFlinger::setActiveColorModeInternal(const sp<DisplayDevice>& hw,
79828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mode) {
79928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    ALOGD("Set active color mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
80028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright          this);
80128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    int32_t type = hw->getDisplayType();
80228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t currentMode = hw->getActiveColorMode();
80328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
80428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (mode == currentMode) {
80528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGD("Screen type=%d is already in color mode=%d", hw->getDisplayType(), mode);
80628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
80728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
80828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
80928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
81028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        ALOGW("Trying to set config for virtual display");
81128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        return;
81228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    }
81328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
81428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    hw->setActiveColorMode(mode);
81528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    getHwComposer().setActiveColorMode(type, mode);
81628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
81728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
81828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright
81928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatus_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
82028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t colorMode) {
82128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    class MessageSetActiveColorMode: public MessageBase {
82228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        SurfaceFlinger& mFlinger;
82328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        sp<IBinder> mDisplay;
82428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t mMode;
82528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    public:
82628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        MessageSetActiveColorMode(SurfaceFlinger& flinger, const sp<IBinder>& disp,
82728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                               android_color_mode_t mode) :
82828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
82928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        virtual bool handler() {
83028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            Vector<android_color_mode_t> modes;
83128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            mFlinger.getDisplayColorModes(mDisplay, &modes);
83228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            bool exists = std::find(std::begin(modes), std::end(modes), mMode) != std::end(modes);
83328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (mMode < 0 || !exists) {
83428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set invalid active color mode = %d for display %p", mMode,
83528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mDisplay.get());
83628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                return true;
83728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
83828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
83928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            if (hw == nullptr) {
84028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGE("Attempt to set active color mode = %d for null display %p",
84128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode, mDisplay.get());
84228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
84328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                ALOGW("Attempt to set active color mode= %d for virtual display",
84428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                        mMode);
84528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            } else {
84628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                mFlinger.setActiveColorModeInternal(hw, mMode);
84728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            }
84828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return true;
84928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        }
85028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    };
85128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    sp<MessageBase> msg = new MessageSetActiveColorMode(*this, display, colorMode);
85228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    postMessageSync(msg);
85328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return NO_ERROR;
85428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright}
855c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
856d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
857d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
858d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
859d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
860d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
861d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
862d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
863d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
864d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
865d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
866d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
867d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
868c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stozastatus_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& display,
869c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        HdrCapabilities* outCapabilities) const {
870c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    Mutex::Autolock _l(mStateLock);
871c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
872c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    sp<const DisplayDevice> displayDevice(getDisplayDevice(display));
873c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (displayDevice == nullptr) {
874c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get());
875c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
876c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
877c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
878c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    std::unique_ptr<HdrCapabilities> capabilities =
879c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza            mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
880c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    if (capabilities) {
881c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        std::swap(*outCapabilities, *capabilities);
882c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    } else {
883c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        return BAD_VALUE;
884c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    }
885c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
886c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza    return NO_ERROR;
887c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza}
888c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza
889c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::enableVSyncInjections(bool enable) {
890c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable == mInjectVSyncs) {
891c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return NO_ERROR;
892c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
893c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
894c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (enable) {
895c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
896c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections enabled");
897c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        if (mVSyncInjector.get() == nullptr) {
898c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju            mVSyncInjector = new InjectVSyncSource();
899ab04685578b254c2eaf43bf5da85e5e922787825Irvel            mInjectorEventThread = new EventThread(mVSyncInjector, *this, false);
900c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        }
901c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mInjectorEventThread);
902c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    } else {
903c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mInjectVSyncs = enable;
904c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("VSync Injections disabled");
905c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mEventQueue.setEventThread(mSFEventThread);
906c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector.clear();
907c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
908c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
909c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
910c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
911c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanjustatus_t SurfaceFlinger::injectVSync(nsecs_t when) {
912c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (!mInjectVSyncs) {
913c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGE("VSync Injections not enabled");
914c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        return BAD_VALUE;
915c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
916c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) {
917c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        ALOGV("Injecting VSync inside SurfaceFlinger");
918c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju        mVSyncInjector->onInjectSyncEvent(when);
919c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    }
920c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju    return NO_ERROR;
921c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju}
922c1ba5c4649554e744844b07cfe402b42fbe12ff3Sahil Dhanju
923d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
924d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
925d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
9268aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
927bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
928bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
929edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
93099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
93199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
93299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
93399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
93499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
93599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
93699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
93799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
93899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
93999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
94099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
94199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
94299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
94399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
94499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
94599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
94699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
94799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
948c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
94999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
95099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
95199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
95299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
953c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
95499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
95599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
95699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
95799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
95899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
95999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9614f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
9624f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
9634f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
9644f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
96599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
967faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
968faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
969948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
970faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
971d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
972d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
973faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
97443601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
975faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
976faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
977948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
978faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
979faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
980948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
981948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
982948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
9830a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // Hardware vsync is not currently available, so abort the resync
9840a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        // attempt for now
985948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
986948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
987948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
9889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
9899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
990faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
991faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
992faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
993faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
994faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
995faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
996d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
997d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
998faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
999faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1000faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1001faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1002948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
1003faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
1004faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
1005d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
1006d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
1007faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
1008faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
1009faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1010948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
1011948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
1012948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
1013faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
1014faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
10154a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murrayvoid SurfaceFlinger::resyncWithRateLimit() {
10164a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
10174a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    if (systemTime() - mLastSwapTime > kIgnoreDelay) {
10180a3c4d6f8c95a89875455e989278a440822968d7Dan Stoza        resyncToHardwareVsync(false);
10194a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    }
10204a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray}
10214a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
10229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) {
1023d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
1024faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1025d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
1026d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
1027d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
1028d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
1029faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1030148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
1031d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
1032d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
1033d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
1034d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
1035d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
1036d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
1037148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
1038148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
10399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
10409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
10419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (disp == DisplayDevice::DISPLAY_PRIMARY) {
10429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        Mutex::Autolock lock(mStateLock);
10439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10449e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        // All non-virtual displays are currently considered secure.
10459e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool isSecure = true;
10469e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
10479e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        int32_t type = DisplayDevice::DISPLAY_PRIMARY;
10489e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
10499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        wp<IBinder> token = mBuiltinDisplays[type];
10509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferProducer> producer;
10529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<IGraphicBufferConsumer> consumer;
10539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        BufferQueue::createBufferQueue(&producer, &consumer,
10549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                new GraphicBufferAlloc());
10559e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
10569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc,
10579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, consumer);
10589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        sp<DisplayDevice> hw = new DisplayDevice(this,
10599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs,
10609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                producer, mRenderEngine->getEGLConfig());
10619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mDisplays.add(token, hw);
10629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    } else {
10639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto type = DisplayDevice::DISPLAY_EXTERNAL;
10649e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
1065692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
10669e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            createBuiltinDisplayLocked(type);
10679e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
1068692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
1069692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
10709e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
10719e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
10729e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
10739e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
10743ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
10758630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10768630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozavoid SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
1078faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
10799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    getHwComposer().setVsyncEnabled(disp,
10809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
10818630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
10828630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
10834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
10841c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
108599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
10866b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
10875018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            bool frameMissed = !mHadClientComposition &&
10885018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence != Fence::NO_FENCE &&
10895018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                    mPreviousPresentFence->getSignalTime() == INT64_MAX;
10905018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
1091c5da271eec001da9e11a2786f2618a45257439c3Dan Stoza            if (mPropagateBackpressure && frameMissed) {
10925018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                signalLayerUpdate();
10935018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza                break;
10945018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza            }
10955018288a44ca53b64fce17b3bfb9656a79cc3465Dan Stoza
10966b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
10976b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
10985878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
10996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
11005878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
11015878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
11025878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
11036b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
11046b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
11056b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
11066b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
11076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
11086b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
11096b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
11106b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
11114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11146b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
1115e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
11164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
111787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
11186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
11194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
11206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
11214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11236b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
1124cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
11256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
11264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
11273a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
11284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
1129cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
113014cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
113140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
113205dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
113305dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    preComposition();
113405dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    rebuildLayerStacks();
113505dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    setUpHWComposer();
113605dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doDebugFlashRegions();
113705dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    doComposition();
113805dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    postComposition(refreshStartTime);
113905dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza
114005dacfb68af895fce3cc8ebb0b4aa06c6c336e26Dan Stoza    mPreviousPresentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY);
1141bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza
1142bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    mHadClientComposition = false;
1143bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
1144bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
1145bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza        mHadClientComposition = mHadClientComposition ||
1146bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
1147bfbffeb4d15b8a783e2f8aa21daee5fff755913fDan Stoza    }
114814cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578Dan Stoza
11499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Release any buffers which were replaced this frame
11509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
11519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        layer->releasePendingBuffer();
11529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
11539e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mLayersWithQueuedFrames.clear();
1154cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1155cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1156cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
1157cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
1158cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
1159cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
1160cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
1161cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1162cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
1163cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1164cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1166cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1167cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
1168cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
1169cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
1170cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
1171cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1172cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
1173cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
11743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
11753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
11763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1177da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
1178cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
1179cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1180cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1181cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1182cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
1183cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1184cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
1185cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
1186cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1187bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
11889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
11897bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
11907bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
11917bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
11927bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
11937bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
11947bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
11959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
11969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
1197bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
1198cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1199cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1200cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
1201cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
12029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("preComposition");
12049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1205cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
12061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
12071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
1208cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
12091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        if (layers[i]->onPreComposition()) {
1210cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
1211cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
1212cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1213cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
1214cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
1215cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
1216cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1217a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
121840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballosvoid SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
1219cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
12209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postComposition");
12229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
12231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
12241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
1225cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
1226e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        bool frameLatched = layers[i]->onPostComposition();
1227e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (frameLatched) {
1228e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            recordBufferingStats(layers[i]->getName().string(),
1229e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                    layers[i]->getOccupancyHistory(false));
1230e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
1231cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
12324b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
12339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    sp<Fence> presentFence = mHwc->getRetireFence(HWC_DISPLAY_PRIMARY);
1234faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1235faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (presentFence->isValid()) {
1236faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (mPrimaryDispSync.addPresentFence(presentFence)) {
1237faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1238faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
1239948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
1240faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1241faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1242faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1243b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
12445167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
12452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1246faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1247faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1248faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1249faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
125040845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos    mFenceTracker.addFrame(refreshStartTime, presentFence,
125140845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            hw->getVisibleLayersSortedByZ(), hw->getClientTargetAcquireFence());
125240845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
12534b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
12544b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
12554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
1256a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall        if (presentFence->isValid()) {
12574b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentFence(presentFence);
12584b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
12594b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
12604b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
12619e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            nsecs_t presentTime =
12629e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    mHwc->getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
12634b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
12644b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
12654b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
12664b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
1267b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1268b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
1269b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        return;
1270b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1271b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1272b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    nsecs_t currentTime = systemTime();
1273b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (mHasPoweredOff) {
1274b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = false;
1275b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    } else {
1276b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t period = mPrimaryDispSync.getPeriod();
1277b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t elapsedTime = currentTime - mLastSwapTime;
1278b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        size_t numPeriods = static_cast<size_t>(elapsedTime / period);
1279b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        if (numPeriods < NUM_BUCKETS - 1) {
1280b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[numPeriods] += elapsedTime;
1281b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        } else {
1282b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
1283b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        }
1284b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime += elapsedTime;
1285b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1286b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    mLastSwapTime = currentTime;
1287cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1288cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1289cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
12909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
12919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("rebuildLayerStacks");
12929e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1293cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
129452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
1295cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
129687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
129787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
1298ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
12991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const LayerVector& layers(mDrawingState.layersSortedByZ);
130092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1301ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
1302ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
13039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Vector<sp<Layer>> layersSortedByZ;
13049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
13059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Transform& tr(displayDevice->getTransform());
13069e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect bounds(displayDevice->getBounds());
13079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (displayDevice->isDisplayOn()) {
13081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                SurfaceFlinger::computeVisibleRegions(layers,
13099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getLayerStack(), dirtyRegion,
13109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        opaqueRegion);
13117e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
13121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const size_t count = layers.size();
1313ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
13141eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const sp<Layer>& layer(layers[i]);
13151eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
13169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (s.layerStack == displayDevice->getLayerStack()) {
1317a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
1318a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
1319a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
1320a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
1321ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
13229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
13239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // Clear out the HWC layer if this layer was
13249e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            // previously visible, but no longer is
13259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(displayDevice->getHwcDisplayId(),
13269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    nullptr);
1327ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
132887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
132987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
13303b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
13319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
13329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.set(bounds);
13339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->undefinedRegion.subtractSelf(
13349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    tr.transform(opaqueRegion));
13359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            displayDevice->dirtyRegion.orSelf(dirtyRegion);
13363b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
13373b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1338cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
13393b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
1340cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
13419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ATRACE_CALL();
13429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("setUpHWComposer");
13439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
1344028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1345b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1346b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1347b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1348b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1349b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1350b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1351b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1352b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1353b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1354b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1355b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1356b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1357b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1358b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1359b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1360b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1361b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1362b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1363b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1364b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1365b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
13667143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1367b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1368b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1369b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1370b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1371028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1372028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
13739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // build the h/w work list
13749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (CC_UNLIKELY(mGeometryInvalid)) {
13759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        mGeometryInvalid = false;
13769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
13779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
13789e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const auto hwcId = displayDevice->getHwcDisplayId();
13799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (hwcId >= 0) {
13809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const Vector<sp<Layer>>& currentLayers(
13819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        displayDevice->getVisibleLayersSortedByZ());
13829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                bool foundLayerWithoutHwc = false;
13839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                for (auto& layer : currentLayers) {
13849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    if (!layer->hasHwcLayer(hwcId)) {
13859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        auto hwcLayer = mHwc->createLayer(hwcId);
13869e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (hwcLayer) {
13879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->setHwcLayer(hwcId, std::move(hwcLayer));
13889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
13899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->forceClientComposition(hwcId);
13909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            foundLayerWithoutHwc = true;
13919e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            continue;
1392a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1393a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1394a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
13959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    layer->setGeometry(displayDevice);
13969f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    if (mDebugDisableHWC || mDebugRegion) {
13979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->forceClientComposition(hwcId);
139803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
139903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
140003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
140103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
14029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
140303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
14049f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
14059f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 colorMatrix = mColorMatrix * mDaltonizer();
14069f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
14079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    // Set the per-frame data
14089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
14109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
14119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId < 0) {
14129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            continue;
14139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14149f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        if (colorMatrix != mPreviousColorMatrix) {
14159f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
14169f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
14179f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    "display %zd: %d", displayId, result);
14189f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        }
14199e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
14209e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->setPerFrameData(displayDevice);
142138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
142252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
14239e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
14249f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mPreviousColorMatrix = colorMatrix;
14259f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
14269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14277bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        auto& displayDevice = mDisplays[displayId];
14287bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
14297bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
14307bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
14317bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza
14327bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        status_t result = displayDevice->prepareFrame(*mHwc);
14339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
14349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                " %d (%s)", displayId, result, strerror(-result));
14359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    }
1436cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
143752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1438cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1439cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
14409e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposition");
14419e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
144252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
144392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
14444297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
14452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1446cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1447cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
144802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
144902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
145002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
145102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1452cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1453cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1454cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
145587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
14564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
145752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1462841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
14639e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("postFramebuffer");
1464b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1465a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1466a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1467c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
14689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
14699e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
14707bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        if (!displayDevice->isDisplayOn()) {
14717bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza            continue;
14727bdf55aacf84715fae7dcd495756d9606e900a86Dan Stoza        }
14739e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const auto hwcId = displayDevice->getHwcDisplayId();
14749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
14759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->commit(hwcId);
14769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14772dc3be88bd85791556ab0e6df6a080989886749eDan Stoza        displayDevice->onSwapBuffersCompleted();
1478b2c838b7add20c4515966a80de809b0a1d315001Season Li        displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
14799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
14809e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            sp<Fence> releaseFence = Fence::NO_FENCE;
14819e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
14829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = displayDevice->getClientTargetAcquireFence();
14839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
14849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                auto hwcLayer = layer->getHwcLayer(hwcId);
14859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
148652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
14879e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->onLayerDisplayed(releaseFence);
14889e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        }
14899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hwcId >= 0) {
14909e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mHwc->clearReleaseFences(hwcId);
1491ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1492e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1493e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1494a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1495a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
14966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
14976547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
14986547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
14996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
15006547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
150387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1505841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1506841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
15077cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
15087cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
15097cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
15107cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
15117cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
15127cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1513ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1514ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1515ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1516ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1517ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1518ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1519ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1520ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1521ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1522ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1523e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
152487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1525ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1526ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1527ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1528ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1529ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
15303d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
153287baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
15333d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
15343d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15377dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    // Notify all layers of available frames
15387dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    for (size_t i = 0; i < count; ++i) {
15397dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        currentLayers[i]->notifyAvailableFrames();
15407dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza    }
15417dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15473559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
154913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
1550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
15603559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1563e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
156492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
156592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
156692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1567e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1568e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
156992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
157192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
157293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
157392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
157492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
157592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
157692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
157792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
157892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1579e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1580e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
158192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
15823ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
158327ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
158427ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
158527ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
158602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1587875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
158802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
158902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
159002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
15919e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
15927adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
159302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
159492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
159592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
159692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
159792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
159892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1599e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
16003ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1601097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
1602097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
16031474f8864faafebc92ff79959bb5c698bd29b704Dan Albert                    if (state_binder != draw_binder) {
1604e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
160593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
160693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
160793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
160802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
160902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
161002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
161193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
161293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
161393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
161493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
161593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
161692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
161793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1618db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
161993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
162093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
162193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
162293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
162300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
162400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
162500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
162600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
162700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
16284fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
162993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
163047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
163147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
163247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
163392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
163492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
163592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
163692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
163792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
163892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
163992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1640e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1641e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1642cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
164399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1644db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1645b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1646b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
164770982a5f95f68295244e5f6cc037c193713a5259Dan Stoza                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
164870982a5f95f68295244e5f6cc037c193713a5259Dan Stoza                            new GraphicBufferAlloc());
1649db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
16509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    int32_t hwcId = -1;
165199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
165202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
165302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
165402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
165599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1656db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
16578cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                            if (mUseHwcVirtualDisplays) {
16588cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int width = 0;
16598cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int status = state.surface->query(
16608cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_WIDTH, &width);
16618cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
16628cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query width (%d)", status);
16638cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int height = 0;
16648cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
16658cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_HEIGHT, &height);
16668cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
16678cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query height (%d)", status);
16688cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                int intFormat = 0;
16698cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                status = state.surface->query(
16708cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        NATIVE_WINDOW_FORMAT, &intFormat);
16718cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                ALOGE_IF(status != NO_ERROR,
16728cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        "Unable to query format (%d)", status);
16738cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                auto format = static_cast<android_pixel_format_t>(
16748cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        intFormat);
16758cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza
16768cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                mHwc->allocateVirtualDisplay(width, height, &format,
16778cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                                        &hwcId);
16788cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                            }
16799e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
16805cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                            // TODO: Plumb requested format back up to consumer
16815cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza
16829e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            sp<VirtualDisplaySurface> vds =
16839e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    new VirtualDisplaySurface(*mHwc,
16849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            hwcId, state.surface, bqProducer,
16859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                            bqConsumer, state.displayName);
1686db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1687db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
168847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
168999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
169099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1691cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1692cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1693cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1694cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
16959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (state.type == DisplayDevice::DISPLAY_EXTERNAL) {
16969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            hwcId = DisplayDevice::DISPLAY_EXTERNAL;
16979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            dispSurface = new FramebufferSurface(*mHwc,
16989e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    DisplayDevice::DISPLAY_EXTERNAL,
16999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    bqConsumer);
17009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            producer = bqProducer;
17019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        } else {
17029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            ALOGE("Attempted to add non-external non-virtual"
17039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                    " display");
17049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        }
1705cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1706cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1707cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
170899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1709cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
17109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                state.type, hwcId, state.isSecure, display,
17119e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                dispSurface, producer,
171205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1713cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1714cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
17154fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
17168dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1717cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
17189e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (!state.isVirtualDisplay()) {
17197adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
17201c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
172193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
172292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
172392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
17253559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
17288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
17298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
17308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
17318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
17338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
17348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
17368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
17378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
17388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
17408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
17418430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
17438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
17448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
17458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
17468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
17478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
17488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
17498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
17508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
17518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
17528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
175313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
17541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
17558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
17568430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
17578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
17588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
17598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
17608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
17618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
17628430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
17638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
17648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
17658430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
17668430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
176791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
17688430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
17698430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
17708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
17718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
17728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
177391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
177491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
177591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
177691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
177791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
177891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
177991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
178091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
17818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
178291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
17838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
17848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
17858430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
17868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
17873559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
17883559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
17893559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17911eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
17921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
17933559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
17943559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
17953559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
17963559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
17973559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
17983559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
17993559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
18003559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
18013559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
18021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const size_t count = layers.size();
18033559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
18041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            const sp<Layer>& layer(layers[i]);
18053559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
18063559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
18073559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
18083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
18093559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
18101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
18113dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                Region visibleReg = s.active.transform.transform(
18121501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
18131501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
18140aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
181903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
182003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
182103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
182203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
182303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
182403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
18259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
18269e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        auto& displayDevice = mDisplays[displayId];
18279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getHwcDisplayId() < 0) {
182803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
182903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
18309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
18319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
18329e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            layer->updateCursorPosition(displayDevice);
183303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
183403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
18354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
18364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
18374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
18384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
1839598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    if (!mLayersPendingRemoval.isEmpty()) {
18404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
18414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
1842e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            recordBufferingStats(mLayersPendingRemoval[i]->getName().string(),
1843e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                    mLayersPendingRemoval[i]->getOccupancyHistory(true));
18444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
18454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
18464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
18474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
18484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
18494b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
18504b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
18514b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
18524b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
18534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
18542d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
18552d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
18564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
186087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
186187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1863841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
18649e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("computeVisibleRegions");
1865841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
187413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer = currentLayers[i];
1875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
18771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
188087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
188187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
188287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1883ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1884ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1885ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1887ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1888ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1889ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1890ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1891ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1892ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1893ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1895ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1896ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1897ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1898ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1899ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1901ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1902a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1903a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1904a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1905a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1906a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1907a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1908a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1909a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1910a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1911a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1912ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1913ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1914da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
19154125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
19163dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr            Rect bounds(s.active.transform.transform(layer->computeBounds()));
1917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1918ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1919ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1920ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
19213dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                    const Transform tr(s.active.transform);
192222f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                    if (tr.preserveRects()) {
192322f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transform the transparent region
192422f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion = tr.transform(s.activeTransparentRegion);
19254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
192622f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transformation too complex, can't do the
192722f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        // transparent region optimization.
192822f7fc45af6ce8c1a2b9543315347bd44d1c9e08Dan Stoza                        transparentRegion.clear();
19294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1930ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1932ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
19333dcabfab7ef80df5884b269fec17350a26da6f51Robert Carr                const int32_t layerOrientation = s.active.transform.getOrientation();
19349e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                if (s.alpha == 1.0f && !translucent &&
1935ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1936ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1937ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1938ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1942ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1943ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1944ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1945ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1946ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1947ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
19564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1959a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1960ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1961ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1962ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1963ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1964ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1965ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1966ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1967ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1968ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1969ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1970a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1971ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
19724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
19734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1974ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1975ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
198087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1982ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
19848b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1985a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1988a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1989a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
199287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
199587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
199687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
199792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
19984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
19994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
20004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
200192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
200292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
200387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
200487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
20056b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
2006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("handlePageFlip");
20089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
20094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
201099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
20114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
20121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
20136b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
201451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
201551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
201651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
201751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
201851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
201951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
202051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
202151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
202251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
202351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
202451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layers.size(); i<count ; i++) {
20251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const sp<Layer>& layer(layers[i]);
20266b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
20276b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
20286b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
20299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mLayersWithQueuedFrames.push_back(layer.get());
2030ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
2031ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
20326b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
2033ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
2034ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
20356b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
203651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    }
20379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    for (auto& layer : mLayersWithQueuedFrames) {
203887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
2039ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
20401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
204187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
20424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
20434da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
20443b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
20456b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
20466b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
20476b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
20486b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
20499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (frameQueued && mLayersWithQueuedFrames.empty()) {
20506b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
20516b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
20526b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
20536b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
20549e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    return !mLayersWithQueuedFrames.empty();
2055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2057ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
2058ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
20599e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mGeometryInvalid = true;
2060ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
2061ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
206299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2063cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
206487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
2065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20667143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
20677143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
20687143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
20697143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
20707143316af216fa92c31a60d4407b707637382da1Dan Stoza    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
20717143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
20729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("Skipping display composition");
20737143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
20747143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
20757143316af216fa92c31a60d4407b707637382da1Dan Stoza
20769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doDisplayComposition");
20779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
207887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
207987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
2080b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
20814297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
2082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
20840f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
208529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
208629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
208729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
20884297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
2089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
20900f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
209129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
2092df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
209395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
20940f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
20954297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
2096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
209729d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
20984297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
20994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
2100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21039f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (!doComposeSurfaces(hw, dirtyRegion)) return;
2104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21059c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
21064297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
2107da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
2108da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
2109da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
2110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stozabool SurfaceFlinger::doComposeSurfaces(
21139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const sp<const DisplayDevice>& displayDevice, const Region& dirty)
2114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21159e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("doComposeSurfaces");
21169e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
21179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto hwcId = displayDevice->getHwcDisplayId();
21189f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
21199f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    mat4 oldColorMatrix;
21209f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    const bool applyColorMatrix = !mHwc->hasDeviceComposition(hwcId) &&
21219f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza            !mHwc->hasCapability(HWC2::Capability::SkipClientColorTransform);
21229f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
21239f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        mat4 colorMatrix = mColorMatrix * mDaltonizer();
21249f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix);
21259f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
21269f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
21279e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    bool hasClientComposition = mHwc->hasClientComposition(hwcId);
21289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hasClientComposition) {
21299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        ALOGV("hasClientComposition");
2130a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
21319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
2132c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
21339e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                  displayDevice->getDisplayName().string());
21343f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
21353f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
21363f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
21373f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
21383f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
2139c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
2140a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
2141a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
21429e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
21439e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (hasDeviceComposition) {
2144b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
2145b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
2146b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
21473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
2148b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
21499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            mRenderEngine->clearWithColor(0, 0, 0, 0);
2150b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
2151766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
21529e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region bounds(displayDevice->getBounds());
2153766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2154766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
2155766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
2156766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
21579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region letterbox(bounds.subtract(displayDevice->getScissor()));
2158766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2159766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
21609e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            Region region(displayDevice->undefinedRegion.merge(letterbox));
2161766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2162766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
2163766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
2164766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
2165b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
216687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
2167b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
21689e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                drawWormhole(displayDevice, region);
2169b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
2170a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
2171f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
21729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
2173766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
2174f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
2175f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
21769e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& bounds(displayDevice->getBounds());
21779e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Rect& scissor(displayDevice->getScissor());
2178f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
2179f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
2180f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
2181f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
21823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2183f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
21849e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                const uint32_t height = displayDevice->getHeight();
21859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
21863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
2187f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
2188f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
218985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
21904b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
219185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
219285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
219385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
21944b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
21959e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    ALOGV("Rendering client layers");
21969e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const Transform& displayTransform = displayDevice->getTransform();
21979e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    if (hwcId >= 0) {
219885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
21999e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        bool firstLayer = true;
22009e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
22019e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            const Region clip(dirty.intersect(
22029e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
22039e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("Layer: %s", layer->getName().string());
22049e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGV("  Composition type: %s",
22059e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    to_string(layer->getCompositionType(hwcId)).c_str());
220685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
22079e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                switch (layer->getCompositionType(hwcId)) {
22089e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Cursor:
22099e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Device:
22109e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::SolidColor: {
2211ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
22129e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        if (layer->getClearClientTarget(hwcId) && !firstLayer &&
22139e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                layer->isOpaque(state) && (state.alpha == 1.0f)
22149e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                                && hasClientComposition) {
2215cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
2216cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
22179e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                            layer->clearWithOpenGL(displayDevice, clip);
2218cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
221985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
222085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
22219e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    case HWC2::Composition::Client: {
22229e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                        layer->draw(displayDevice, clip);
222385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
2224a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
22259e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    default:
2226da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
2227cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
22289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            } else {
22299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                ALOGV("  Skipping for empty clip");
2230a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
22319e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            firstLayer = false;
223285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
223385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
223485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
22359e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
223685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
22379e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                    displayTransform.transform(layer->visibleRegion)));
223885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
22399e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza                layer->draw(displayDevice, clip);
224085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
22414b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
22424b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
2243f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
22449f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    if (applyColorMatrix) {
22459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza        getRenderEngine().setupColorTransform(oldColorMatrix);
22469f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    }
22479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza
2248f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
22499e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    mRenderEngine->disableScissor();
22503f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
2251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
225455801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
22553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
22563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
2257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22597d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
2260ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
22616710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
226213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
22631b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
22647d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    // add this layer to the current state list
22657d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    {
22667d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        Mutex::Autolock _l(mStateLock);
22677d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {
22687d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza            return NO_MEMORY;
22697d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        }
22707d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mCurrentState.layersSortedByZ.add(lbc);
22717d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
22727d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
22737d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
227496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
2275ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
22764f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
22777d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    return NO_ERROR;
227896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
227996f0819f81293076e652792794a961543e6750d7Mathias Agopian
228022851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stozastatus_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
228196f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
228222851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    sp<Layer> layer = weakLayer.promote();
228322851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    if (layer == nullptr) {
228422851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        // The layer has already been removed, carry on
228522851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza        return NO_ERROR;
228622851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    }
228722851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza
2288598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
2289598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    if (index >= 0) {
2290598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        mLayersPendingRemoval.push(layer);
2291598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        mLayersRemoved = true;
2292598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        setTransactionFlags(eTransactionNeeded);
2293598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch        return NO_ERROR;
2294598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    }
2295598f6d5429b290f33107ef678328914b99c8312eSteve Pfetsch    return status_t(index);
2296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2298c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
2299dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
2300dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
2301dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
23023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
2303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
2304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
230999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
2310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
2312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23148b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
23158b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
23168b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
23178b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
23188b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
23197c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2320698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
232128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2322e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
23232d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
23242d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
23252d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
23262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
23277c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
23282d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
23292d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
23307c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
23317c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
23327c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
23332d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
23342d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
23352d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
23362d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
23372d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
23382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2339e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2340e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2342e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2343b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2344b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2345e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2346698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2347698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2348d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2349d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2350d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2351d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2352d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2353d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2354d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2355d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2356097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2357d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
2358d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
2359d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
2360d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2361d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2362d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2363d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2364d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2365698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2366386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
23672a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // If a synchronous transaction is explicitly requested without any changes,
23682a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // force a transaction anyway. This can be used as a flush mechanism for
23692a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    // previous async transactions.
23702a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    if (transactionFlags == 0 && (flags & eSynchronous)) {
23712a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr        transactionFlags = eTransactionNeeded;
23722a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr    }
23732a7dbb4135976b01015d237ac95d5eeb3ed7a85cRobert Carr
237428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2375ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (mInterceptor.isEnabled()) {
2376ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags);
2377ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
2378468051e20be19130572231266db306396a56402bIrvel
2379386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
238028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2381698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2382386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2383386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2384386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
23852d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
23862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
23872d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
23882d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2389386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
23902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2391386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2392386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2393386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2394386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
23952d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
23962d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2397386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2398386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2399cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2403e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2404e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
24059a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
24069a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
24079a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
24089a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2409e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
24109a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
24113ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2412e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2413e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2414097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2415e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2416e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2417e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2418e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2419e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2420e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2421e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2422e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2423e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2424e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
242500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2426e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2427e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2428e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2429e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2430e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2431e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2432e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2433e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2434e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2435e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2436e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2437e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2438e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
243947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
244047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
244147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
244247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
244347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
244447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
244547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
244647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
244747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
244847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2449e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2450e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2451e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2452e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2453e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2454e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2455e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2456e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2457e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
245813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2459e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2460e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
246199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr        bool geometryAppliesWithResize =
246299e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr                what & layer_state_t::eGeometryAppliesWithResize;
2463e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
246499e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
2465e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
246682364e3cea0bf88fa8147766433329b3dd5148b8Robert Carr            }
2467e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2468e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2469e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2470e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
247147db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos            if (layer->setLayer(s.z) && idx >= 0) {
2472e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2473e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2474e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2475e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2476e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2477e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2478e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2479e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2480e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2481e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2482e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2483e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2484e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
24859e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            if (layer->setAlpha(s.alpha))
2486e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2487e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2488e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2489e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2490e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2491e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2492e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2493e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2494e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2495e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2496231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        if (what & layer_state_t::eFlagsChanged) {
2497e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2498e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2499e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2500e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
250199e27f0bc236e38d88ff4f9912ede514a729b8ebRobert Carr            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
2502e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2503e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2504acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        if (what & layer_state_t::eFinalCropChanged) {
2505acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos            if (layer->setFinalCrop(s.finalCrop))
2506acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos                flags |= eTraversalNeeded;
2507acbe67888f0bd65d5400400f0115bae6bd6199dcPablo Ceballos        }
2508e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2509e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
251147db6ebf45c74b6de94afed05c0aa9c1d8a0fda8Pablo Ceballos            if (layer->setLayerStack(s.layerStack) && idx >= 0) {
2512e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2513e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2514e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2515e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2516e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2517e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2518e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
25197dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        if (what & layer_state_t::eDeferTransaction) {
25207dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            layer->deferTransactionUntil(s.handle, s.frameNumber);
25217dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // We don't trigger a traversal here because if no other state is
25227dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza            // changed, we don't want this to cause any more work
25237dde599bf1a0dbef7390d91c2689d506371cdbd7Dan Stoza        }
2524c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        if (what & layer_state_t::eOverrideScalingModeChanged) {
2525c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            layer->setOverrideScalingMode(s.overrideScalingMode);
2526c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // We don't trigger a traversal here because if no other state is
2527c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr            // changed, we don't want this to cause any more work
2528c3574f7b0141c69fdca25ccafb80ff334462f9a3Robert Carr        }
2529e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2530e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2531e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2532e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
25334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
25340ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
25350ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
25364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
25374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
2538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
25396e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2540921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
25416e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
25424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
25436e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
25448b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
25454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
25464d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
25474d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
25484d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
25493165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
25503165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
25514d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
25524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
25534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
25553165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
25564d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
25574d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
25584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
25594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
25604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
25614d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25657d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
25667d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
2567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
25687d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
25697d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    result = addClientLayer(client, *handle, *gbp, layer);
25707d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
25717d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
25727d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
2573ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    mInterceptor.saveSurfaceCreation(layer);
25747d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
25757d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    setTransactionFlags(eTransactionNeeded);
25764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
25804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
25814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
258492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
25908f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
25954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
25964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
25974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2598b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
26004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
26014d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
26024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
26064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
26074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
26094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
26104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2611b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
26124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2613118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2614118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2615ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
26169a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
26176710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
26186710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
26196710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
26206710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
2621ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.saveSurfaceDeletion(l);
26226710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
26236710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
26246710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
26259a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
26269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
26279a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
26289a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
262913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
26316710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
26326710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
263322851c3ba2cf5ccb0c3a0aa6c5b94ae123a5616aDan Stoza    return removeLayer(layer);
2634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2636b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2637b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
263813a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
263901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
264013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
264113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
264213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
264301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
264401e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2645692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
264601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
264713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
26484c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
26494c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
265047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
265147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
265213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
265313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
26542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
26556547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
26569e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
26579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
26586547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
265913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
266013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
266113a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
266213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
266313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
266413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
2665c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
266613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
266713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
266813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
266913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
267013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
267113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
267213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
267313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
267413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
26752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
26762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
26772c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
26782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
26792c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
26802c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
268113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
26822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
26832c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2684c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2685c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2686c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
26872c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
26882c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
26892c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
26902c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
26912c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2692c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
2693ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    if (mInterceptor.isEnabled()) {
2694ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        Mutex::Autolock _l(mStateLock);
2695ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken());
2696ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        if (idx < 0) {
2697ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            ALOGW("Surface Interceptor SavePowerMode: invalid display token");
2698ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel            return;
2699ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        }
2700ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel        mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode);
2701ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel    }
2702ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel
27032c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
2704f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn on the display
27052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2706c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2707c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2708c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2709948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2710c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27122c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
2713b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = true;
27142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
2715f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
2716f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
2717f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        param.sched_priority = 1;
2718f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
2719f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_FIFO on display on");
2720f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
27212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2722f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        // Turn off the display
2723f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        struct sched_param param = {0};
2724f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        if (sched_setscheduler(0, SCHED_OTHER, &param) != 0) {
2725f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray            ALOGW("Couldn't set SCHED_OTHER on display off");
2726f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray        }
2727f9d4e44fff4f9c0a09e5820a5596c6dec34ee4daTim Murray
2728c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2729948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2730948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2731cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2732cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2733cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2734c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
27352c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
27362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
27372c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
27382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
27392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2740b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
27442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2745db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2746db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
27472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2748b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
27492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
27502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
27512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2752b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
27532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2754db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
27552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
27567306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
27579e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
27582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
27592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2760db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
27612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2762db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2763b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2764b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2765b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
27662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2767db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2768b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2769b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2770b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2771b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
277599b49840d309727678b77403d6cc9f920111623fMathias Agopian
2776bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2777bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2778bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2779bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2780bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
278174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2782bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
2784fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
27859795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
27869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
2787fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
2788fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
27899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
2790fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
2791fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
2792fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
27939795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
27949795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
279582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
279682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
279725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
279825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
279925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
280025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
280125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
280274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
280335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
280425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
280525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
280625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
280725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
280882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
280974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
281035aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
281182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
281225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
281325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
281425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
281525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
281674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
281735aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
281825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2819c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2820c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2821c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2822c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2823c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2824c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2825c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2826b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2827b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            if ((index < numArgs) &&
2828b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                    (args[index] == String16("--static-screen"))) {
2829b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                index++;
2830b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpStaticScreenStats(result);
2831b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpAll = false;
2832b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            }
283340845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos
283440845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            if ((index < numArgs) &&
283540845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                    (args[index] == String16("--fences"))) {
283640845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                index++;
283740845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                mFenceTracker.dump(&result);
283840845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos                dumpAll = false;
283940845df1285b387bcbf8f43ac72228eee2606d80Pablo Ceballos            }
2840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
28411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
284282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
284374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
284482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
284548b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
284682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
284782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
284848b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
284982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
285082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
285182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
285282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
285348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2854c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2855c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
285625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
285725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
285825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
285925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
286013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
286174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
286225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
286325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
286425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
286582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
286674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
286782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
286882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
286982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
287082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
287182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
287282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
287348b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
28749e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
28759e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const nsecs_t period = activeConfig->getVsyncPeriod();
287686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
28774b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
28784b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2879d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
28804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
28814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
28824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const size_t count = currentLayers.size();
28834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        for (size_t i=0 ; i<count ; i++) {
288413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
28854b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2886d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
28874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
288882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
288982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
289082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2891ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
289225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2893c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
289425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
289525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
289625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
289725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
289825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
289925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
290025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
290125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
290225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
290325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
290413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
290525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2906d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
290725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
290825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
29094b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2910d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
291125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
291225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
29136547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
29146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
29156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
29166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
29176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const size_t count = drawingLayers.size();
29186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
29196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        const sp<Layer>& layer(drawingLayers[i]);
29206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
29216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
29226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
29236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
29246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
29256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
29264803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
29274803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
29284803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
29294803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
29304803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
29314803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
29324803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
29334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
29344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
29354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
29364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
29374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
29384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
29394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
29404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
29414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
29424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
2943b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const
2944b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{
2945b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("Static screen stats:\n");
2946b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
2947b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float bucketTimeSec = mFrameBuckets[b] / 1e9;
2948b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float percent = 100.0f *
2949b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
2950b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
2951b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                b + 1, bucketTimeSec, percent);
2952b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
2953b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
2954b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float percent = 100.0f *
2955b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
2956b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
2957b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            NUM_BUCKETS - 1, bucketTimeSec, percent);
2958b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza}
2959b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2960e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::recordBufferingStats(const char* layerName,
2961e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::vector<OccupancyTracker::Segment>&& history) {
2962e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
2963e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    auto& stats = mBufferingStats[layerName];
2964e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& segment : history) {
2965e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (!segment.usedThirdBuffer) {
2966e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.twoBufferTime += segment.totalTime;
2967e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2968e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (segment.occupancyAverage < 1.0f) {
2969e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.doubleBufferedTime += segment.totalTime;
2970e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        } else if (segment.occupancyAverage < 2.0f) {
2971e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            stats.tripleBufferedTime += segment.totalTime;
2972e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2973e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ++stats.numSegments;
2974e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        stats.totalTime += segment.totalTime;
2975e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
2976e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
2977e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
2978e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozavoid SurfaceFlinger::dumpBufferingStats(String8& result) const {
2979e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("Buffering stats:\n");
2980e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("  [Layer name] <Active time> <Two buffer> "
2981e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            "<Double buffered> <Triple buffered>\n");
2982e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    Mutex::Autolock lock(mBufferingStatsMutex);
2983e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    typedef std::tuple<std::string, float, float, float> BufferTuple;
2984e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::map<float, BufferTuple, std::greater<float>> sorted;
2985e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& statsPair : mBufferingStats) {
2986e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const char* name = statsPair.first.c_str();
2987e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferingStats& stats = statsPair.second;
2988e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        if (stats.numSegments == 0) {
2989e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            continue;
2990e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        }
2991e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = ns2ms(stats.totalTime) / 1000.0f;
2992e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float twoBufferRatio = static_cast<float>(stats.twoBufferTime) /
2993e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.totalTime;
2994e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float doubleBufferRatio = static_cast<float>(
2995e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.doubleBufferedTime) / stats.totalTime;
2996e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float tripleBufferRatio = static_cast<float>(
2997e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                stats.tripleBufferedTime) / stats.totalTime;
2998e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        sorted.insert({activeTime, {name, twoBufferRatio,
2999e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                doubleBufferRatio, tripleBufferRatio}});
3000e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3001e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (const auto& sortedPair : sorted) {
3002e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        float activeTime = sortedPair.first;
3003e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        const BufferTuple& values = sortedPair.second;
3004e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        result.appendFormat("  [%s] %.2f %.3f %.3f %.3f\n",
3005e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<0>(values).c_str(), activeTime,
3006e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<1>(values), std::get<2>(values),
3007e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                std::get<3>(values));
3008e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
3009e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    result.append("\n");
3010e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
3011e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
3012e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
301374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
301474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
301582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
30163e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
30173e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
30183e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
30193e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
30203e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
30213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
30223e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
30233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
30243e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
302582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
302682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
302782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
302882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
302982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
303082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
3031bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
303282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
30334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
30344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
30353e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
30363e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
30374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
30383e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
30404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
30414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
30424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
30434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
30443e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
3045ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
30463e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
3047ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
3048ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
3049ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
30509e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    const auto& activeConfig = mHwc->getActiveConfig(HWC_DISPLAY_PRIMARY);
30519e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza
305241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
305341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
305441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
305524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
305624cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
30579e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
30589e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza        PRESENT_TIME_OFFSET_FROM_VSYNC_NS, activeConfig->getVsyncPeriod());
305941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
306041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
3061b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    // Dump static screen stats
3062b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3063b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    dumpStaticScreenStats(result);
3064b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
3065b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
3066e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    dumpBufferingStats(result);
3067e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
30684803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
306982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
307082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
307182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
307282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
30733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
307486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Visible layers (count = %zu)\n", count);
30753e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
307682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
307713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
30783e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
307982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
3080bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
308182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
30825f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
30835f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
30845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
30853e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
308686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
30873e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
30885f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
30895f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
309074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
30915f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
30925f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
30935f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
309482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
309582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
30961b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
30973e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
309874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
30993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31001b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
3101888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
31024297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
3103ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
31043e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
31053e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
31063e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
31073e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31083e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
3109ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
3110ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
3111875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
31129795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
31134297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
31142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
31152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
311674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
311782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
311882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
3119c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
312082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
312182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
3122ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
3123ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
3124ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
312582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
312682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
3127c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
31289e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            1e9 / activeConfig->getVsyncPeriod(),
31299e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiX(),
31309e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            activeConfig->getDpiY(),
3131ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
313282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
313374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
313482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
313582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
313674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
313782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
313882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
313982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
314082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
314182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
314274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
3143e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    result.append("\n");
3144e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3145e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    /*
3146e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     * HWC layer minidump
3147e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza     */
3148e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    for (size_t d = 0; d < mDisplays.size(); d++) {
3149e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
3150e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        int32_t hwcId = displayDevice->getHwcDisplayId();
3151e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
3152e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            continue;
3153e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3154e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza
3155e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.appendFormat("Display %d HWC layers:\n", hwcId);
3156e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        Layer::miniDumpHeader(result);
3157e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        for (size_t l = 0; l < count; l++) {
3158e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            const sp<Layer>& layer(currentLayers[l]);
3159e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza            layer->miniDump(result, hwcId);
3160e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        }
3161e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza        result.append("\n");
3162e22aec741f1530cde86c38989bcc2f87626b93b0Dan Stoza    }
316382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
316482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
316582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
316682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
31673e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
316874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
31693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
31709f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza    bool hwcDisabled = mDebugDisableHWC || mDebugRegion;
31719e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza    result.appendFormat("  h/w composer %s\n",
31729e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            hwcDisabled ? "disabled" : "enabled");
317374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
317482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
317582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
317682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
317782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
317882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
317982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
3180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
318213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
318348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
3184db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
318548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
318648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
318748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
318848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
318948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
319048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
319148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
319248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
319348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
319448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
319548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
319648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
319748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
3198cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
3199cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
320063f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
320163f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
320263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
320363f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
320463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
320563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
320663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
320763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
320863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
320924cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
321063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
321163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
321263f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
321363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
321463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
321563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
321663f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
321763f165fd6b86d04be94d4023e845e98560504a96Keun young Park
32186e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
3219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
3220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
3221041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
3222698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
3223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
3224d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
3225d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
32262c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
3227c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza        case GET_HDR_CAPABILITIES:
3228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
3229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
3230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
3231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
3232a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
32333bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
323499b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
32356e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3236375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
3237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
32381b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
32391b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
32401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
32411b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
32421b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
32431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
32441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
32451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
324699b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
324799b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
32486e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard                ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid);
32491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
32501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
32511b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
3252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
32546e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    return OK;
32556e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard}
32566e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard
32576e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglardstatus_t SurfaceFlinger::onTransact(
32586e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
32596e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard{
32606e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    status_t credentialCheck = CheckTransactCodeCredentials(code);
32616e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    if (credentialCheck != OK) {
32626e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard        return credentialCheck;
32636e8e98a23592c2522396b673145814a4bbee69dbFabien Sanglard    }
32641b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
3266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
3267b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
326899ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
3269375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
3270375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
3271375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
3272e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
3273375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
3274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
3275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
3277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
327801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
327935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
3280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
3282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
3283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
328453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
328553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
328853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
3289cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3290cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
3291cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
3292e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
3293e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
3294e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
3295e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
3296cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
3297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
32984d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
32994d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
33004d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
33014d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
330253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
330353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
330453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
330553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
330653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
330753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
3308a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
3309a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
3310a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
3311a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
3312a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
3313a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
3314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
331501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
3316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
3317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
3318b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
331912839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
3320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
3321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
3322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
33234297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
33244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
3325ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
3326ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
3327ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
3328ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
3329ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
3330ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
33319f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 1:
33329f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Protanomaly);
33339f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
33349f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 2:
33359f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
33369f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
33379f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    case 3:
33389f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
33399f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
33409f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    default:
33419f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        mDaltonizer.setType(ColorBlindnessType::None);
33429f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        break;
3343ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3344ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
33459f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Correction);
3346ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
33479f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                    mDaltonizer.setMode(ColorBlindnessMode::Simulation);
3348ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
3349ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
3350ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
33519c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
33529c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
33539c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
33549c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
33559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
33569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
33579c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
33589c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
33599c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
3360794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
33619f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        for (size_t j = 0; j < 4; j++) {
33629f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                            mColorMatrix[i][j] = data.readFloat();
33639f26a9c8be6f00f55cbc30b93adf4895c6a093aaDan Stoza                        }
33649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
33659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
33669c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
33679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
33689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
33699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
33709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
3371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
3372f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
3373f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
3374f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
3375645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
3376645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
3377f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
3378f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
3379ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
3380ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
3381ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
3382ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
3383ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
3384db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1018: { // Modify Choreographer's phase offset
3385db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3386db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3387db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3388db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1019: { // Modify SurfaceFlinger's phase offset
3390db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3394468051e20be19130572231266db306396a56402bIrvel            case 1020: { // Layer updates interceptor
3395468051e20be19130572231266db306396a56402bIrvel                n = data.readInt32();
3396468051e20be19130572231266db306396a56402bIrvel                if (n) {
3397468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor enabled");
3398ffc9efc4b55df38ac524f20cdd1a2fca8e259faeIrvel                    mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays);
3399468051e20be19130572231266db306396a56402bIrvel                }
3400468051e20be19130572231266db306396a56402bIrvel                else{
3401468051e20be19130572231266db306396a56402bIrvel                    ALOGV("Interceptor disabled");
3402468051e20be19130572231266db306396a56402bIrvel                    mInterceptor.disable();
3403468051e20be19130572231266db306396a56402bIrvel                }
3404468051e20be19130572231266db306396a56402bIrvel                return NO_ERROR;
3405468051e20be19130572231266db306396a56402bIrvel            }
34068cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            case 1021: { // Disable HWC virtual displays
34078cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                n = data.readInt32();
34088cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                mUseHwcVirtualDisplays = !n;
34098cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza                return NO_ERROR;
34108cf150a0341768133b37cd9c6f2369bf6f79a943Dan Stoza            }
3411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
3414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
341653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
341787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
341899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
341953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
342053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
342159119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
34222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
34232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
342459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
34252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
34262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
34272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
3428b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
3429b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
3430b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
3431b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
34322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
34332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
3434b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
3435b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
3436b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
3437b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3438b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
3439b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
3440b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
3441b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
3442b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3443b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
3444b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
3445b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
3446b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
3447b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
34482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
34492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
34502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
34512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
34522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
3453b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
34542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
34552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
34562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
34572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
34592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
34602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
34612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
34622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3464b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
3465b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
3466b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
34672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
34682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
3469c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
34702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
34712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
34722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
34732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
3474b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
3475b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
3476b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
3477b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
34782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
34792ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
34802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
3481b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
3482b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
3483b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
34842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
34852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
34862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
3487c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
34882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
34892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
34902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3491b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
34922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
34932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
34942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
3495b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
3496b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
3497b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
3498b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
3499097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
35002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
3501b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
35022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
35032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
35042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
3507c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh    explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
3508b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
3509b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
351053390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        result(NO_ERROR),
3511b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
351253390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        exitRequested(false),
351353390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        code(0),
351453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        data(NULL),
351553390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos        reply(NULL)
3516b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
3517b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
3518b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
35192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
35202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
35212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
35222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
35232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
35242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
3526b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
35272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
3528aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
35292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
3530b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
3531b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
3532b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
35332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
35342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
35352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
35362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
35382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
35392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3540c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3541c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3542c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
35432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
35452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
35462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
35482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
35492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
35505ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
35515ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
35525ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
3553b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
35545ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
3555c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
3556c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
3557c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
3558c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
3559c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3560c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3561c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
3562c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
3563c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3564c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
3565c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
3566c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3567c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
3568c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
3569c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3570c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
3571c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3572c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
3573c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3574c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
3575c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
35762a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
35772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
35782a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
35792a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
3580c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
35812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
35822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
3583c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
3584c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
35852a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
3586b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot;
35872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
35882a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
35892a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
35902a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
3591c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3592c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                uint32_t minLayerZ, uint32_t maxLayerZ,
3593b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool useIdentityTransform,
3594b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                Transform::orientation_flags rotation,
3595b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                bool isLocalScreenshot)
35962a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
3597c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
35982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
3599c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
3600b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              rotation(rotation), result(PERMISSION_DENIED),
3601b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos              isLocalScreenshot(isLocalScreenshot)
36022a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
36032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
36042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
36052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
36062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
36072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
36082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
36092a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
3610c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
3611c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3612b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                    useIdentityTransform, rotation, isLocalScreenshot);
3613097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
36142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
36152a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
36162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
36172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
36182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
36192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
36202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
36212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
36222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
36232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
36242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
36252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
36262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
3627c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3628b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            useIdentityTransform, rotationFlags, isLocalScreenshot);
36292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
36302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
36312a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
36322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
36332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
36342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
3635118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3636118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3637180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3638180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3639180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3640c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3641180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ,
3642c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
3643180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3644180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
36453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3646180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3647180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
364889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
364989fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
365089fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
36510e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
3652180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3653c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3654c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3655c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3656c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3657c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3658c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3659c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3660c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3661c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3662c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3663c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3664be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
3665be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3666c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3667c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3668c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3669c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3670be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
3671be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3672c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3673c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3674180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
36753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3676180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3677180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3678c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
3679c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
36803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3681180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3682180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
36833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3684180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3685180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const LayerVector& layers( mDrawingState.layersSortedByZ );
3686180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const size_t count = layers.size();
3687180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
3688180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<Layer>& layer(layers[i]);
36891eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
3690180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
3691180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
3692180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
3693180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
3694c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    layer->draw(hw, useIdentityTransform);
3695180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
3696180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
3697180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
3698180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
3699180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3700180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3701931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
3702180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
3703180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3704180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
37052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
37062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
37072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3708c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3709c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3710b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool useIdentityTransform, Transform::orientation_flags rotation,
3711b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        bool isLocalScreenshot)
371274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
3713fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
3714fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
3715180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
37163502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_w = hw->getWidth();
37173502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_h = hw->getHeight();
37183502416204d9dbd905012ee586d8bd145323809fDan Stoza
37193502416204d9dbd905012ee586d8bd145323809fDan Stoza    if (rotation & Transform::ROT_90) {
37203502416204d9dbd905012ee586d8bd145323809fDan Stoza        std::swap(hw_w, hw_h);
37213502416204d9dbd905012ee586d8bd145323809fDan Stoza    }
3722180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3723180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
3724180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
3725180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
3726180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
3727180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3728180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3729180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
3730180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
3731180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3732b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    bool secureLayerIsVisible = false;
3733b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    const LayerVector& layers(mDrawingState.layersSortedByZ);
3734b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    const size_t count = layers.size();
3735b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    for (size_t i = 0 ; i < count ; ++i) {
3736b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const sp<Layer>& layer(layers[i]);
3737b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        const Layer::State& state(layer->getDrawingState());
3738b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ &&
3739b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                state.z <= maxLayerZ && layer->isVisible() &&
3740b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos                layer->isSecure()) {
3741b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos            secureLayerIsVisible = true;
3742b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        }
3743b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
3744b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
3745b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    if (!isLocalScreenshot && secureLayerIsVisible) {
3746b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        ALOGW("FB is protected: PERMISSION_DENIED");
3747b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos        return PERMISSION_DENIED;
3748b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos    }
3749b5b3563058c178811d434ab6e8c4ead4a519701bPablo Ceballos
37500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
37510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
375283cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
3753605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
3754605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Put the screenshot Surface into async mode so that
3755605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // Layer::headFenceHasSignaled will always return true and we'll latch the
3756605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // first buffer regardless of whether or not its acquire fence has
3757605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // signaled. This is needed to avoid a race condition in the rotation
3758605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    // animation. See b/30209608
3759605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos    sur->setAsyncMode(true);
3760605d15afbb801ddeee173a3f430006bd25c07d2ePablo Ceballos
37610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
376274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
37635a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
37645a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    if (result == NO_ERROR) {
37653ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
37663ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
37672a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
37680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
37690aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
37704ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
37710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
37720aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
37732a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
37740aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
37750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
37760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
37770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
37780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
37790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
37800aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
3781866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
37820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
37830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
37840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
37850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
37860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
37873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
37883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
37893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
37903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
37910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
37920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
37930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
37940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3795c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
3796c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
3797c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
3798d555684cb36dfb959694db76962e570184f98838Mathias Agopian
3799866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
3800866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
3801866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
3802866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
3803866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
3804866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
38059707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
38069707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
3807866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3808866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
3809866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
38102d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
3811866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
3812866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
3813866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
3814866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
3815866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
3816866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
38172d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
3818866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3819866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
3820866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
3821866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
3822866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
3823866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
3824866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
3825866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
3826866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
3827866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
3828866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
3829866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
3830866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
3831866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
38322d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
3833866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
38342d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
38352d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
3836d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3837d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3838d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3839d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3840d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3841d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3842d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3843d555684cb36dfb959694db76962e570184f98838Mathias Agopian
38440aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
38450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
38460aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
3847f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        window->cancelBuffer(window, buffer, syncFd);
3848f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                        buffer = NULL;
38490aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
38500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
38510aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
38520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
38530aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
385474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
3855f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                if (buffer) {
3856f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    // queueBuffer takes ownership of syncFd
3857f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                    result = window->queueBuffer(window, buffer, syncFd);
3858f3209b03b3adbf6868c2dcadb07adc5f865f5688Prathmesh Prabhu                }
385974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
38600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
38610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
386274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
38630aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
386474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
386574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
386674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
386774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
386874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3869d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3870d555684cb36dfb959694db76962e570184f98838Mathias Agopian        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
3871fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3872d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3873d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3874d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3875fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3876fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3877fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3878fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3879fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3880fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
3881fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const LayerVector& layers( mDrawingState.layersSortedByZ );
3882fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const size_t count = layers.size();
3883fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
3884fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const sp<Layer>& layer(layers[i]);
3885fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
3886fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
3887fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
3888fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
38899e56aa0fdb5f7121b9b975c6c16db103ea4d2fe9Dan Stoza            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
3890fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
3891fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            i, layer->getName().string(), state.layerStack, state.z,
3892fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
3893fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3894fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3895fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian}
3896fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
3897ce796e78a57018f186b062199c75d94545318acaPablo Ceballosbool SurfaceFlinger::getFrameTimestamps(const Layer& layer,
3898ce796e78a57018f186b062199c75d94545318acaPablo Ceballos        uint64_t frameNumber, FrameTimestamps* outTimestamps) {
3899ce796e78a57018f186b062199c75d94545318acaPablo Ceballos    return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps);
3900ce796e78a57018f186b062199c75d94545318acaPablo Ceballos}
3901ce796e78a57018f186b062199c75d94545318acaPablo Ceballos
39021b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
39031b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3904921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
3905921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3906921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3907921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
390813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : SortedVector<sp<Layer> >(rhs) {
3909921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3910921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3911921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
3912921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
3913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3914be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
391513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
391613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
3917be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
39181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t ls = l->getCurrentState().layerStack;
39191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rs = r->getCurrentState().layerStack;
3920be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
3921be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
3922be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
39231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t lz = l->getCurrentState().z;
39241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rz = r->getCurrentState().z;
3925be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
3926be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
3927be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
3928be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
3929921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3930921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
39323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
39333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
39343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
39353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
39363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
39373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
39383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
39393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
39403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3941