SurfaceFlinger.cpp revision 0a688f5005b512b96d676a7fa6e23be9132a492c
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
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
2363f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h>
2486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h>
25b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h>
26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
27921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
37c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
3867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h>
39c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
44e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
45392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h>
46921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
50d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
51cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
550a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato#include <utils/Timers.h>
561c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
59ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
613e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
633e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6490ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
650f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
66faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
67d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
68d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
74a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
77ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
78ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
79875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
80ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
81875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
89fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
90ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
91ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event
95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer.  The software vsync
96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each
97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame.
98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application
100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window
101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed.  This value may be either positive (after the HW vsync)
102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync).  Setting it to 0 will result in a
103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger
104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync.  Setting it to a positive number will
105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being:
106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications
110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time.  When this happens
111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations
112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup.  Therefore, this latency should be tuned somewhat
113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made).
114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
115faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs.
1170a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
1180a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
12499b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
12599b49840d309727678b77403d6cc9f920111623fMathias Agopian
12699b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
12799b49840d309727678b77403d6cc9f920111623fMathias Agopian
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1294f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1312d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1322d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
133076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
13452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
135875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mRenderEngine(NULL),
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
138a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
1394b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1418afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14273d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
143a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1479795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
148ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
149ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        mForceFullDamage(false),
150faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
151948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
1529c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mDaltonize(false),
153b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasColorMatrix(false),
154b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff(false),
155b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mFrameBuckets(),
156b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime(0),
157b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mLastSwapTime(0)
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
159a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1638afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
164b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
16550210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
166b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1698afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1708afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1718afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1728afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
17363f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
17463f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
17563f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
17663f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1778afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
178c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
179c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
18399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
18499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
18599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
18699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
189a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
190a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
191a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
194c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
19799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
19913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
20099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
20199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
202a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
20399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
20499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
2057e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20796f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
20896f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
20996f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
21096f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
21196f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
216dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
217dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
231e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
2363ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
2378dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
238dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    info.isSecure = secure;
239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2576c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2586c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2596c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2606c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2616c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2626c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
266692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
267692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    DisplayDeviceState info(type);
268692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
269692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    info.isSecure = true;
270692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
271692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
272692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2749e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
275e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
276e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
277e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
278692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
279e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
280e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2819a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2829a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2839a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2849a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2859a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
286b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
291a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2923330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2961f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2971f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
298921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2991f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
3001f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
3011f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
302a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
303a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
304a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
3050a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato
3060a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
3070a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
3080a688f5005b512b96d676a7fa6e23be9132a492cYusuke Sato                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
315921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
318921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
319921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
321921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
322921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
323921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
325921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
326921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
327faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
328faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3295167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3305167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden        const char* label) :
3310a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3320a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3335167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            mVsyncOnLabel(String8::format("VsyncOn-%s", label)),
3345167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            mVsyncEventLabel(String8::format("VSYNC-%s", label)),
335db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mDispSync(dispSync),
336db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallbackMutex(),
337db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mCallback(),
338db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mVsyncMutex(),
339db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mPhaseOffset(phaseOffset),
340db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            mEnabled(false) {}
341faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
345db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3470a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            status_t err = mDispSync->addEventListener(mPhaseOffset,
348faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
349faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3535167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3615167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
363db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mEnabled = enable;
364faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
365faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
366faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
367db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mCallbackMutex);
368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
371db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    virtual void setPhaseOffset(nsecs_t phaseOffset) {
372db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        Mutex::Autolock lock(mVsyncMutex);
373db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
374db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Normalize phaseOffset to [0, period)
375db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        auto period = mDispSync->getPeriod();
376db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        phaseOffset %= period;
377db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (phaseOffset < 0) {
378db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // If we're here, then phaseOffset is in (-period, 0). After this
379db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            // operation, it will be in (0, period)
380db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            phaseOffset += period;
381db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
382db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        mPhaseOffset = phaseOffset;
383db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
384db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // If we're not enabled, we don't need to mess with the listeners
385db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (!mEnabled) {
386db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            return;
387db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
388db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
389db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Remove the listener with the old offset
390db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        status_t err = mDispSync->removeEventListener(
391db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
392db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
393db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error unregistering vsync callback: %s (%d)",
394db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
395db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
396db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
397db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        // Add a listener with the new offset
398db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        err = mDispSync->addEventListener(mPhaseOffset,
399db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                static_cast<DispSync::Callback*>(this));
400db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        if (err != NO_ERROR) {
401db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            ALOGE("error registering vsync callback: %s (%d)",
402db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                    strerror(-err), err);
403db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza        }
404db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    }
405db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
406faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
407faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
408faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
409faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
410db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            Mutex::Autolock lock(mCallbackMutex);
411faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
412a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
4130a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
4140a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
4155167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
4160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
417faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
418faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
419faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
420faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
421faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
422faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
423faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
424faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
425faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
4260a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
4275167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
4285167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
4290a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
430faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
431db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
432db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mCallbackMutex; // Protects the following
433faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
434db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
435db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex mVsyncMutex; // Protects the following
436db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    nsecs_t mPhaseOffset;
437db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    bool mEnabled;
438faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
439faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
440faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
441a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
442a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
443a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
444692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    Mutex::Autolock _l(mStateLock);
445692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
446b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // initialize EGL for the default display
44734a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
44834a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
449a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
450f9481058101c4e2b38c74048feac383664691d03Saurabh Shah    // start the EventThread
451f9481058101c4e2b38c74048feac383664691d03Saurabh Shah    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
452f9481058101c4e2b38c74048feac383664691d03Saurabh Shah            vsyncPhaseOffsetNs, true, "app");
453f9481058101c4e2b38c74048feac383664691d03Saurabh Shah    mEventThread = new EventThread(vsyncSrc);
454f9481058101c4e2b38c74048feac383664691d03Saurabh Shah    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
455f9481058101c4e2b38c74048feac383664691d03Saurabh Shah            sfVsyncPhaseOffsetNs, true, "sf");
456f9481058101c4e2b38c74048feac383664691d03Saurabh Shah    mSFEventThread = new EventThread(sfVsyncSrc);
457f9481058101c4e2b38c74048feac383664691d03Saurabh Shah    mEventQueue.setEventThread(mSFEventThread);
458f9481058101c4e2b38c74048feac383664691d03Saurabh Shah
459b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // Initialize the H/W composer object.  There may or may not be an
460b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // actual hardware composer underneath.
461b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    mHwc = new HWComposer(this,
462b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            *static_cast<HWComposer::EventHandler *>(this));
463b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
464875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // get a RenderEngine for the given display / config (can't fail)
46505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
466875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
467875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
468875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
469a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
470da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
471da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
472da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
473cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // initialize our non-virtual displays
4749e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
475f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
476f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        // set-up the displays that are already connected
4779e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
478dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            // All non-virtual displays are currently considered secure.
479dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            bool isSecure = true;
480692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked(type);
481692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            wp<IBinder> token = mBuiltinDisplays[i];
482692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
483b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<IGraphicBufferProducer> producer;
484b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<IGraphicBufferConsumer> consumer;
485b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            BufferQueue::createBufferQueue(&producer, &consumer,
486b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    new GraphicBufferAlloc());
487b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza
488b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
489b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    consumer);
49019e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall            int32_t hwcId = allocateHwcDisplayId(type);
491f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            sp<DisplayDevice> hw = new DisplayDevice(this,
49219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
493b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    fbs, producer,
49405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                    mRenderEngine->getEGLConfig());
495f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            if (i > DisplayDevice::DISPLAY_PRIMARY) {
496c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden                // FIXME: currently we don't get blank/unblank requests
497f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // for displays other than the main display, so we always
498f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // assume a connected display is unblanked.
49986efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann                ALOGD("marking display %zu as acquired/unblanked", i);
5002c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                hw->setPowerMode(HWC_POWER_MODE_NORMAL);
501f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            }
502f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            mDisplays.add(token, hw);
503f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        }
504e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
505cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
506a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // make the GLContext current so that we can create textures when creating Layers
507a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // (which may happens before we render something)
508a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
509a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
510d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
511d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
512d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
513faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    // set a fake vsync period if there is no HWComposer
514faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mHwc->initCheck() != NO_ERROR) {
515faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.setPeriod(16666667);
516faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
517faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
51892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
51992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
5208630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
52113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
52213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
52313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
524a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
525a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
5283ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
5299e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ?
5303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
5313ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
5323ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
533a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
534a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
535a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
536a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
537a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
538a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
539875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
540875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
541a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
542a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
543875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
544875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
545a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
546a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
548d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
549582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
5502adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
551134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
552097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
5536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
554134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
555134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
5577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
55823e16bb5dae277cd20a739ca56553ae931c43ccfTatenda Chipeperekwa    if ((configs == NULL) || (display.get() == NULL)) {
5597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
5607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
5617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5627aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed    if (!display.get())
5637aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed        return NAME_NOT_FOUND;
5647aa0c47e4205c6fca136c38f272d911c25c8a8faNaseer Ahmed
565692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
5669e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
567692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
5681604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
5691604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
5701604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5711604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
5721604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5731604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
5741604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
575c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5768b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5778b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5788b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5798b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5808b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5818b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5828b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5838b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5848b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5858b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5868b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5878b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5888b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5898b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5908b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5918b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5928b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5931604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5947f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
5957f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    const Vector<HWComposer::DisplayConfig>& hwConfigs =
5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            getHwComposer().getConfigs(type);
5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    for (size_t c = 0; c < hwConfigs.size(); ++c) {
5997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        const HWComposer::DisplayConfig& hwConfig = hwConfigs[c];
6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
6017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6027f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        float xdpi = hwConfig.xdpi;
6037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        float ydpi = hwConfig.ydpi;
6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
6067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
6077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
6097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
6107f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
6117f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
6127f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
6137f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6147f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
6157f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
6167f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
6177f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
6187f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
6197f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
6207f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6217f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
6227f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
6237f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
6247f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
6257f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
6267f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
6277f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
6287f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
6291604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
6307f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6317f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.w = hwConfig.width;
6327f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.h = hwConfig.height;
6337f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
6347f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
6357f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.fps = float(1e9 / hwConfig.refresh);
63691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
63791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden
63891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
63991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
64091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
64191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
64291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
64391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
64491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
64591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
64691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
64791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
64891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
64991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
65091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.presentationDeadline =
65191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden                hwConfig.refresh - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
6527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
6547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
6557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        configs->push_back(info);
6578b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6588b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
6607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
661dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
66289fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
66367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
66467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
66567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
66667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
66767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
66867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
66967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
67067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
67167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
67267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
67367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
67467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
6756c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
67624a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    sp<DisplayDevice> device(getDisplayDevice(display));
67724a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    if (device != NULL) {
67824a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza        return device->getActiveConfig();
67924a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    }
68024a42e9f54e971a17b829e85681c68d60a178d26Dan Stoza    return BAD_VALUE;
6817f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
682dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
6836c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
6846c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
6856c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
6866c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
6876c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
6886c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6896c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
6906c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
6916c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6926c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6936c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6946c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
6956c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
6966c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6976c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6986c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6996c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
7006c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
7016c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
7026c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
7036c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
7046c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
7056c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
7066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
7076c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
7086c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
7096c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
7106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
7116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
7126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
7137306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
7147306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
715784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
7169ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
7177306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
7187306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
7196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
7206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
7216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
7227306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
7236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
7246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
7256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
7266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
7276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
7286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
7296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
7306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
7316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
7326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
7336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
734888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
735c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
736c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
737d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
738d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
739d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
740d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
741d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
742d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
743d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
744d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
745d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
746d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
747d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
748d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
749d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
750d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
751d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
7528aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
753bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
754bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
75699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
75799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
75899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
75999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
76099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
76199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
76299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
76399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
76499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
76599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
76699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
76799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
76899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
76999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
77099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
77199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
77299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
77399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
774c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
77599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
77699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
77799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
77899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
779c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
78099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
78199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
78299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
78399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
78499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
78599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7874f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
7884f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
7894f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
7904f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
79199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
793faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
794faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
795948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
796faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
797d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
798d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
799faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
80043601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
801faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
802faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
803948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
804faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
805faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
806948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
807948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
808948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
809948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
810948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
811948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
812948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
813faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const nsecs_t period =
814faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
815faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
816faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
817faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
818faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
819faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
820faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
821d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
822d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
823faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
824faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
825faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
826faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
827948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
828faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
829faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
830d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
831d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
832faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
833faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
834faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
835948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
836948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
837948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
838faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
839faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
840faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
841d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
842faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
843d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
844d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
845d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
846d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
847faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
848148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
849d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
850d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
851d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
852d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
853d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
854d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
855148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
856148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
857148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) {
858148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    if (mEventThread == NULL) {
859148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // This is a temporary workaround for b/7145521.  A non-null pointer
860148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // does not mean EventThread has finished initializing, so this
861148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // is not a correct fix.
862148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        ALOGW("WARNING: EventThread not started, ignoring hotplug");
863148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        return;
864148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
8659e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
8669e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
8679e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
868692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
869692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked((DisplayDevice::DisplayType)type);
8709e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
871692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
872692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
8739e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
8749e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
8759e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
8769e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
8773ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
8788630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
8798630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
88081cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) {
881faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
88281cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian    getHwComposer().eventControl(disp, event, enabled);
8838630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
8848630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
8854fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
8861c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
88799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
8886b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::TRANSACTION: {
8896b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageTransaction();
8906b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
8916b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
8926b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::INVALIDATE: {
8936b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            bool refreshNeeded = handleMessageTransaction();
8946b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            refreshNeeded |= handleMessageInvalidate();
8955878444fb8da043021f30d3de739531f15390df5Dan Stoza            refreshNeeded |= mRepaintEverything;
8966b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (refreshNeeded) {
8975878444fb8da043021f30d3de739531f15390df5Dan Stoza                // Signal a refresh if a transaction modified the window state,
8985878444fb8da043021f30d3de739531f15390df5Dan Stoza                // a new buffer was latched, or if HWC has requested a full
8995878444fb8da043021f30d3de739531f15390df5Dan Stoza                // repaint
9006b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                signalRefresh();
9016b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
9026b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
9036b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
9046b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        case MessageQueue::REFRESH: {
9056b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            handleMessageRefresh();
9066b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            break;
9076b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
9084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
9094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9116b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageTransaction() {
912e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
9134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
91487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
9156b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        return true;
9164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
9176b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return false;
9184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
9206b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handleMessageInvalidate() {
921cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
9226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return handlePageFlip();
9234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
9243a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
9254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
926cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
927cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
928cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
929cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
930cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
931cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
932cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
933cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
934cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
935cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
936cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
937cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
938cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
939cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
940cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
941cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
942cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
943cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
9442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
945cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
946cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
947cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
948cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
949cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
950cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
951cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
952cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
9533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
9543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
9553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
956cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
957da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
958cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
959cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
960cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
961cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
962cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
963cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
964cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
965cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
966cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
967bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
968bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    HWComposer& hwc(getHwComposer());
969bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
970bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        status_t err = hwc.prepare();
971bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
972bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
973cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
974cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
975cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
976cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
977cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
9781eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
9791eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
980cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
9811eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        if (layers[i]->onPreComposition()) {
982cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
983cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
984cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
985cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
986cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
987cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
988cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
989a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
990cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
991cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
9921eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
9931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
994cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
9951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        layers[i]->onPostComposition();
996cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
9974b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
998faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const HWComposer& hwc = getHwComposer();
999faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
1000faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1001faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (presentFence->isValid()) {
1002faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (mPrimaryDispSync.addPresentFence(presentFence)) {
1003faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1004faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
1005948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
1006faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1007faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1008faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1009b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
10105167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
10112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1012faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
1013faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
1014faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
1015faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
10164b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
10174b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
10184b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
1019a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall        if (presentFence->isValid()) {
10204b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentFence(presentFence);
10214b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
10224b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
10234b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
10244b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
10254b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
10264b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
10274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
10284b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
1029b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1030b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
1031b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        return;
1032b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1033b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
1034b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    nsecs_t currentTime = systemTime();
1035b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    if (mHasPoweredOff) {
1036b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = false;
1037b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    } else {
1038b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t period = mPrimaryDispSync.getPeriod();
1039b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        nsecs_t elapsedTime = currentTime - mLastSwapTime;
1040b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        size_t numPeriods = static_cast<size_t>(elapsedTime / period);
1041b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        if (numPeriods < NUM_BUCKETS - 1) {
1042b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[numPeriods] += elapsedTime;
1043b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        } else {
1044b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
1045b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        }
1046b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mTotalTime += elapsedTime;
1047b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
1048b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    mLastSwapTime = currentTime;
1049cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
1050cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
1051cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
1052cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
105352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
1054cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
105587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
105687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
1057ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
10581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const LayerVector& layers(mDrawingState.layersSortedByZ);
105992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1060ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
1061ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
106213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            Vector< sp<Layer> > layersSortedByZ;
10634297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
10647e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
10657e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
10662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            if (hw->isDisplayOn()) {
10671eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                SurfaceFlinger::computeVisibleRegions(layers,
1068ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
10697e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
10701eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const size_t count = layers.size();
1071ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
10721eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const sp<Layer>& layer(layers[i]);
10731eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
1074ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
1075a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
1076a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
1077a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
1078a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
1079ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
1080ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
108187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
108287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
10833b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
10844297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
10857e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
10867e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
10877e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
10883b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
10893b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1090cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
10913b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
1092cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
1093028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1094b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1095b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1096b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1097b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1098b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1099b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1100b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1101b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1102b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1103b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1104b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1105b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1106b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1107b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1108b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1109b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1110b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1111b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1112b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1113b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1114b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
11157143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1116b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1117b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1118b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1119b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1120028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1121028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
112252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
112352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
112452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
1125a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        if (CC_UNLIKELY(mHwWorkListDirty)) {
1126a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            mHwWorkListDirty = false;
1127a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1128a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                sp<const DisplayDevice> hw(mDisplays[dpy]);
1129a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const int32_t id = hw->getHwcDisplayId();
1130a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                if (id >= 0) {
113113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const Vector< sp<Layer> >& currentLayers(
1132a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        hw->getVisibleLayersSortedByZ());
1133a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    const size_t count = currentLayers.size();
1134a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    if (hwc.createWorkList(id, count) == NO_ERROR) {
1135a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        HWComposer::LayerListIterator cur = hwc.begin(id);
1136a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        const HWComposer::LayerListIterator end = hwc.end(id);
1137a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
113813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            const sp<Layer>& layer(currentLayers[i]);
1139a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            layer->setGeometry(hw, *cur);
11409c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
1141a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                                cur->setSkip(true);
1142a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            }
1143a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1144a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1145a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                }
1146a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            }
1147a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        }
1148a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
1149a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        // set the per-frame data
115092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11514297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
1152e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
1153e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
115413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                const Vector< sp<Layer> >& currentLayers(
1155cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
1156e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
1157a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                HWComposer::LayerListIterator cur = hwc.begin(id);
1158a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const HWComposer::LayerListIterator end = hwc.end(id);
1159a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
1160a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    /*
1161a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * update the per-frame h/w composer data for each layer
1162a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * and build the transparent region of the FB
1163a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     */
116413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const sp<Layer>& layer(currentLayers[i]);
1165a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    layer->setPerFrameData(hw, *cur);
11661e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
116752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
116887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
1169a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
117003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        // If possible, attempt to use the cursor overlay on each display.
117103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
117203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            sp<const DisplayDevice> hw(mDisplays[dpy]);
117303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            const int32_t id = hw->getHwcDisplayId();
117403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            if (id >= 0) {
117503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const Vector< sp<Layer> >& currentLayers(
117603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    hw->getVisibleLayersSortedByZ());
117703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const size_t count = currentLayers.size();
117803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                HWComposer::LayerListIterator cur = hwc.begin(id);
117903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const HWComposer::LayerListIterator end = hwc.end(id);
118003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
118103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    const sp<Layer>& layer(currentLayers[i]);
118203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    if (layer->isPotentialCursor()) {
118303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                        cur->setIsCursorLayerHint();
118403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                        break;
118503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
118603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
118703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
118803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
118903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
119052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
119152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
119238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall
119338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
119438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            sp<const DisplayDevice> hw(mDisplays[dpy]);
119538efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            hw->prepareFrame(hwc);
119638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
119752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
1198cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
119952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1200cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1201cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
120252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
120392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
12044297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
12052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1206cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1207cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
120802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
120902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
121002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
121102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1212cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1213cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1214cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
121587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
121652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
12174297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
12184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
121952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1224841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1225b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1226a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1227a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1228c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
122952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
1230ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
12312a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        if (!hwc.supportsFramebufferTarget()) {
12322a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            // EGL spec says:
12332a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //   "surface must be bound to the calling thread's current context,
12342a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //    for the current rendering API."
1235875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
12362a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        }
1237e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
123852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
123952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
12406da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // make the default display current because the VirtualDisplayDevice code cannot
12416da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // deal with dequeueBuffer() being called outside of the composition loop; however
12426da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // the code below can call glFlush() which is allowed (and does in some case) call
12436da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // dequeueBuffer().
12446da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
12456da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian
124692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
12474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
124813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
1249da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        hw->onSwapBuffersCompleted(hwc);
125052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
1251e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
1252e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
12531e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
12541e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
125552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
1256d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
125752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1258cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
125952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
1260d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
126152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1262ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1263e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1264e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1265a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1266a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
12676547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
12686547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
12696547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
12706547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
12716547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
127487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1276841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1277841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
12787cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
12797cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
12807cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
12817cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
12827cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
12837cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1284ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1285ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1286ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1287ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1288ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1289ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1290ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1291ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1292ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1293ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1294e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
129587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1296ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1297ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1298ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1299ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1300ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
13013d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
130387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
13043d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
13053d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13133559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
131513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
1316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
13263559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1329e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
133092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
133192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
133292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1333e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1334e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
133592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
133792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
133893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
133992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
134092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
134192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
134292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
134392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
134492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1345e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1346e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
134792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
13483ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
134927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
135027ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
135127ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
135202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1353875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
135402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
135502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
135602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
13579e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
13587adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
135902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
136092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
136192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
136292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
136392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
136492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1365e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
13663ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1367097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
1368097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
13691474f8864faafebc92ff79959bb5c698bd29b704Dan Albert                    if (state_binder != draw_binder) {
1370e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
137193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
137293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
137393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
137402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
137502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
137602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
137793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
137893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
137993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
138093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
138193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
138292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
138393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1384db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
138593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
138693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
138793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
138893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
138900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
139000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
139100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
139200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
139300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
13944fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
139593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
139647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
139747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
139847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
139992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
140092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
140192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
140292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
140392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
140492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
140592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1406e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1407e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1408cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
140999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1410db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1411b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1412b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
1413b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
1414b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                            new GraphicBufferAlloc());
1415db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
141602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                    int32_t hwcDisplayId = -1;
141799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
141802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
141902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
142002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
142199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1422db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
14231f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int width = 0;
14241f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int status = state.surface->query(
14251f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    NATIVE_WINDOW_WIDTH, &width);
14261f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            ALOGE_IF(status != NO_ERROR,
14271f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    "Unable to query width (%d)", status);
14281f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int height = 0;
14291f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            status = state.surface->query(
14301f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    NATIVE_WINDOW_HEIGHT, &height);
14311f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            ALOGE_IF(status != NO_ERROR,
14321f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    "Unable to query height (%d)", status);
14331f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            if (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 ||
14341f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    (width <= MAX_VIRTUAL_DISPLAY_DIMENSION &&
14351f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                     height <= MAX_VIRTUAL_DISPLAY_DIMENSION)) {
14361f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                hwcDisplayId = allocateHwcDisplayId(state.type);
14371f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            }
14381f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza
1439db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
1440b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    *mHwc, hwcDisplayId, state.surface,
1441b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    bqProducer, bqConsumer, state.displayName);
1442db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1443db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
144447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
144599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
144699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1447cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1448cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1449cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1450cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
145102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        hwcDisplayId = allocateHwcDisplayId(state.type);
1452cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // for supported (by hwc) displays we provide our
1453cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // own rendering surface
1454b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        dispSurface = new FramebufferSurface(*mHwc, state.type,
1455b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                bqConsumer);
1456b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        producer = bqProducer;
1457cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1458cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1459cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
146099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1461cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
146219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                state.type, hwcDisplayId,
146319e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                mHwc->getFormat(hwcDisplayId), state.isSecure,
146405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                display, dispSurface, producer,
146505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1466cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1467cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
14684fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
14698dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1470cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
14711c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        if (state.isVirtualDisplay()) {
14721c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            if (hwcDisplayId >= 0) {
14731c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                mHwc->setVirtualDisplayProperties(hwcDisplayId,
14741c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getWidth(), hw->getHeight(),
14751c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getFormat());
14761c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            }
14771c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        } else {
14787adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
14791c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
148093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
148192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
148292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
14843559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
14878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
14888430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
14898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
14908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
14928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
14938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
14958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
14968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
14978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
14998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
15008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
15018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
15028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
15038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
15048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
15058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
15068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
15078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
15088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
15098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
15108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
15118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
151213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
15131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
15148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
15158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
15168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
15178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
15188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
15198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
15208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
15218430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
15228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
15238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
15248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
15258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
152691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
15278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
15288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
15298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
15308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
15318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
153291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
153391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
153491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
153591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
153691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
153791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
153891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
153991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
15408430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
154191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
15428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
15438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
15448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
15458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
15463559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
15473559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
15483559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
15511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
15523559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
15533559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
15543559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
15553559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
15563559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
15573559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
15583559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
15593559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
15603559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
15611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const size_t count = layers.size();
15623559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
15631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            const sp<Layer>& layer(layers[i]);
15643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
15653559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
15663559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
15673559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
15683559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
15691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
15701501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
15711501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
15721501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
15730aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
157803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
157903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
158003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
158103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
158203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
158303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
158403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    HWComposer& hwc(getHwComposer());
158503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
158603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        sp<const DisplayDevice> hw(mDisplays[dpy]);
158703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const int32_t id = hw->getHwcDisplayId();
158803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        if (id < 0) {
158903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
159003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
159103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const Vector< sp<Layer> >& currentLayers(
159203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            hw->getVisibleLayersSortedByZ());
159303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const size_t count = currentLayers.size();
159403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        HWComposer::LayerListIterator cur = hwc.begin(id);
159503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const HWComposer::LayerListIterator end = hwc.end(id);
159603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
159703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) {
159803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                continue;
159903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
160003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            const sp<Layer>& layer(currentLayers[i]);
160103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            Rect cursorPos = layer->getPosition(hw);
160203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            hwc.setCursorPositionAsync(id, cursorPos);
160303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            break;
160403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
160503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
16064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
16074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
16084fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
16094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
16104fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
16114fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
16124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
16134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
16144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
16154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
16164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
16174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
16184b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
16194b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
16204b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
16214b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
16224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
16232d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
16242d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
16254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
162987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
163087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1632841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1633841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
163887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
164213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer = currentLayers[i];
1643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
16451eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
164701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
164887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
164987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
165087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1652ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1653ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1656ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1657ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1658ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1659ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1660ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1661ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1663ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1664ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1665ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1666ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1667ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1669ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1670a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1671a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1672a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1673a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1674a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1675a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1676a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1677a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1678a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1679a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1680ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1681ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1682da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
16834125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
16845219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian            Rect bounds(s.transform.transform(layer->computeBounds()));
1685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1686ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1687ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1688ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
16894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
16904fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
16914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
16924fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
16932ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                            transparentRegion = tr.transform(s.activeTransparentRegion);
16944fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
16954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
16964fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
1697a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                            transparentRegion.clear();
16984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
16994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
17002ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        transparentRegion = s.activeTransparentRegion;
17014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1702ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1704ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
17054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1706ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1707ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1708ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1709ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1710ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1714ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1715ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1716ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1717ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1718ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1719ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
17284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1731a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1732ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1733ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1734ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1735ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1736ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1737ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1738ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1739ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1740ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1741ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1742a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1743ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
17444fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
17454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1746ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1747ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
175287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1754ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
17568b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1757a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1760a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1761a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
176487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
176787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
176887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
176992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
17704297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
17714297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
17724297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
177392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
177492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
177587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
177687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
17776b9454d1fee0347711af1746642aa7820b1ea04dDan Stozabool SurfaceFlinger::handlePageFlip()
1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
178099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
17814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
17821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
17836b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    bool frameQueued = false;
178451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
178551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
178651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
178751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
178851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
178951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
179051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
179151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
179251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
179351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
179451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    Vector<Layer*> layersWithQueuedFrames;
179551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layers.size(); i<count ; i++) {
17961eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const sp<Layer>& layer(layers[i]);
17976b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        if (layer->hasQueuedFrame()) {
17986b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            frameQueued = true;
17996b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            if (layer->shouldPresentNow(mPrimaryDispSync)) {
18006b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza                layersWithQueuedFrames.push_back(layer.get());
1801ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            } else {
1802ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                layer->useEmptyDamage();
18036b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza            }
1804ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        } else {
1805ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            layer->useEmptyDamage();
18066b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        }
180751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    }
180851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
180951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner        Layer* layer = layersWithQueuedFrames[i];
181087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
1811ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza        layer->useSurfaceDamage();
18121eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
181387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
18144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
18154da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
18163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
18176b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
18186b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // If we will need to wake up at some time in the future to deal with a
18196b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // queued frame that shouldn't be displayed during this vsync period, wake
18206b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // up during the next vsync period to check again.
18216b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    if (frameQueued && layersWithQueuedFrames.empty()) {
18226b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza        signalLayerUpdate();
18236b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    }
18246b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza
18256b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    // Only continue with the refresh if there is actually new work to do
18266b9454d1fee0347711af1746642aa7820b1ea04dDan Stoza    return !layersWithQueuedFrames.empty();
1827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1829ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1830ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1831ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1832ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1833ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
183499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1835cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
183687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18387143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
18397143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
18407143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
18417143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
18427143316af216fa92c31a60d4407b707637382da1Dan Stoza    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
18437143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
18447143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
18457143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
18467143316af216fa92c31a60d4407b707637382da1Dan Stoza
184787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
184887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1849b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
18504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
18530f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
185429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
185529d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
185629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
18574297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
18590f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
186029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1861df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
186295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
18630f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
18644297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
186629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
18674297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
18684297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
18733f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine        if (!doComposeSurfaces(hw, dirtyRegion)) return;
1874ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    } else {
1875ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        RenderEngine& engine(getRenderEngine());
18769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mat4 colorMatrix = mColorMatrix;
18779c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        if (mDaltonize) {
18789c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            colorMatrix = colorMatrix * mDaltonizer();
18799c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        }
1880f008799d3753e52c10849824ff8146985ea66284Dan Stoza        mat4 oldMatrix = engine.setupColorTransform(colorMatrix);
1881ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        doComposeSurfaces(hw, dirtyRegion);
1882f008799d3753e52c10849824ff8146985ea66284Dan Stoza        engine.setupColorTransform(oldMatrix);
1883ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    }
1884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18859c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
18864297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1887da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1888da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
1889da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
1890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18923f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentinebool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
18943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
189585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
18968630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
18971e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
18981e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1899a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1900d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall    bool hasGlesComposition = hwc.hasGlesComposition(id);
190185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1902875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
1903c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
1904c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock                  hw->getDisplayName().string());
19053f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
19063f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
19073f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
19083f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
19093f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
1910c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
1911a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1912a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
191385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1914e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1915b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1916b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1917b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
19183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
1919b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
19203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.clearWithColor(0, 0, 0, 0);
1921b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1922766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
1923766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region bounds(hw->getBounds());
1924766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1925766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
1926766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
1927766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
1928766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region letterbox(bounds.subtract(hw->getScissor()));
1929766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1930766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
1931766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            Region region(hw->undefinedRegion.merge(letterbox));
1932766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1933766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
1934766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
1935766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1936b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
193787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1938b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
193955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1940b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1941a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
1942f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1943766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
1944766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
1945f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
1946f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
1947f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            const Rect& bounds(hw->getBounds());
1948766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Rect& scissor(hw->getScissor());
1949f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
1950f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
1951f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
1952f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
19533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1954f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
19553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                const uint32_t height = hw->getHeight();
19563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.setScissor(scissor.left, height - scissor.bottom,
19573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
1958f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
1959f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
196085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
19614b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
196285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
196385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
196485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
19654b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
196613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
196785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
196885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
196985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
197085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
197185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
197213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
19734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
197485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
197585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
197603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    case HWC_CURSOR_OVERLAY:
197785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
1978ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
197985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
198085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
19814125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                                && layer->isOpaque(state) && (state.alpha == 0xFF)
198285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1983cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1984cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1985cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1986cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
198785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
198885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
198985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1990cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
199185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1992a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1993da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    case HWC_FRAMEBUFFER_TARGET: {
1994da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // this should not happen as the iterator shouldn't
1995da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // let us get there.
199686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i);
1997da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
1998da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    }
1999cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
2000a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
200185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
200285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
200385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
200485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
200585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
200613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
200785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
200885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
200985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
201085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
201185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
20124b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
20134b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
2014f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
2015f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
20163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableScissor();
20173f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
2018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
202155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
20223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
20233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
2024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20267d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stozastatus_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
2027ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
20286710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
202913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
20301b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
20317d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    // add this layer to the current state list
20327d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    {
20337d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        Mutex::Autolock _l(mStateLock);
20347d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {
20357d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza            return NO_MEMORY;
20367d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        }
20377d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mCurrentState.layersSortedByZ.add(lbc);
20387d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
20397d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
20407d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
204196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
2042ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
20434f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
20447d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    return NO_ERROR;
204596f0819f81293076e652792794a961543e6750d7Mathias Agopian}
204696f0819f81293076e652792794a961543e6750d7Mathias Agopian
20473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
204896f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
204913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
2050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
20516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        mLayersPendingRemoval.push(layer);
2052076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
20536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        setTransactionFlags(eTransactionNeeded);
2054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
2055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
20563d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
2057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2059c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
2060dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
2061dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
2062dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
20633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
2064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
2065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
207099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
2071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
2073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20758b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
20768b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
20778b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
20788b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
20798b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
20807c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
2081698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
208228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
2083e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
20842d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
20852d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
20862d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
20872d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
20887c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
20892d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
20902d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
20917c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
20927c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
20937c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
20942d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
20952d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
20962d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
20972d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
20982d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
20992d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
2100e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
2101e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2102e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
2103e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
2104b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
2105b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
2106e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
2107698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2108698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
2109d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
2110d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
2111d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
2112d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
2113d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
2114d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
2115d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
2116d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
2117097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            sp<IBinder> binder = IInterface::asBinder(s.client);
2118d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
2119d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
2120d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
2121d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2122d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2123d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2124d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2125d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2126698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2127386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
212828378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2129386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
213028378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2131698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2132386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2133386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2134386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
21352d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
21362d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
21372d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
21382d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2139386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
21402d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2141386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2142386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2143386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2144386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
21452d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
21462d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2147386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2148386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2149cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2153e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2154e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
21559a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
21569a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
21579a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
21589a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2159e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
21609a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
21613ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2162e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2163e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2164097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
2165e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2166e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2169e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2170e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2172e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2173e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2174e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
217500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2176e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2177e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2178e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2179e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2180e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2181e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2182e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2183e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2184e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2185e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2186e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2187e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2188e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
218947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
219047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
219147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
219247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
219347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
219447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
219547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
219647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
219747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
219847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2199e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2200e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2201e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2202e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2203e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2205e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2206e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2207e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
220813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2209e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2210e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2211e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
2212e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
2213e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2214e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2215e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2216e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
2218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
2219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2230e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2231e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
2232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
2233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2240e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2242e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2243231160866738f6ed2175701f300fed1a8e8e02b0Dan Stoza        if (what & layer_state_t::eFlagsChanged) {
2244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2245e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2246e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2247e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
2248e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
2249e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2250e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2251e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2252e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2253e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
2254e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
2255e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2256e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2257e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2258e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2259e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2260e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2261e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2262e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2263e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2264e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2265e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
22664d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
22670ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
22680ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
22694d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
22704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
2271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
22724d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
22736e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2274921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
22756e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
22764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
22776e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
22788b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
22794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
22804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
22814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
22824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
22833165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
22843165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
22854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
22864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
22874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
22893165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
22904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
22914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
22924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
22934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
22944d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
22954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22997d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
23007d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
2301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
23027d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
23037d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    result = addClientLayer(client, *handle, *gbp, layer);
23047d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    if (result != NO_ERROR) {
23057d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza        return result;
23067d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    }
23077d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza
23087d89d06a6fe1bfadfe277f19dbb7e4aa021444e0Dan Stoza    setTransactionFlags(eTransactionNeeded);
23094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
23134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
23144d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
231792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
23238f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
23284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
23294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
23304d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2331b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
23334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
23344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
23354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
23394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
23404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
23424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
23434d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2344b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
23454d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2346118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2347118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2348ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
23499a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
23506710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
23516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
23526710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
23536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
23546710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
23556710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
23566710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
23579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
23589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
23599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
23609a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
236113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
23636710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
23646710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
2365ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
236613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> l(layer.promote());
2367ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
23686710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
2369e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
2370ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
2371ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
2372ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
2373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2375b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2376b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
237713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
237801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
237913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
238013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
238113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
238201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
238301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2384692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
238501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
238613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
23874c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
23884c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
238947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
239047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
239113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
239213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
23932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
23946547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
23956547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const nsecs_t period =
23966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
23976547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
239813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
239913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
240013a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
240113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
240213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
240313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
240413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
240513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
240613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
240713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
240813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
240913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
241013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
241113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
241213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
241313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
24142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
24152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
24162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
24172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
24182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
24192c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
242013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
24212c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
24222c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2423c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2424c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2425c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
24262c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
24272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
24282c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
24292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
24302c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2431c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
24322c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
24332c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2434c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2435c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2436c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2437948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2438c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24402c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
2441b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        mHasPoweredOff = true;
24422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
24432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2444c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2445948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2446948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2447cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2448cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2449cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2450c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
24512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
24522c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
24532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
24542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
24552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2456b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
24602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2461db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2462db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
24632c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2464b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
24652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
24662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
24672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2468b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
24692c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2470db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
24712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
24727306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
24739e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
24742c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
24752c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2476db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
24772c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2478db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2479b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2480b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2481b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
24822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2483db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2484b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2485b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2486b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2487b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
249199b49840d309727678b77403d6cc9f920111623fMathias Agopian
2492bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2493bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2494bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2495bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2496bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
249774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2498bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
2500fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        // Try to get the main lock, but give up after one second
25019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
25029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
2503fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        status_t err = mStateLock.timedLock(s2ns(1));
2504fcd15b478c20f579388bb1368f05098dca534639Jesse Hall        bool locked = (err == NO_ERROR);
25059795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
2506fcd15b478c20f579388bb1368f05098dca534639Jesse Hall            result.appendFormat(
2507fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
2508fcd15b478c20f579388bb1368f05098dca534639Jesse Hall                    "dumping anyways (no locks held)\n", strerror(-err), err);
25099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
25109795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
251182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
251282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
251325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
251425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
251525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
251625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
251725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
251874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
251935aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
252025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
252125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
252225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
252325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
252482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
252574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
252635aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
252782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
252825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
252925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
253025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
253125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
253274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
253335aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
253425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2535c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2536c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2537c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2538c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2539c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2540c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2541c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2542b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
2543b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            if ((index < numArgs) &&
2544b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                    (args[index] == String16("--static-screen"))) {
2545b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                index++;
2546b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpStaticScreenStats(result);
2547b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                dumpAll = false;
2548b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            }
2549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
25501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
255182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
255274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
255382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
255448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
255582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
255682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
255748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
255882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
255982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
256082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
256182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
256248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2563c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2564c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
256525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
256625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
256725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
256825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
256913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
257074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
257125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
257225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
257325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
257482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
257574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
257682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
257782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
257882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
257982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
258082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
258182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
258248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
25834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    const nsecs_t period =
25844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
258586efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
25864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
25874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2588d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
25894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
25904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
25914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const size_t count = currentLayers.size();
25924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        for (size_t i=0 ; i<count ; i++) {
259313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
25944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2595d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
25964b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
259782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
259882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
259982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2600ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
260125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2602c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
260325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
260425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
260525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
260625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
260725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
260825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
260925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
261025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
261125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
261225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
261313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
261425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2615d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
261625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
261725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
26184b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2619d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
262025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
262125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
26226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
26236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
26246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
26256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
26266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const size_t count = drawingLayers.size();
26276547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
26286547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        const sp<Layer>& layer(drawingLayers[i]);
26296547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
26306547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
26316547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
26326547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
26336547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
26346547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
26354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
26364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
26374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
26384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
26394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
26404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
26414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
26424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
26434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
26444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
26454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
26464803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
26474803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
26484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
26494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
26504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
26514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
2652b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stozavoid SurfaceFlinger::dumpStaticScreenStats(String8& result) const
2653b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza{
2654b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("Static screen stats:\n");
2655b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
2656b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float bucketTimeSec = mFrameBuckets[b] / 1e9;
2657b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        float percent = 100.0f *
2658b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
2659b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
2660b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza                b + 1, bucketTimeSec, percent);
2661b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    }
2662b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
2663b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    float percent = 100.0f *
2664b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
2665b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
2666b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza            NUM_BUCKETS - 1, bucketTimeSec, percent);
2667b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza}
2668b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
266974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
267074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
267182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
26723e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
26733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
26743e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
26753e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
26763e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
26773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
26783e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
26793e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
26803e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
268182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
268282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
268382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
268482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
268582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
268682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2687bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
268882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
26894803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
26904803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
26913e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
26923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
26934803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
26943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
26954803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
26964803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
26974803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
26984803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
26994803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
27003e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
2701ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
27023e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
2703ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
2704ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
2705ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
270641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
270741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
270841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
270924cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
271024cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
271141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS,
271241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY));
271341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
271441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
2715b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    // Dump static screen stats
2716b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
2717b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    dumpStaticScreenStats(result);
2718b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza    result.append("\n");
2719b90cf07f8b3a8fe76e40b997924c2509d04575f4Dan Stoza
27204803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
272182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
272282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
272382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
272482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
27253e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
272686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Visible layers (count = %zu)\n", count);
27273e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
272882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
272913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
27303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
273182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2732bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
273382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
27345f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
27355f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
27365f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
27373e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
273886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
27393e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
27405f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
27415f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
274274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
27435f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
27445f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
27455f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
274682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
274782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
27481b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
27493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
275074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
27513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
27521b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2753888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
27544297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
2755ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
27563e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
27573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
27583e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
27593e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
27603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
2761ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
2762ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
2763875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
27649795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
27654297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
27662c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
27672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
276874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
276982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
277082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2771c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
277282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
277382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
2774ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
2775ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
2776ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
277782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
277882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2779c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2780b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2781b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2782ed985574148a938bc3af24442eead313cc62521cMathias Agopian            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
2783ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
278482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
278574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
278682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
278782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
278874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
278982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
279082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
279182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
279282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
279382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
279474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
279582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
279682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
279782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
279882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
27993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
280074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
28013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
280274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  h/w composer %s and %s\n",
280382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
28049c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    (mDebugDisableHWC || mDebugRegion || mDaltonize
28059c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            || mHasColorMatrix) ? "disabled" : "enabled");
280674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
280782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
280882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
280982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
281082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
281182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
281282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
2813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
281513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
281648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
2817db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
281848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
281948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
282048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
282148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
282248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
282348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
282448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
282548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
282648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
282748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
282848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
282948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
283048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
2831cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
2832cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
283363f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
283463f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
283563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
283663f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
283763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
283863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
283963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
284063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
284163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
284224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
284363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
284463f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
284563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
284663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
284763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
284863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
284963f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
285063f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2856041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
2857698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
2859d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
2860d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
28612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
2862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2866a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
28673bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
286899b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2869e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2870375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2871375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
28731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
28741b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
28751b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
28761b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
28771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
28781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
28791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
28801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
288199b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
288299b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2883e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
28841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
28851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
28861b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
28871b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
28901b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2893b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
289499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2895375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2896375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2897375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2898e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2899375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
290401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
290535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
291053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
291153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
291453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2915cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2916cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2917cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2918e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2919e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2920e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2921e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2922cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
29244d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
29254d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
29264d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
29274d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
292853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
292953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
293053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
293153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
293253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
293353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2934a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2935a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2936a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2937a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2938a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2939a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
294101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2944b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
294512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
29494297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
29504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2951ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
2952ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
2953ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
2954ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
2955ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
2956ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
2957ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 1: mDaltonizer.setType(Daltonizer::protanomaly);   break;
2958ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break;
2959ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 3: mDaltonizer.setType(Daltonizer::tritanomaly);   break;
2960ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2961ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
2962ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::correction);
2963ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
2964ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::simulation);
2965ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2966ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                mDaltonize = n > 0;
2967ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
2968ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
29699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
29709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
29719c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
29729c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
29739c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
29749c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                mHasColorMatrix = n ? 1 : 0;
29759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
29769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
29779c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
29789c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
2979794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
2980794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      for (size_t j = 0; j < 4; j++) {
2981794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                          mColorMatrix[i][j] = data.readFloat();
2982794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      }
29839c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
29849c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
29859c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
29869c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
29879c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
29889c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
29899c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
2990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2991f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
2992f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
2993f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
2994645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
2995645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
2996f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
2997f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
2998ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            case 1017: {
2999ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                n = data.readInt32();
3000ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                mForceFullDamage = static_cast<bool>(n);
3001ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza                return NO_ERROR;
3002ee44edd0acccbf5eaa918d75737c3b65ee04fff7Dan Stoza            }
3003db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1018: { // Modify Choreographer's phase offset
3004db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3005db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3006db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3007db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3008db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            case 1019: { // Modify SurfaceFlinger's phase offset
3009db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                n = data.readInt32();
3010db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
3011db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza                return NO_ERROR;
3012db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza            }
3013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
3014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
3016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
3017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
301853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
301987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
302099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
302153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
302253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
302359119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
30242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
30252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
302659119e658a12279e8fff508f8773843de2d90917Mathias Agopian
30272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
30282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
30292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
3030b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
3031b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
3032b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
3033b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
30342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
30352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
3036b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
3037b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
3038b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
3039b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3040b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
3041b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
3042b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
3043b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
3044b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
3045b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
3046b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
3047b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
3048b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
3049b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
30502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
30512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
30522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
30532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
30542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
3055b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
30562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
30572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
30582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
30592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
30602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
30612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
30622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
30632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
30642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
30652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3066b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
3067b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
3068b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
30692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
30702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
3071c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
30722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
30732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
30742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
30752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
3076b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
3077b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
3078b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
3079b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
30802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
30812ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
30822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
3083b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
3084b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
3085b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
30862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
30872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
30882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
3089c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
30902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
30912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
30922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
3093b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
30942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
30952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
30962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
3097b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
3098b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
3099b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
3100b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
3101097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
31022ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
3103b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
31042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
31052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
31062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
31072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
31082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
3109b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
3110b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
3111b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
3112b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
3113b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitRequested(false)
3114b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
3115b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
3116b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
31172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
31182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
31192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
31202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
31212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
31222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
31232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
3124b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
31252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
3126aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
31272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
3128b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
3129b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
3130b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
31312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
31322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
31332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
31342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
31352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
31362a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
31372a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3138c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3139c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3140c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
31412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
31422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
31432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
31442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
31452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
31462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
31472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
31485ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
31495ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
31505ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
3151097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen    if (!IInterface::asBinder(producer)->localBinder()) {
31525ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        Mutex::Autolock _l(mStateLock);
31535ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        sp<const DisplayDevice> hw(getDisplayDevice(display));
31545ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        if (hw->getSecureLayerVisible()) {
31555ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            ALOGW("FB is protected: PERMISSION_DENIED");
31565ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            return PERMISSION_DENIED;
31575ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        }
31585ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    }
31595ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
3160c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
3161c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
3162c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
3163c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
3164c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3165c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3166c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
3167c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
3168c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3169c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
3170c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
3171c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3172c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
3173c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
3174c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3175c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
3176c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3177c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
3178c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3179c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
3180c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
31812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
31822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
31832a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
31842a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
3185c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
31862a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
31872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
3188c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
3189c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
31902a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
31912a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
31922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
31932a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
31942a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
3195c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3196c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                uint32_t minLayerZ, uint32_t maxLayerZ,
3197c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                bool useIdentityTransform, Transform::orientation_flags rotation)
31982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
3199c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
32002a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
3201c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
3202c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews              rotation(rotation),
32032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              result(PERMISSION_DENIED)
32042a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
32052a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
32062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
32072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
32082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
32092a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
32102a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
32112a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
3212c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
3213c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3214c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                    useIdentityTransform, rotation);
3215097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
32162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
32172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
32182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
32192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
32209eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // make sure to process transactions before screenshots -- a transaction
32219eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // might already be pending but scheduled for VSYNC; this guarantees we
32229eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // will handle it before the screenshot. When VSYNC finally arrives
32239eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // the scheduled transaction will be a no-op. If no transactions are
32249eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // scheduled at this time, this will end-up being a no-op as well.
32259eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    mEventQueue.invalidateTransactionNow();
32269eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
32272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
32282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
32292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
32302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
32312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
32322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
32332ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
32342a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
32352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
3236c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3237c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            useIdentityTransform, rotationFlags);
32382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
32392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
32402a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
32412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
32422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
32432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
3244118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3245118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3246180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3247180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3248180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3249c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3250180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ,
3251c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
3252180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3253180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
32543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3255180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3256180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
325789fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_w = hw->getWidth();
325889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const int32_t hw_h = hw->getHeight();
325989fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
32600e7497957a029fd123b429388d84bba2930fddefChristopher Ferris                           static_cast<int32_t>(reqHeight) != hw_h;
3261180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3262c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3263c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3264c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3265c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3266c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3267c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3268c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3269c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3270c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3271c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3272c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3273be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
3274be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3275c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3276c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3277c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3278c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3279be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
3280be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3281c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3282c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3283180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
32843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3285180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3286180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3287c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
3288c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
32893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3290180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3291180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
32923f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3293180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3294180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const LayerVector& layers( mDrawingState.layersSortedByZ );
3295180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const size_t count = layers.size();
3296180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
3297180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<Layer>& layer(layers[i]);
32981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
3299180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
3300180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
3301180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
3302180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
3303c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    layer->draw(hw, useIdentityTransform);
3304180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
3305180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
3306180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
3307180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
3308180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3309180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3310180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // compositionComplete is needed for older driver
3311180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    hw->compositionComplete();
3312931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
3313180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
3314180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3315180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
33162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
33172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
33182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3319c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3320c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3321c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, Transform::orientation_flags rotation)
332274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
3323fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
3324fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
3325180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
33263502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_w = hw->getWidth();
33273502416204d9dbd905012ee586d8bd145323809fDan Stoza    uint32_t hw_h = hw->getHeight();
33283502416204d9dbd905012ee586d8bd145323809fDan Stoza
33293502416204d9dbd905012ee586d8bd145323809fDan Stoza    if (rotation & Transform::ROT_90) {
33303502416204d9dbd905012ee586d8bd145323809fDan Stoza        std::swap(hw_w, hw_h);
33313502416204d9dbd905012ee586d8bd145323809fDan Stoza    }
3332180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3333180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
3334180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
3335180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
3336180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
3337180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3338180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3339180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
3340180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
3341180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
33420aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
33430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
334483cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
33450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
334674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
33475a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
33485a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine    if (result == NO_ERROR) {
33493ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
33503ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
33512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
33520aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
33530aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
33544ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
33550aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
33560aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
33572a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
33580aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
33590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
33600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
33610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
33620aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
33630aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
33640aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
3365866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
33660aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
33670aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
33680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
33690aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
33700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
33713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
33723f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
33733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
33743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
33750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
33760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
33770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
33780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3379c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
3380c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
3381c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
3382d555684cb36dfb959694db76962e570184f98838Mathias Agopian
3383866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
3384866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
3385866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
3386866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
3387866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
3388866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
33899707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
33909707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
3391866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3392866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
3393866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
33942d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
3395866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
3396866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
3397866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
3398866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
3399866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
3400866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
34012d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
3402866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3403866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
3404866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
3405866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
3406866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
3407866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
3408866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
3409866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
3410866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
3411866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
3412866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
3413866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
3414866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
3415866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
34162d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
3417866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
34182d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
34192d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
3420d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3421d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3422d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3423d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3424d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3425d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3426d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3427d555684cb36dfb959694db76962e570184f98838Mathias Agopian
34280aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
34290aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
34300aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
34310aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
34320aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
34330aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
34340aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
34350aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
343674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
3437afe2b1fadd29149ceed639357e44e06e97c3a5caJesse Hall                // queueBuffer takes ownership of syncFd
34385a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentine                result = window->queueBuffer(window, buffer, syncFd);
343974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
34400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
34410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
344274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
34430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
344474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
344574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
344674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
344774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
344874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3449d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3450d555684cb36dfb959694db76962e570184f98838Mathias Agopian        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
3451fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3452d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3453d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3454d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3455fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3456fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3457fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3458fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3459fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3460fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
3461fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const LayerVector& layers( mDrawingState.layersSortedByZ );
3462fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const size_t count = layers.size();
3463fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
3464fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const sp<Layer>& layer(layers[i]);
3465fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
3466fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
3467fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
3468fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
346986efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x",
3470fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
3471fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            i, layer->getName().string(), state.layerStack, state.z,
3472fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
3473fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3474fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3475fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian}
3476fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
34771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
34781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3479921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
3480921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3481921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3482921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
348313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : SortedVector<sp<Layer> >(rhs) {
3484921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3485921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3486921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
3487921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
3488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3489be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
349013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
349113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
3492be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
34931eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t ls = l->getCurrentState().layerStack;
34941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rs = r->getCurrentState().layerStack;
3495be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
3496be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
3497be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
34981eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t lz = l->getCurrentState().z;
34991eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rz = r->getCurrentState().z;
3500be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
3501be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
3502be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
3503be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
3504921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3505921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3506921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
3507921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
35083ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
350947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    : type(DisplayDevice::DISPLAY_ID_INVALID), width(0), height(0) {
3510e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
3511e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
35123ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
351347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0), width(0), height(0) {
3514da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
3515da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
3516b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
35177303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3518b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
351996f0819f81293076e652792794a961543e6750d7Mathias Agopian
3520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
35213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
35223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
35233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
35243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
35253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
35263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
35273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
35283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
35293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3530