SurfaceFlinger.cpp revision 866399093f9f60e7305f291e688abb456bace710
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>
38c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
39921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
401a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
421a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
43e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
44392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h>
45921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
46921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
49d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
50cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
541c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
57ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
593e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
613e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
630f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
64faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
65d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
66d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
72a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
75ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
76ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
77875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
78ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
79875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
82fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
83fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
88ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
89ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
91faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
92faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event
93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer.  The software vsync
94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each
95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame.
96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application
98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window
99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed.  This value may be either positive (after the HW vsync)
100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync).  Setting it to 0 will result in a
101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger
102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync.  Setting it to a positive number will
103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being:
104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications
108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time.  When this happens
109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations
110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup.  Therefore, this latency should be tuned somewhat
111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made).
112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1140a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs.
1150a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
1160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11999b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
12099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
12199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
12399b49840d309727678b77403d6cc9f920111623fMathias Agopian
12499b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
12599b49840d309727678b77403d6cc9f920111623fMathias Agopian
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1274f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1292d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1302d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
131076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
13252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
133875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mRenderEngine(NULL),
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
136a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
1374b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1398afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14073d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
141a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1429795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
146ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
147faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
148948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
1499c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mDaltonize(false),
1509c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mHasColorMatrix(false)
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
152a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1568afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
157b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
15850210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
159b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1628afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1638afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1648afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1658afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
16663f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
16763f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
16863f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
16963f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1708afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
171c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
172c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
17699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
17799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
17899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
17999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
182a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
183a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
184a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
18899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
18999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
19099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
19213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
19399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
195a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
19699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
19799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1987e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20096f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
20196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
20296f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
20396f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
20496f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
209dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
210dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
211e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
212e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
213e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
214e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
215e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
216e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
2293ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
2308dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
231dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    info.isSecure = secure;
232e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2376c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2386c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2396c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2406c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2416c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2426c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2436c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
256692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
257692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
258692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
259692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
260692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    DisplayDeviceState info(type);
261692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
262692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    info.isSecure = true;
263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
266e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2679e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
268e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
269e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
270e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
271692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
272e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2749a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
279b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
284a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2853330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2861f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
291921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2921f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
295a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
296a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
297a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
301921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
304921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
307921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
308921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
310921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
311921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
315921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
316faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
317faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3185167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3195167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden        const char* label) :
3200a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3210a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mPhaseOffset(phaseOffset),
3220a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3235167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            mVsyncOnLabel(String8::format("VsyncOn-%s", label)),
3245167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            mVsyncEventLabel(String8::format("VSYNC-%s", label)),
3250a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mDispSync(dispSync) {}
326faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
327faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
328faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
329faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
330faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        // Do NOT lock the mutex here so as to avoid any mutex ordering issues
331faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        // with locking it in the onDispSyncEvent callback.
332faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3330a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            status_t err = mDispSync->addEventListener(mPhaseOffset,
334faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
335faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
336faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
338faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3395167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
340faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
341faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
345faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3475167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
348faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
349faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        Mutex::Autolock lock(mMutex);
353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            Mutex::Autolock lock(mMutex);
361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
362a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3630a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
3640a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
3655167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
3660a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
367faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
3760a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const nsecs_t mPhaseOffset;
3770a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
3785167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
3795167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
3800a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
381faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex mMutex;
384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
387a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
390b65f32ebe2c86869b07ac1c986660dfb2187b7d3Jesse Hall    status_t err;
391692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    Mutex::Autolock _l(mStateLock);
392692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
393b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // initialize EGL for the default display
39434a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
39534a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
396a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
397b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // Initialize the H/W composer object.  There may or may not be an
398b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // actual hardware composer underneath.
399b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    mHwc = new HWComposer(this,
400b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            *static_cast<HWComposer::EventHandler *>(this));
401b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
402875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // get a RenderEngine for the given display / config (can't fail)
40305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
404875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
405875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
406875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
407a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
408da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
409da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
410da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
411cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // initialize our non-virtual displays
4129e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
413f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
414f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        // set-up the displays that are already connected
4159e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
416dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            // All non-virtual displays are currently considered secure.
417dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            bool isSecure = true;
418692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked(type);
419692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            wp<IBinder> token = mBuiltinDisplays[i];
420692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
421b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<IGraphicBufferProducer> producer;
422b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<IGraphicBufferConsumer> consumer;
423b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            BufferQueue::createBufferQueue(&producer, &consumer,
424b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    new GraphicBufferAlloc());
425b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza
426b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
427b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    consumer);
42819e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall            int32_t hwcId = allocateHwcDisplayId(type);
429f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            sp<DisplayDevice> hw = new DisplayDevice(this,
43019e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
431b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    fbs, producer,
43205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                    mRenderEngine->getEGLConfig());
433f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            if (i > DisplayDevice::DISPLAY_PRIMARY) {
434c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden                // FIXME: currently we don't get blank/unblank requests
435f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // for displays other than the main display, so we always
436f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // assume a connected display is unblanked.
43786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann                ALOGD("marking display %zu as acquired/unblanked", i);
4382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                hw->setPowerMode(HWC_POWER_MODE_NORMAL);
439f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            }
440f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            mDisplays.add(token, hw);
441f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        }
442e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
443cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
444a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // make the GLContext current so that we can create textures when creating Layers
445a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // (which may happens before we render something)
446a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
447a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
448028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
4490a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4505167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            vsyncPhaseOffsetNs, true, "app");
451faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mEventThread = new EventThread(vsyncSrc);
4520a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4535167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            sfVsyncPhaseOffsetNs, true, "sf");
4540a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    mSFEventThread = new EventThread(sfVsyncSrc);
4550a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    mEventQueue.setEventThread(mSFEventThread);
456028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
457d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
458d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
459d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
460faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    // set a fake vsync period if there is no HWComposer
461faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mHwc->initCheck() != NO_ERROR) {
462faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.setPeriod(16666667);
463faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
464faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
46592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
46692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4678630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
46813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
46913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
47013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
471a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
472a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4753ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
4769e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ?
4773ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
4783ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
4793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
480a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
481a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
482a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
483a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
484a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
485a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
486875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
487875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
488a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
489a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
490875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
491875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
492a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
493a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
495d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
496582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
4972adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
498134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
4992adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder());
5006710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
501134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
502134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
5047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
5057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    if (configs == NULL) {
5067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
5077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
5087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
509692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
5109e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
511692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
5121604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
5131604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
5141604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5151604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
5161604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5171604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
5181604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
519c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5208b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5371604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5387f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
5397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    const Vector<HWComposer::DisplayConfig>& hwConfigs =
5417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            getHwComposer().getConfigs(type);
5427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    for (size_t c = 0; c < hwConfigs.size(); ++c) {
5437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        const HWComposer::DisplayConfig& hwConfig = hwConfigs[c];
5447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
5457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        float xdpi = hwConfig.xdpi;
5477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        float ydpi = hwConfig.ydpi;
5487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
5507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
5517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
5527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
5537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
5547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
5557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
5567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
5577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
5587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
5597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
5607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
5617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
5627f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
5637f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
5647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
5667f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5677f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
5687f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
5697f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
5707f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
5717f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
5727f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
5731604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5747f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.w = hwConfig.width;
5767f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.h = hwConfig.height;
5777f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
5787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
5797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.fps = float(1e9 / hwConfig.refresh);
58091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
58191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden
58291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
58391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
58491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
58591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
58691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
58791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
58891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
58991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
59091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
59191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
59291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
59391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
59491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.presentationDeadline =
59591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden                hwConfig.refresh - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
5967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
5997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        configs->push_back(info);
6018b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6037f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
605dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
6066c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
6076c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    return getDisplayDevice(display)->getActiveConfig();
6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
609dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
6106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
6116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
6126c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
6136c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
6146c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
6156c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6166c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
6176c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
6186c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6196c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
6226c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
6236c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
6276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
6286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
6296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
6316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
6326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
6336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
6346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
6356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
6366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
6376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
6386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
6396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
6407306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
6417306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
6427306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            if(mMode < 0 || mMode >= configs.size()) {
6439ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
6447306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
6457306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
6466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
6476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
6486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
6497306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
6506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
6516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
6526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
6536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
6546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
6556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
6566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
6576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
6586c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
6596c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
6606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
661888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
662c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
663c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
664d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
665d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
666d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
667d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
668d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
669d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
670d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
671d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
672d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
673d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
674d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
675d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
676d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
677d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
678d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
6798aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
680bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
681bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
68399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
68499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
68599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
68699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
68799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
68899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
68999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
69099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
69199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
69299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
69399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
69499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
69599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
69699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
69799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
69899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
69999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
70099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
701c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
70299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
70399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
70499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
70599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
706c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
70799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
70899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
70999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
71099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
71199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
71299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7144f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
7154f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
7164f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
7174f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
71899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
720faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
721faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
722948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
723faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
724d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
725d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
726faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
72743601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
728faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
729faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
730948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
731faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
732faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
733948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
734948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
735948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
736948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
737948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
738948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
739948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
740faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const nsecs_t period =
741faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
742faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
743faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
744faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
745faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
746faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
747faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
748d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
749d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
750faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
751faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
752faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
753faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
754948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
755faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
756faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
757d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
758d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
759faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
760faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
761faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
762948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
763948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
764948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
765faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
766faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
767faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
768d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
769faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
770d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
771d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
772d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
773d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
774faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
775148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
776d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
777d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
778d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
779d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
780d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
781d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
782148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
783148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
784148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) {
785148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    if (mEventThread == NULL) {
786148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // This is a temporary workaround for b/7145521.  A non-null pointer
787148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // does not mean EventThread has finished initializing, so this
788148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // is not a correct fix.
789148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        ALOGW("WARNING: EventThread not started, ignoring hotplug");
790148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        return;
791148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
7929e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
7939e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
7949e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
795692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
796692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked((DisplayDevice::DisplayType)type);
7979e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
798692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
799692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
8009e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
8019e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
8029e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
8039e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
8043ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
8058630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
8068630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
80781cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) {
808faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
80981cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian    getHwComposer().eventControl(disp, event, enabled);
8108630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
8118630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
8124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
8131c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
81499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
8159eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    case MessageQueue::TRANSACTION:
8169eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        handleMessageTransaction();
8179eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        break;
8184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
8194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
8204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
8214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
8224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
8234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
8244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
8254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
8264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
8274fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8294fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
830e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
8314fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
83287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
8334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
8344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
837cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
83887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
8394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
8403a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
8414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
843cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
844cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
845cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
846cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
847cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
848cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
849cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
850cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
851cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
852cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
853cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
854cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
855cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
856cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
857cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
858cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
859cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
8602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
861cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
862cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
863cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
864cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
865cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
866cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
867cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
868cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
8693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
8703f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
8713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
872cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
873da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
874cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
875cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
876cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
877cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
880cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
882cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
883bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
884bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    HWComposer& hwc(getHwComposer());
885bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
886bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        status_t err = hwc.prepare();
887bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
888bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
889cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
890cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
891cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
892cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
893cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
8941eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
8951eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
896cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
8971eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        if (layers[i]->onPreComposition()) {
898cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
899cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
900cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
901cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
902cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
903cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
904cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
905a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
906cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
907cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
9081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
9091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
910cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
9111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        layers[i]->onPostComposition();
912cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
9134b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
914faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const HWComposer& hwc = getHwComposer();
915faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
916faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
917faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (presentFence->isValid()) {
918faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (mPrimaryDispSync.addPresentFence(presentFence)) {
919faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
920faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
921948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
922faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
923faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
924faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
9255167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
926faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
9272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
928faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
929faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
930faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
931faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
9324b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
9334b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
9344b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
935a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall        if (presentFence->isValid()) {
9364b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentFence(presentFence);
9374b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
9384b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
9394b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
9404b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
9414b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
9424b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
9434b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
9444b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
945cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
946cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
947cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
948cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
94952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
950cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
95187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
95287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
953ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
9541eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const LayerVector& layers(mDrawingState.layersSortedByZ);
95592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
956ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
957ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
95813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            Vector< sp<Layer> > layersSortedByZ;
9594297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
9607e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
9617e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
9622c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            if (hw->isDisplayOn()) {
9631eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                SurfaceFlinger::computeVisibleRegions(layers,
964ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
9657e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
9661eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const size_t count = layers.size();
967ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
9681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const sp<Layer>& layer(layers[i]);
9691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
970ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
971a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
972a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
973a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
974a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
975ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
976ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
97787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
97887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
9793b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
9804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
9817e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
9827e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
9837e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
9843b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
9853b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
986cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
9873b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
988cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
989028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
9907143316af216fa92c31a60d4407b707637382da1Dan Stoza        bool mustRecompose =
9917143316af216fa92c31a60d4407b707637382da1Dan Stoza                !(mDisplays[dpy]->getDirtyRegion(false).isEmpty());
9927143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
993028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
994028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
99552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
99652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
99752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
998a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        if (CC_UNLIKELY(mHwWorkListDirty)) {
999a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            mHwWorkListDirty = false;
1000a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1001a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                sp<const DisplayDevice> hw(mDisplays[dpy]);
1002a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const int32_t id = hw->getHwcDisplayId();
1003a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                if (id >= 0) {
100413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const Vector< sp<Layer> >& currentLayers(
1005a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        hw->getVisibleLayersSortedByZ());
1006a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    const size_t count = currentLayers.size();
1007a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    if (hwc.createWorkList(id, count) == NO_ERROR) {
1008a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        HWComposer::LayerListIterator cur = hwc.begin(id);
1009a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        const HWComposer::LayerListIterator end = hwc.end(id);
1010a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
101113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            const sp<Layer>& layer(currentLayers[i]);
1012a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            layer->setGeometry(hw, *cur);
10139c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
1014a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                                cur->setSkip(true);
1015a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            }
1016a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1017a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1018a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                }
1019a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            }
1020a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        }
1021a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
1022a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        // set the per-frame data
102392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
10244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
1025e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
1026e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
102713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                const Vector< sp<Layer> >& currentLayers(
1028cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
1029e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
1030a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                HWComposer::LayerListIterator cur = hwc.begin(id);
1031a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const HWComposer::LayerListIterator end = hwc.end(id);
1032a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
1033a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    /*
1034a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * update the per-frame h/w composer data for each layer
1035a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * and build the transparent region of the FB
1036a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     */
103713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const sp<Layer>& layer(currentLayers[i]);
1038a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    layer->setPerFrameData(hw, *cur);
10391e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
104052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
104187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
1042a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
104303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        // If possible, attempt to use the cursor overlay on each display.
104403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
104503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            sp<const DisplayDevice> hw(mDisplays[dpy]);
104603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            const int32_t id = hw->getHwcDisplayId();
104703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            if (id >= 0) {
104803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const Vector< sp<Layer> >& currentLayers(
104903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    hw->getVisibleLayersSortedByZ());
105003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const size_t count = currentLayers.size();
105103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                HWComposer::LayerListIterator cur = hwc.begin(id);
105203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const HWComposer::LayerListIterator end = hwc.end(id);
105303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
105403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    const sp<Layer>& layer(currentLayers[i]);
105503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    if (layer->isPotentialCursor()) {
105603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                        cur->setIsCursorLayerHint();
105703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                        break;
105803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
105903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
106003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
106103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
106203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
106352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
106452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
106538efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall
106638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
106738efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            sp<const DisplayDevice> hw(mDisplays[dpy]);
106838efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            hw->prepareFrame(hwc);
106938efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
107052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
1071cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
107252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1073cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1074cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
107552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
107692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
10774297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
10782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1079cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1080cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
108102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
108202b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
108302b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
108402b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1085cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1086cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1087cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
108887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
108952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
10904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
10914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
109252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1097841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1098b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1099a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1100a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1101c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
110252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
1103ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
11042a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        if (!hwc.supportsFramebufferTarget()) {
11052a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            // EGL spec says:
11062a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //   "surface must be bound to the calling thread's current context,
11072a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //    for the current rendering API."
1108875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
11092a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        }
1110e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
111152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
111252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
11136da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // make the default display current because the VirtualDisplayDevice code cannot
11146da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // deal with dequeueBuffer() being called outside of the composition loop; however
11156da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // the code below can call glFlush() which is allowed (and does in some case) call
11166da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // dequeueBuffer().
11176da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
11186da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian
111992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
112113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
1122da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        hw->onSwapBuffersCompleted(hwc);
112352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
1124e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
1125e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
11261e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
11271e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
112852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
1129d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
113052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1131cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
113252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
1133d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
113452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1135ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1136e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1137e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1138a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1139a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
11406547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
11416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
11426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
11436547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
11446547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
114787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1149841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1150841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
11517cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
11527cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
11537cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
11547cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
11557cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
11567cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1157ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1158ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1159ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1160ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1161ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1162ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1163ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1164ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1165ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1166ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1167e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
116887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1169ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1170ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1171ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1172ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1173ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
11743d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
117687baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
11773d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
11783d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11863559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
118813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
1189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
11993559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1202e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
120392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
120492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
120592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1206e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1207e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
120892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
121092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
121193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
121292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
121392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
121492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
121592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
121692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
121792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
122092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
12213ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
122227ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
122327ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
122427ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
122502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1226875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
122702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
122802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
122902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
12309e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
12317adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
123202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
123392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
123492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
123592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
123692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
123792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1238e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
12393ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1240111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
1241e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
124293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
124393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
124493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
124502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
124602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
124702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
124893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
124993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
125093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
125193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
125293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
125392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
125493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1255db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
125693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
125793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
125893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
125993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
126000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
126100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
126200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
126300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
126400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
12654fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
126693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
126747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
126847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
126947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
127092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
127192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
127292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
127392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
127492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
127592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
127692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1277e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1278e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1279cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
128099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1281db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1282b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1283b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
1284b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
1285b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                            new GraphicBufferAlloc());
1286db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
128702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                    int32_t hwcDisplayId = -1;
128899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
128902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
129002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
129102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
129299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1293db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
129402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hwcDisplayId = allocateHwcDisplayId(state.type);
1295db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
1296b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    *mHwc, hwcDisplayId, state.surface,
1297b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    bqProducer, bqConsumer, state.displayName);
1298db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1299db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
130047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
130199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
130299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1303cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1304cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1305cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1306cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
130702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        hwcDisplayId = allocateHwcDisplayId(state.type);
1308cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // for supported (by hwc) displays we provide our
1309cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // own rendering surface
1310b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        dispSurface = new FramebufferSurface(*mHwc, state.type,
1311b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                bqConsumer);
1312b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        producer = bqProducer;
1313cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1314cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1315cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
131699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1317cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
131819e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                state.type, hwcDisplayId,
131919e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                mHwc->getFormat(hwcDisplayId), state.isSecure,
132005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                display, dispSurface, producer,
132105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1322cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1323cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
13244fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
13258dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1326cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
13271c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        if (state.isVirtualDisplay()) {
13281c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            if (hwcDisplayId >= 0) {
13291c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                mHwc->setVirtualDisplayProperties(hwcDisplayId,
13301c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getWidth(), hw->getHeight(),
13311c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getFormat());
13321c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            }
13331c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        } else {
13347adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
13351c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
133693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
133792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
133892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
13403559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13428430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
13438430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
13448430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
13458430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
13468430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
13478430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
13488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
13498430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
13508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
13518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
13528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
13538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
13548430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
13558430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
13568430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
13578430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
13588430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
13598430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
13608430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
13618430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
13628430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
13638430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
13648430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
13658430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
13668430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
13678430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
136813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
13691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
13708430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
13718430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
13728430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
13738430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
13748430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
13758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
13768430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
13778430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
13788430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
13798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
13808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
13818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
138291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
13838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
13848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
13858430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
13868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
13878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
138891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
138991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
139091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
139191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
139291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
139391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
139491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
139591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
13968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
139791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
13988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
13998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
14008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
14018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
14023559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
14033559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
14043559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
14071eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
14083559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
14093559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
14103559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
14113559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
14123559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
14133559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
14143559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
14153559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
14163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
14171eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const size_t count = layers.size();
14183559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
14191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            const sp<Layer>& layer(layers[i]);
14203559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
14213559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
14223559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
14233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
14243559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
14251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
14261501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
14271501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
14281501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
14290aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
143403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
143503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
143603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
143703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
143803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
143903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
144003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    HWComposer& hwc(getHwComposer());
144103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
144203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        sp<const DisplayDevice> hw(mDisplays[dpy]);
144303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const int32_t id = hw->getHwcDisplayId();
144403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        if (id < 0) {
144503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
144603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
144703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const Vector< sp<Layer> >& currentLayers(
144803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            hw->getVisibleLayersSortedByZ());
144903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const size_t count = currentLayers.size();
145003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        HWComposer::LayerListIterator cur = hwc.begin(id);
145103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const HWComposer::LayerListIterator end = hwc.end(id);
145203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
145303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) {
145403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                continue;
145503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
145603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            const sp<Layer>& layer(currentLayers[i]);
145703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            Rect cursorPos = layer->getPosition(hw);
145803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            hwc.setCursorPositionAsync(id, cursorPos);
145903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            break;
146003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
146103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
14624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
14634fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
14644fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
14654fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
14664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
14674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
14684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
14694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
14704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
14714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
14724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
14734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
14744b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
14754b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
14764b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
14774b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
14784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
14792d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
14802d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
14814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
148587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
148687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1488841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1489841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
149487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
149813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer = currentLayers[i];
1499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
15011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
150301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
150487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
150587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
150687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1507ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1508ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1509ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1511ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1512ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1513ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1514ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1515ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1516ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1517ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1519ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1520ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1521ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1522ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1523ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1525ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1526a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1527a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1528a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1529a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1530a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1531a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1532a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1533a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1534a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1535a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1536ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1537ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1538da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
15394125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
15405219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian            Rect bounds(s.transform.transform(layer->computeBounds()));
1541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1542ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1543ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1544ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
15454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
15464fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
15474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
15484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
15492ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                            transparentRegion = tr.transform(s.activeTransparentRegion);
15504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
15514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
15524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
1553a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                            transparentRegion.clear();
15544fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
15554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
15562ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        transparentRegion = s.activeTransparentRegion;
15574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1558ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1560ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
15614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1562ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1563ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1564ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1565ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1566ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1570ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1571ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1572ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1573ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1574ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1575ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
15844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1587a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1590ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1591ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1592ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1593ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1597ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1598a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1599ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
16004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
16014fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1602ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1603ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
160887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
16128b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1613a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1616a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1617a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
162087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
162387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
162487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
162592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
16264297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
16274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
16284297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
162992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
163092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
163187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
163287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
163387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
163699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
16374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
16381eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
163951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
164051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
164151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
164251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
164351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
164451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
164551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
164651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
164751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
164851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
164951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    Vector<Layer*> layersWithQueuedFrames;
165051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layers.size(); i<count ; i++) {
16511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const sp<Layer>& layer(layers[i]);
165251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner        if (layer->hasQueuedFrame())
165351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner            layersWithQueuedFrames.push_back(layer.get());
165451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    }
165551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
165651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner        Layer* layer = layersWithQueuedFrames[i];
165787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
16581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
165987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
16604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
16614da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
16623b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1665ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1666ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1667ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1668ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1669ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
167099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1671cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
167287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16747143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
16757143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
16767143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
16777143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
16787143316af216fa92c31a60d4407b707637382da1Dan Stoza    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
16797143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
16807143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
16817143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
16827143316af216fa92c31a60d4407b707637382da1Dan Stoza
168387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
168487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1685b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
16864297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16884297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
16890f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
169029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
169129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
169229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
16934297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
16950f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
169629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1697df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
169895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
16990f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
17004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
170229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
17034297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
17044297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17089c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
1709ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        doComposeSurfaces(hw, dirtyRegion);
1710ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    } else {
1711ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        RenderEngine& engine(getRenderEngine());
17129c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mat4 colorMatrix = mColorMatrix;
17139c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        if (mDaltonize) {
17149c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            colorMatrix = colorMatrix * mDaltonizer();
17159c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        }
17169c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        engine.beginGroup(colorMatrix);
1717ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        doComposeSurfaces(hw, dirtyRegion);
1718ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        engine.endGroup();
1719ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    }
1720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17219c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
17224297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1723da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1724da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
1725da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
1726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1728cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
173185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
17328630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
17331e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
17341e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1735a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1736d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall    bool hasGlesComposition = hwc.hasGlesComposition(id);
173785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1738875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
1739c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
1740c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock                  hw->getDisplayName().string());
1741c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            return;
1742c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
1743a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1744a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
174585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1746e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1747b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1748b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1749b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
17503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
1751b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
17523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.clearWithColor(0, 0, 0, 0);
1753b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1754766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
1755766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region bounds(hw->getBounds());
1756766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1757766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
1758766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
1759766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
1760766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region letterbox(bounds.subtract(hw->getScissor()));
1761766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1762766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
1763766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            Region region(hw->undefinedRegion.merge(letterbox));
1764766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1765766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
1766766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
1767766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1768b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
176987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1770b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
177155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1772b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1773a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
1774f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1775766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
1776766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
1777f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
1778f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
1779f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            const Rect& bounds(hw->getBounds());
1780766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Rect& scissor(hw->getScissor());
1781f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
1782f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
1783f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
1784f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
17853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1786f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
17873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                const uint32_t height = hw->getHeight();
17883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.setScissor(scissor.left, height - scissor.bottom,
17893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
1790f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
1791f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
179285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
17934b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
179485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
179585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
179685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
17974b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
179813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
179985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
180085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
180185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
180285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
180385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
180413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
18054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
180685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
180785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
180803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    case HWC_CURSOR_OVERLAY:
180985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
1810ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
181185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
181285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
18134125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                                && layer->isOpaque(state) && (state.alpha == 0xFF)
181485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1815cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1816cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1817cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1818cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
181985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
182085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
182185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1822cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
182385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1824a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1825da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    case HWC_FRAMEBUFFER_TARGET: {
1826da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // this should not happen as the iterator shouldn't
1827da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // let us get there.
182886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i);
1829da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
1830da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    }
1831cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1832a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
183385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
183485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
183585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
183685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
183785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
183813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
183985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
184085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
184185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
184285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
184385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
18444b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
18454b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1846f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1847f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
18483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableScissor();
1849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
185255801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
18533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
18543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
1855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1857ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianvoid SurfaceFlinger::addClientLayer(const sp<Client>& client,
1858ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
18596710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
186013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
18611b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
186296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
1863ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
18644f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
186596f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1866921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1867921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
18686710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    mGraphicBufferProducerList.add(gbc->asBinder());
186996f0819f81293076e652792794a961543e6750d7Mathias Agopian}
187096f0819f81293076e652792794a961543e6750d7Mathias Agopian
18713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
187296f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
187313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
1874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
18756710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        mLayersPendingRemoval.push(layer);
1876076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
18776710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
18803d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1883c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
1884dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1885dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1886dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
18873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
1888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
1892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
189499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18998b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
19008b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
19018b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
19028b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
19038b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
19047c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
1905698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
190628378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1907e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
19082d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
19092d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
19102d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
19112d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
19127c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
19132d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
19142d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
19157c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
19167c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
19177c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
19182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
19192d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
19202d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
19212d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
19222d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
19232d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
1924e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1925e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1926e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1927e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1928b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1929b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1930e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1931698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1932698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1933d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
1934d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
1935d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
1936d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
1937d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
1938d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
1939d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
1940d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
1941d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            sp<IBinder> binder = s.client->asBinder();
1942d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
1943d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
1944d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
1945d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
1946d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
1947d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
1948d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
1949d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
1950698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1951386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
195228378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1953386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
195428378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1955698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1956386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1957386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1958386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
19592d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
19602d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
19612d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
19622d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
1963386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
19642d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
1965386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1966386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1967386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1968386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
19692d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
19702d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
1971386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1972386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1973cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1977e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1978e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
19799a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
19809a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
19819a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
19829a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
1983e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
19849a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
19853ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
1986e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1987e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1988e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1989e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1990e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1991e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1992e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1993e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1994e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1995e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1996e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1997e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1998e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
199900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2000e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2001e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2002e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2003e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2004e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2005e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2006e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2007e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2008e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2009e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2010e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2011e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2012e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
201347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
201447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
201547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
201647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
201747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
201847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
201947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
202047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
202147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
202247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2023e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2024e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2025e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2026e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2027e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2028e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2029e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2030e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2031e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
203213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2033e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2034e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2035e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
2036e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
2037e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2038e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2039e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2040e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2041e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
2042e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
2043e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2044e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2045e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2046e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2047e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2048e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2049e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2050e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2051e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2052e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2053e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2054e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2055e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
2056e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
2057e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2058e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2059e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2060e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2061e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2062e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2063e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2064e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2065e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2066e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
20674125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if ((what & layer_state_t::eVisibilityChanged) ||
20684125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                (what & layer_state_t::eOpacityChanged)) {
20694125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            // TODO: should we just use an eFlagsChanged for this?
2070e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2071e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2072e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2073e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
2074e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
2075e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2076e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2077e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2078e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2079e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
2080e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
2081e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2082e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2083e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2084e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2085e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2086e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2087e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2088e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2089e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2090e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2091e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
20924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
20930ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
20940ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
20954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
20964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
2097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
20996e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2100921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
21016e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
21024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
21036e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
21048b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
21054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
21064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
21074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
21084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
21093165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
21103165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
21114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
21124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
21134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
21153165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
21164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
21174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
21184d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
21194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
21204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
21214d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (result == NO_ERROR) {
21266710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        addClientLayer(client, *handle, *gbp, layer);
212796f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
2128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
21294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
21334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
21344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
213792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
21438f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21474d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
21484d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
21494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
21504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2151b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
21534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
21544d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
21554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21584d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
21594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
21604d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
21634d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2164b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
21654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2166118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2167118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2168ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
21699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
21706710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
21716710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
21726710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
21736710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
21746710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
21756710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
21766710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
21779a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
21789a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
21799a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
21809a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
218113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21836710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
21846710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
2185ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
218613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> l(layer.promote());
2187ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
21886710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
2189e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
2190ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
2191ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
2192ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
2193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2195b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2196b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
219713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
219801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
219913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
220013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
220113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
220201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
220301e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2204692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
220501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
220613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
22074c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
22084c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
220947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
221047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
221113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
221213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
22132c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
22146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
22156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const nsecs_t period =
22166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
22176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
221813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
221913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
222013a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
222113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
222213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
222313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
222413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
222513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
222613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
222713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
222813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
222913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
223013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
223113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
223213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
223313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
22342c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
22352c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
22362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
22372c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
22382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
22392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
224013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
22412c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
22422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2243c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2244c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2245c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
22462c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
22472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
22482c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
22492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
22502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2251c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
22522c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
22532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2254c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2255c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2256c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2257948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2258c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
22612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
22622c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2263c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2264948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2265948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2266cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2267cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2268cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2269c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
22702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
22712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
22722c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
22732c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
22742c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2275b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
22792c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2280db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2281db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
22822c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2283b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
22842c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
22852c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
22862c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2287b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
22882c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2289db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
22902c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
22917306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
22929e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
22932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
22942c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2295db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
22962c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2297db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2298b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2299b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2300b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
23012c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2302db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2303b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2304b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2305b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2306b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
231099b49840d309727678b77403d6cc9f920111623fMathias Agopian
2311bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2312bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2313bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2314bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2315bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
231674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2317bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
23199795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
23209795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
23219795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
23229795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
23239795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
23249795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
23259795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
23269795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
23279795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
232874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            result.append(
23299795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
23309795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
23319795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
23329795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
233382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
233482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
233525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
233625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
233725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
233825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
233925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
234074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
234135aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
234225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
234325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
234425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
234525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
234682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
234774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
234835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
234982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
235025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
235125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
235225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
235325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
235474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
235535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
235625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2357c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2358c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2359c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2360c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2361c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2362c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2363c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
23651b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
236682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
236774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
236882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
236948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
237082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
237182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
237248b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
237382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
237482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
237582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
237682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
237748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2378c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2379c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
238025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
238125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
238225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
238325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
238413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
238574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
238625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
238725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
238825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
238982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
239074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
239182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
239282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
239382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
239482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
239582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
239682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
239748b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
23984b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    const nsecs_t period =
23994b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
240086efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
24014b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
24024b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2403d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
24044b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
24054b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
24064b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const size_t count = currentLayers.size();
24074b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        for (size_t i=0 ; i<count ; i++) {
240813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
24094b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2410d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
24114b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
241282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
241382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
241482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2415ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
241625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2417c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
241825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
241925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
242025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
242125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
242225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
242325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
242425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
242525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
242625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
242725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
242813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
242925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2430d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
243125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
243225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
24334b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2434d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
243525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
243625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
24376547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
24386547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
24396547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
24406547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
24416547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const size_t count = drawingLayers.size();
24426547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
24436547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        const sp<Layer>& layer(drawingLayers[i]);
24446547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
24456547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
24466547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
24476547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
24486547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
24496547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
24504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
24514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
24524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
24534803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
24544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
24554803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
24564803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
24574803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
24584803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
24594803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
24604803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
24614803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
24624803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
24634803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
24644803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
24654803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
24664803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
246774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
246874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
246982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
24703e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
24713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
24723e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
24733e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
24743e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
24753e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
24763e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
24773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
24783e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
247982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
248082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
248182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
248282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
248382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
248482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2485bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
248682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
24874803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
24884803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
24893e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
24903e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
24914803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
24923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
24934803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
24944803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
24954803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
24964803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
24974803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
24983e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
2499ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
25003e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
2501ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
2502ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
2503ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
250441d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
250541d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
250641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
250724cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
250824cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
250941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS,
251041d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY));
251141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
251241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
25134803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
251482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
251582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
251682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
251782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
25183e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
251986efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Visible layers (count = %zu)\n", count);
25203e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
252182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
252213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
25233e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
252482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2525bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
252682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
25275f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
25285f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
25295f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
25303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
253186efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
25323e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
25335f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
25345f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
253574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
25365f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
25375f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
25385f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
253982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
254082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
25411b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
25423e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
254374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
25443e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
25451b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2546888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
25474297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
2548ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
25493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
25503e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
25513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
25523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
25533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
2554ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
2555ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
2556875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
25579795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
25584297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
25592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
25602c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
256174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
256282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
256382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2564c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
256582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
256682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
2567ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
2568ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
2569ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
257082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
257182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2572c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2573b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2574b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2575ed985574148a938bc3af24442eead313cc62521cMathias Agopian            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
2576ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
257782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
257874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
257982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
258082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
258174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
258282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
258382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
258482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
258582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
258682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
258774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
258882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
258982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
259082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
259182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
25923e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
259374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
25943e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
259574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  h/w composer %s and %s\n",
259682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
25979c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    (mDebugDisableHWC || mDebugRegion || mDaltonize
25989c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            || mHasColorMatrix) ? "disabled" : "enabled");
259974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
260082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
260182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
260282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
260382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
260482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
260582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
2606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
260813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
260948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
2610db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
261148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
261248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
261348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
261448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
261548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
261648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
261748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
261848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
261948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
262048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
262148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
262248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
262348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
2624cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
2625cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
262663f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
262763f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
262863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
262963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
263063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
263163f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
263263f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
263363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
263463f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
263524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
263663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
263763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
263863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
263963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
264063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
264163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
264263f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
264363f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2649041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
2650698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
2652d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
2653d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
26542c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
2655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2659a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
266099b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
266199b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2662e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2663375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2664375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
26661b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
26671b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
26681b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
26691b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
26701b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
26711b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
26721b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
26731b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
267499b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
267599b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2676e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
26771b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
26781b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
26791b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
26801b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
26831b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2686b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
268799ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2688375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2689375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2690375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2691e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2692375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
269701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
269835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
270353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
270453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
270753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2708cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2709cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2710cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2711e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2712e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2713e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2714e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2715cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
27174d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
27184d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
27194d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
27204d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
272153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
272253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
272353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
272453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
272553331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
272653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2727a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2728a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2729a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2730a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2731a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2732a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
273401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2737b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
273812839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
27424297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
27434297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2744ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
2745ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
2746ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
2747ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
2748ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
2749ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
2750ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 1: mDaltonizer.setType(Daltonizer::protanomaly);   break;
2751ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break;
2752ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 3: mDaltonizer.setType(Daltonizer::tritanomaly);   break;
2753ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2754ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
2755ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::correction);
2756ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
2757ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::simulation);
2758ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2759ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                mDaltonize = n > 0;
2760ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
2761ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
27629c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
27639c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
27649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
27659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
27669c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
27679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                mHasColorMatrix = n ? 1 : 0;
27689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
27699c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
27709c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
27719c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
2772794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
2773794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      for (size_t j = 0; j < 4; j++) {
2774794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                          mColorMatrix[i][j] = data.readFloat();
2775794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      }
27769c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
27779c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
27789c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
27799c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
27809c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
27819c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
27829c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
2783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2784f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
2785f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
2786f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
2787645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
2788645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
2789f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
2790f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
2791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
279653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
279787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
279899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
279953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
280053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
280159119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
28022a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
28032a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
280459119e658a12279e8fff508f8773843de2d90917Mathias Agopian
28052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
28062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
28072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
2808b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
2809b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
2810b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
2811b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
28122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
28132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
2814b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
2815b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
2816b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
2817b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
2818b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
2819b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
2820b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
2821b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
2822b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
2823b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
2824b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
2825b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
2826b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
2827b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
28282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
28292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
28302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
28312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
28322ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
2833b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
28342ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
28352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
28362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
28372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
28382ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
28392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
28402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
28412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
28422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
28432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
2844b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
2845b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
2846b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
28472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
28482ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
2849c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
28502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
28512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
28522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
28532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
2854b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
2855b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
2856b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
2857b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
28582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
28592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
28602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
2861b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
2862b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
2863b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
28642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
28652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
28662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
2867c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
28682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
28692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
28702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
2871b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
28722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
28732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
28742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
2875b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
2876b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
2877b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
2878b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
2879c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng            result = impl->asBinder()->transact(code, data[0], reply);
28802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
2881b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
28822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
28832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
28842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
28852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
28862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
2887b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
2888b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
2889b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
2890b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
2891b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitRequested(false)
2892b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
2893b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
2894b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
28952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
28962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
28972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
28982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
28992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
29002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
29012ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
2902b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
29032ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
2904aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
29052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
2906b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
2907b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
2908b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
29092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
29102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
29112ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
29122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29142a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
29152a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
2916c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
2917c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
2918c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) {
29192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
29202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
29212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
29222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
29232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
29242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
29252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
29265ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
29275ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
29285ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
29295ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    if (!producer->asBinder()->localBinder()) {
29305ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        Mutex::Autolock _l(mStateLock);
29315ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        sp<const DisplayDevice> hw(getDisplayDevice(display));
29325ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        if (hw->getSecureLayerVisible()) {
29335ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            ALOGW("FB is protected: PERMISSION_DENIED");
29345ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            return PERMISSION_DENIED;
29355ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        }
29365ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    }
29375ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
29382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
29392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
29402a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
29412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
2942c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
29432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
29442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
2945c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
29462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
29472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
29482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
29492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
29502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
2951c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
2952c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                uint32_t minLayerZ, uint32_t maxLayerZ,
2953c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                bool useIdentityTransform)
29542a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
2955c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
29562a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2957c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
29582a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              result(PERMISSION_DENIED)
29592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
29602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
29612a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
29622a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
29632a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
29642a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
29652a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
29662a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
2967c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
2968c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
2969c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    useIdentityTransform);
29702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
29712a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
29722a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
29732a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
29742a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
29759eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // make sure to process transactions before screenshots -- a transaction
29769eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // might already be pending but scheduled for VSYNC; this guarantees we
29779eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // will handle it before the screenshot. When VSYNC finally arrives
29789eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // the scheduled transaction will be a no-op. If no transactions are
29799eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // scheduled at this time, this will end-up being a no-op as well.
29809eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    mEventQueue.invalidateTransactionNow();
29819eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
29822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
29832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
29842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
29852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
29862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
29882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
29892a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
29902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
2991c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
2992c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            useIdentityTransform);
29932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
29952a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
29962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
29972a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
29982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
2999118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3000118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3001180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3002180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3003180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3004c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3005180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ,
3006c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool yswap, bool useIdentityTransform)
3007180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3008180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
30093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3010180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3011180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
3012180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
3013180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
3014180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const bool filtering = reqWidth != hw_w || reqWidth != hw_h;
3015180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3016c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3017c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3018c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3019c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3020c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3021c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3022c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3023c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3024c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3025c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3026c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3027be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
3028be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3029c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3030c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3031c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3032c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3033be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
3034be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3035c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3036c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3037180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
30383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3039180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3040180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3041c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, hw_h, yswap);
30423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3043180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3044180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
30453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3046180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3047180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const LayerVector& layers( mDrawingState.layersSortedByZ );
3048180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const size_t count = layers.size();
3049180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
3050180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<Layer>& layer(layers[i]);
30511eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
3052180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
3053180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
3054180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
3055180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
3056c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    layer->draw(hw, useIdentityTransform);
3057180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
3058180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
3059180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
3060180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
3061180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3062180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3063180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // compositionComplete is needed for older driver
3064180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    hw->compositionComplete();
3065931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
3066180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
3067180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3068180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
30692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
30702a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
30712a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3072c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3073c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3074c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform)
307574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
3076fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
3077fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
3078180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
3079180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
3080180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
3081180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3082180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
3083180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
3084180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
3085180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
3086180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3087180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3088180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
3089180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
3090180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
30910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
30920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
309383cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
30940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
309574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
30960aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    status_t result = NO_ERROR;
30970aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) {
30983ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
30993ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
31002a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
31010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
31020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
31034ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
31040aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
31050aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
31062a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
31070aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
31080aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
31090aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
31100aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
31110aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
31120aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
31130aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
3114866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
31150aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
31160aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
31170aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
31180aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
31190aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
31203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
31213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
31223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
31233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
31240aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
31250aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
31260aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
31270aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3128c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                        renderScreenImplLocked(hw, sourceCrop, reqWidth, reqHeight,
3129c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                                minLayerZ, maxLayerZ, true, useIdentityTransform);
3130d555684cb36dfb959694db76962e570184f98838Mathias Agopian
3131866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
3132866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
3133866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
3134866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
3135866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
3136866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
3137866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3138866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
3139866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
31402d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
3141866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
3142866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
3143866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
3144866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
3145866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
3146866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
31472d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
3148866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3149866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
3150866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
3151866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
3152866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
3153866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
3154866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
3155866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
3156866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
3157866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
3158866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
3159866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
3160866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
3161866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
31622d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
3163866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
31642d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
31652d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
3166d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3167d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3168d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3169d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3170d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3171d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3172d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3173d555684cb36dfb959694db76962e570184f98838Mathias Agopian
31740aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
31750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
31760aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
31770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
31780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
31790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
31800aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
31810aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
318274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
3183866399093f9f60e7305f291e688abb456bace710Riley Andrews                window->queueBuffer(window, buffer, syncFd);
3184866399093f9f60e7305f291e688abb456bace710Riley Andrews                if (syncFd != -1) {
3185866399093f9f60e7305f291e688abb456bace710Riley Andrews                    close(syncFd);
3186866399093f9f60e7305f291e688abb456bace710Riley Andrews                }
318774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
31880aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
31890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
319074c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
31910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
319274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
319374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
319474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
319574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
319674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3197d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3198d555684cb36dfb959694db76962e570184f98838Mathias Agopian        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
3199fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3200d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3201d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3202d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3203fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3204fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3205fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3206fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3207fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3208fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
3209fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const LayerVector& layers( mDrawingState.layersSortedByZ );
3210fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const size_t count = layers.size();
3211fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
3212fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const sp<Layer>& layer(layers[i]);
3213fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
3214fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
3215fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
3216fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
321786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x",
3218fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
3219fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            i, layer->getName().string(), state.layerStack, state.z,
3220fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
3221fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3222fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3223fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian}
3224fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
32251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
32261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3227921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
3228921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3229921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3230921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
323113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : SortedVector<sp<Layer> >(rhs) {
3232921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3233921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3234921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
3235921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
3236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3237be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
323813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
323913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
3240be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
32411eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t ls = l->getCurrentState().layerStack;
32421eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rs = r->getCurrentState().layerStack;
3243be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
3244be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
3245be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
32461eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t lz = l->getCurrentState().z;
32471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rz = r->getCurrentState().z;
3248be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
3249be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
3250be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
3251be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
3252921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3253921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3254921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
3255921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
32563ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
325747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    : type(DisplayDevice::DISPLAY_ID_INVALID), width(0), height(0) {
3258e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
3259e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
32603ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
326147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0), width(0), height(0) {
3262da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
3263da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
3264b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
32657303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3266b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
326796f0819f81293076e652792794a961543e6750d7Mathias Agopian
3268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
32693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
32703f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
32713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
32723f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
32733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
32743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
32753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
32763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
32773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3278