SurfaceFlinger.cpp revision b154c42c39c1499c26d88fff8ca642cd86f91098
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
60691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFaddenint SurfaceFlinger::getActiveConfig(const sp<IBinder>&) {
6077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return 0;
6087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
609dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
61091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFaddenstatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>&, int) {
611888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
612c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
613c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
614d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
615d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
616d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
617d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
618d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
619d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
620d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
621d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
622d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
623d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
624d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
625d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
626d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
627d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
628d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
6298aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
630bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
631bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
63399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
63499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
63599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
63699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
63799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
63899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
63999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
64099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
64199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
64299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
64399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
64499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
64599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
64699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
64799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
64899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
64999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
65099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
651c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
65299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
65399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
65499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
65599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
656c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
65799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
65899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
65999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
66099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
66199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
66299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6644f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
6654f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
6664f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
6674f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
66899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
670faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
671faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
672948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
673faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
674d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
675d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
676faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
67743601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
678faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
679faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
680948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
681faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
682faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
683948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
684948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
685948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
686948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
687948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
688948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
689948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
690faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const nsecs_t period =
691faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
692faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
693faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
694faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
695faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
696faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
697faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
698d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
699d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
700faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
701faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
702faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
703faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
704948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
705faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
706faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
707d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
708d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
709faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
710faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
711faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
712948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
713948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
714948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
715faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
716faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
717faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
718d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
719faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
720d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
721d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
722d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
723d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
724faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
725148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
726d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
727d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
728d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
729d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
730d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
731d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
732148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
733148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
734148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) {
735148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    if (mEventThread == NULL) {
736148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // This is a temporary workaround for b/7145521.  A non-null pointer
737148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // does not mean EventThread has finished initializing, so this
738148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // is not a correct fix.
739148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        ALOGW("WARNING: EventThread not started, ignoring hotplug");
740148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        return;
741148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
7429e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
7439e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
7449e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
745692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
746692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked((DisplayDevice::DisplayType)type);
7479e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
748692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
749692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
7509e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
7519e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
7529e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
7539e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
7543ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
7558630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
7568630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
75781cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) {
758faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
75981cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian    getHwComposer().eventControl(disp, event, enabled);
7608630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
7618630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
7624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
7631c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
76499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
7659eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    case MessageQueue::TRANSACTION:
7669eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        handleMessageTransaction();
7679eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        break;
7684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
7694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
7704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
7714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
7724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
7734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
7744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
7754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
7764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
7774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7794fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
780e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
7814fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
78287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
7834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
7844fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
787cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
78887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
7894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
7903a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
7914fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
792cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
793cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
794cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
795cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
796cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
797cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
798cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
799cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
800cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
801cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
802cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
803cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
804cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
805cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
806cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
807cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
808cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
809cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
8102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
811cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
812cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
813cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
814cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
815cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
816cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
817cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
818cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
8193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
8203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
8213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
822cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
823da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
824cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
825cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
826cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
827cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
828cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
829cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
830cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
831cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
832cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
833bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
834bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    HWComposer& hwc(getHwComposer());
835bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
836bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        status_t err = hwc.prepare();
837bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
838bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
839cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
840cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
841cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
842cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
843cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
8441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
8451eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
846cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
8471eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        if (layers[i]->onPreComposition()) {
848cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
849cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
850cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
851cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
852cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
853cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
854cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
855a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
856cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
857cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
8581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
8591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
860cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
8611eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        layers[i]->onPostComposition();
862cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
8634b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
864faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const HWComposer& hwc = getHwComposer();
865faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
866faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
867faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (presentFence->isValid()) {
868faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (mPrimaryDispSync.addPresentFence(presentFence)) {
869faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
870faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
871948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
872faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
873faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
874faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
8755167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
876faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
8772c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
878faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
879faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
880faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
881faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
8824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
8834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
8844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
885a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall        if (presentFence->isValid()) {
8864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentFence(presentFence);
8874b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
8884b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
8894b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
8904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
8914b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
8924b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
8934b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
8944b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
895cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
896cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
897cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
898cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
89952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
900cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
90187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
90287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
903ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
9041eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const LayerVector& layers(mDrawingState.layersSortedByZ);
90592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
906ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
907ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
90813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            Vector< sp<Layer> > layersSortedByZ;
9094297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
9107e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
9117e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
9122c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            if (hw->isDisplayOn()) {
9131eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                SurfaceFlinger::computeVisibleRegions(layers,
914ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
9157e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
9161eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const size_t count = layers.size();
917ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
9181eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const sp<Layer>& layer(layers[i]);
9191eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
920ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
921a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
922a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
923a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
924a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
925ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
926ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
92787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
92887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
9293b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
9304297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
9317e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
9327e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
9337e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
9343b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
9353b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
936cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
9373b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
938cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
939028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
9407143316af216fa92c31a60d4407b707637382da1Dan Stoza        bool mustRecompose =
9417143316af216fa92c31a60d4407b707637382da1Dan Stoza                !(mDisplays[dpy]->getDirtyRegion(false).isEmpty());
9427143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
943028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
944028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
94552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
94652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
94752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
948a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        if (CC_UNLIKELY(mHwWorkListDirty)) {
949a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            mHwWorkListDirty = false;
950a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
951a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                sp<const DisplayDevice> hw(mDisplays[dpy]);
952a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const int32_t id = hw->getHwcDisplayId();
953a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                if (id >= 0) {
95413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const Vector< sp<Layer> >& currentLayers(
955a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        hw->getVisibleLayersSortedByZ());
956a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    const size_t count = currentLayers.size();
957a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    if (hwc.createWorkList(id, count) == NO_ERROR) {
958a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        HWComposer::LayerListIterator cur = hwc.begin(id);
959a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        const HWComposer::LayerListIterator end = hwc.end(id);
960a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
96113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            const sp<Layer>& layer(currentLayers[i]);
962a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            layer->setGeometry(hw, *cur);
9639c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
964a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                                cur->setSkip(true);
965a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            }
966a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
967a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
968a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                }
969a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            }
970a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        }
971a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
972a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        // set the per-frame data
97392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
9744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
975e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
976e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
97713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                const Vector< sp<Layer> >& currentLayers(
978cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
979e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
980a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                HWComposer::LayerListIterator cur = hwc.begin(id);
981a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const HWComposer::LayerListIterator end = hwc.end(id);
982a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
983a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    /*
984a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * update the per-frame h/w composer data for each layer
985a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * and build the transparent region of the FB
986a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     */
98713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const sp<Layer>& layer(currentLayers[i]);
988a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    layer->setPerFrameData(hw, *cur);
9891e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
99052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
99187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
992a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
99352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
99452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
99538efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall
99638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
99738efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            sp<const DisplayDevice> hw(mDisplays[dpy]);
99838efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            hw->prepareFrame(hwc);
99938efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
100052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
1001cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
100252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1003cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1004cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
100552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
100692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
10074297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
10082c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1009cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1010cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
101102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
101202b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
101302b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
101402b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1015cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1016cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1017cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
101887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
101952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
10204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
10214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
102252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1027841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1028b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1029a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1030a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1031c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
103252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
1033ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
10342a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        if (!hwc.supportsFramebufferTarget()) {
10352a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            // EGL spec says:
10362a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //   "surface must be bound to the calling thread's current context,
10372a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //    for the current rendering API."
1038875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
10392a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        }
1040e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
104152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
104252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
10436da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // make the default display current because the VirtualDisplayDevice code cannot
10446da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // deal with dequeueBuffer() being called outside of the composition loop; however
10456da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // the code below can call glFlush() which is allowed (and does in some case) call
10466da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // dequeueBuffer().
10476da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
10486da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian
104992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
10504297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
105113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
1052da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        hw->onSwapBuffersCompleted(hwc);
105352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
1054e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
1055e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
10561e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
10571e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
105852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
1059d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
106052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1061cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
106252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
1063d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
106452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1065ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1066e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1067e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1068a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1069a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
10706547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
10716547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
10726547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
10736547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
10746547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
107787baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1079841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1080841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
10817cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
10827cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
10837cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
10847cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
10857cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
10867cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1087ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1088ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1089ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1090ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1091ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1092ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1093ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1094ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1095ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1096ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1097e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
109887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1099ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1100ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1101ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1102ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1103ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
11043d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
110687baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
11073d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
11083d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
11163559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
111813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
11293559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1132e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
113392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
113492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
113592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1136e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1137e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
113892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
114092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
114193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
114292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
114392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
114492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
114592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
114692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
114792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1148e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1149e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
115092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
11513ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
115227ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
115327ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
115427ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
115502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1156875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
115702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
115802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
115902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
11609e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
11617adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
116202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
116392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
116492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
116592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
116692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
116792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1168e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
11693ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1170111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
1171e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
117293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
117393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
117493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
117502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
117602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
117702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
117893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
117993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
118093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
118193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
118293997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
118392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
118493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1185db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
118693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
118793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
118893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
118993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
119000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
119100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
119200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
119300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
119400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
11954fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
119693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
119792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
119892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
119992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
120092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
120192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
120292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
120392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1205e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1206cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
120799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1208db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1209b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1210b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
1211b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
1212b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                            new GraphicBufferAlloc());
1213db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
121402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                    int32_t hwcDisplayId = -1;
121599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
121602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
121702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
121802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
121999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1220db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
122102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hwcDisplayId = allocateHwcDisplayId(state.type);
1222db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
1223b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    *mHwc, hwcDisplayId, state.surface,
1224b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    bqProducer, bqConsumer, state.displayName);
1225db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1226db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
1227db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            if (hwcDisplayId >= 0) {
1228db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                                producer = vds;
1229db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            } else {
1230db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                                // There won't be any interaction with HWC for this virtual display,
1231db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                                // so the GLES driver can pass buffers directly to the sink.
1232db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                                producer = state.surface;
1233db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            }
123499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
123599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1236cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1237cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1238cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1239cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
124002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        hwcDisplayId = allocateHwcDisplayId(state.type);
1241cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // for supported (by hwc) displays we provide our
1242cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // own rendering surface
1243b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        dispSurface = new FramebufferSurface(*mHwc, state.type,
1244b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                bqConsumer);
1245b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        producer = bqProducer;
1246cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1247cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1248cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
124999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1250cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
125119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                state.type, hwcDisplayId,
125219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                mHwc->getFormat(hwcDisplayId), state.isSecure,
125305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                display, dispSurface, producer,
125405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1255cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1256cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
12574fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
12588dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1259cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
12601c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        if (state.isVirtualDisplay()) {
12611c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            if (hwcDisplayId >= 0) {
12621c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                mHwc->setVirtualDisplayProperties(hwcDisplayId,
12631c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getWidth(), hw->getHeight(),
12641c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getFormat());
12651c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            }
12661c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        } else {
12677adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
12681c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
126993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
127092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
127192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
12733559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12758430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
12768430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
12778430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
12788430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
12798430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12808430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
12818430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
12828430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12838430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
12848430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
12858430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
12868430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12878430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
12888430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
12898430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12908430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
12918430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
12928430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
12938430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
12948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
12958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
12968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
12978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
12988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
12998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
13008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
130113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
13021eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
13038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
13048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
13058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
13068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
13078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
13088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
13098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
13108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
13118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
13128430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
13138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
13148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
131591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
13168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
13178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
13188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
13198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
13208430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
132191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
132291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
132391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
132491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
132591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
132691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
132791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
132891d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
13298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
133091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
13318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
13328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
13338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
13348430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
13353559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
13363559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
13373559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13391eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
13401eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
13413559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
13423559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
13433559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
13443559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
13453559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
13463559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
13473559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
13483559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
13493559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
13501eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const size_t count = layers.size();
13513559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
13521eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            const sp<Layer>& layer(layers[i]);
13533559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
13543559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
13553559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
13563559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
13573559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
13581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
13591501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
13601501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
13611501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
13620aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
13674fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
13684fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
13694fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
13704fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
13714fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
13724fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
13734fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
13744fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
13754fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
13764fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
13774fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
13784fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
13794b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
13804b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
13814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
13824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
13834fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
13842d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
13852d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
13864fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
139087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
139187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1393841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1394841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
139987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
140313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer = currentLayers[i];
1404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
14061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
140801e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
140987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
141087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
141187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1412ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1413ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1414ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1416ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1417ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1418ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1419ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1420ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1421ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1422ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1424ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1425ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1426ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1427ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1428ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1430ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1431a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1432a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1433a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1434a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1435a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1436a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1437a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1438a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1439a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1440a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1441ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1442ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1443da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
14444125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
14455219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian            Rect bounds(s.transform.transform(layer->computeBounds()));
1446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1447ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1448ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1449ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
14504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
14514fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
14524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
14534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
14542ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                            transparentRegion = tr.transform(s.activeTransparentRegion);
14554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
14564fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
14574fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
1458a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                            transparentRegion.clear();
14594fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
14604fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
14612ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        transparentRegion = s.activeTransparentRegion;
14624fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1463ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1465ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
14664fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1467ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1468ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1469ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1470ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1471ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1475ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1476ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1477ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1478ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1479ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1480ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
14894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1492a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1493ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1494ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1495ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1496ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1497ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1498ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1499ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1500ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1501ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1502ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1503a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1504ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
15054fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
15064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1507ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1508ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
151387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1515ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
15178b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1518a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1521a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1522a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
152587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
152887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
152987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
153092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
15314297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
15324297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
15334297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
153492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
153592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
153687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
153787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
153887baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
154199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
15424fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
15431eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
15441eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
15454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    for (size_t i=0 ; i<count ; i++) {
15461eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const sp<Layer>& layer(layers[i]);
154787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
15481eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
154987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
15504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
15514da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
15523b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1555ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1556ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1557ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1558ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1559ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
156099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1561cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
156287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
15647143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
15657143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
15667143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
15677143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
15687143316af216fa92c31a60d4407b707637382da1Dan Stoza    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
15697143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
15707143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
15717143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
15727143316af216fa92c31a60d4407b707637382da1Dan Stoza
157387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
157487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1575b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
15764297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
15790f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
158029d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
158129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
158229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
15834297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
15850f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
158629d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1587df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
158895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
15890f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
15904297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
159229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
15934297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
15944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
15989c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
1599ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        doComposeSurfaces(hw, dirtyRegion);
1600ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    } else {
1601ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        RenderEngine& engine(getRenderEngine());
16029c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mat4 colorMatrix = mColorMatrix;
16039c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        if (mDaltonize) {
16049c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            colorMatrix = colorMatrix * mDaltonizer();
16059c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        }
16069c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        engine.beginGroup(colorMatrix);
1607ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        doComposeSurfaces(hw, dirtyRegion);
1608ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        engine.endGroup();
1609ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    }
1610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
16119c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
16124297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1613da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1614da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
1615da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
1616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1618cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
162185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
16228630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
16231e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
16241e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1625a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1626d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall    bool hasGlesComposition = hwc.hasGlesComposition(id);
162785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1628875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
1629c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
1630c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock                  hw->getDisplayName().string());
1631c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            return;
1632c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
1633a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1634a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
163585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1636e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1637b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1638b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1639b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
16403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
1641b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
16423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.clearWithColor(0, 0, 0, 0);
1643b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1644766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
1645766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region bounds(hw->getBounds());
1646766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1647766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
1648766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
1649766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
1650766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region letterbox(bounds.subtract(hw->getScissor()));
1651766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1652766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
1653766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            Region region(hw->undefinedRegion.merge(letterbox));
1654766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1655766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
1656766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
1657766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1658b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
165987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1660b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
166155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1662b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1663a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
1664f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1665766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
1666766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
1667f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
1668f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
1669f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            const Rect& bounds(hw->getBounds());
1670766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Rect& scissor(hw->getScissor());
1671f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
1672f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
1673f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
1674f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
16753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1676f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
16773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                const uint32_t height = hw->getHeight();
16783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.setScissor(scissor.left, height - scissor.bottom,
16793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
1680f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
1681f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
168285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
16834b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
168485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
168585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
168685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
16874b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
168813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
168985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
169085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
169185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
169285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
169385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
169413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
16954fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
169685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
169785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
169885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
1699ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
170085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
170185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
17024125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                                && layer->isOpaque(state) && (state.alpha == 0xFF)
170385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1704cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1705cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1706cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1707cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
170885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
170985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
171085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1711cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
171285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1713a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1714da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    case HWC_FRAMEBUFFER_TARGET: {
1715da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // this should not happen as the iterator shouldn't
1716da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // let us get there.
171786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i);
1718da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
1719da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    }
1720cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1721a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
172285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
172385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
172485d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
172585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
172685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
172713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
172885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
172985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
173085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
173185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
173285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
17334b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
17344b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1735f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1736f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
17373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableScissor();
1738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
174155801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
17423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
17433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
1744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1746ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianvoid SurfaceFlinger::addClientLayer(const sp<Client>& client,
1747ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
17486710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
174913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
17501b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
175196f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
1752ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
17534f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
175496f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1755921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1756921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
17576710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    mGraphicBufferProducerList.add(gbc->asBinder());
175896f0819f81293076e652792794a961543e6750d7Mathias Agopian}
175996f0819f81293076e652792794a961543e6750d7Mathias Agopian
17603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
176196f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
176213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
1763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
17646710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        mLayersPendingRemoval.push(layer);
1765076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
17666710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
17693d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1772c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
1773dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1774dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1775dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
17763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
1777edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
178399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17888b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
17898b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
17908b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
17918b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
17928b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
17937c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
1794698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
179528378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1796e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
17972d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
17982d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
17992d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
18002d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
18017c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
18022d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
18032d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
18047c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
18057c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
18067c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
18072d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
18082d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
18092d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
18102d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
18112d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
18122d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
1813e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1814e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1815e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1816e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1817b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1818b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1819e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1820698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1821698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1822d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
1823d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
1824d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
1825d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
1826d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
1827d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
1828d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
1829d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
1830d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            sp<IBinder> binder = s.client->asBinder();
1831d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
1832d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
1833d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
1834d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
1835d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
1836d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
1837d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
1838d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
1839698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
1840386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
184128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
1842386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
184328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
1844698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
1845386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
1846386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
1847386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
18482d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
18492d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
18502d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
18512d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
1852386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
18532d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
1854386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1855386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
1856386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
1857386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
18582d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
18592d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
1860386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
1861386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
1862cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
1863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1866e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
1867e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
18689a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
18699a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
18709a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
18719a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
1872e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
18739a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
18743ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
1875e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1876e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
1877e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
1878e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
1879e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1880e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1881e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1882e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
1883e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
1884e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
1885e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1886e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1887e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
188800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
1889e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
1890e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
1891e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1892e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1893e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
1894e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
1895e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1896e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1897e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
1898e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
1899e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
1900e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1901e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1902e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1903e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1904e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1905e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
1906e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
1907e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
1908e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
1909e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
1910e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
191113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
1912e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
1913e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
1914e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
1915e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
1916e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1917e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1918e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
1919e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1920e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1921e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
1922e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1923e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1924e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1925e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1926e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1927e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1928e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1929e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
1930e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
1931e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1932e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1933e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1934e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
1935e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1936e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1937e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1938e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
1939e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
1940e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1941e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1942e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
1943e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
1944e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1945e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
19464125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if ((what & layer_state_t::eVisibilityChanged) ||
19474125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                (what & layer_state_t::eOpacityChanged)) {
19484125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            // TODO: should we just use an eFlagsChanged for this?
1949e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
1950e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1951e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1952e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
1953e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
1954e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
1955e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1956e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
1957e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
1958e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
1959e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
1960e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
1961e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
1962e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
1963e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
1964e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
1965e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
1966e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
1967e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
1968e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
1969e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
1970e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
19714d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
19720ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
19730ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
19744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
19754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
1976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
19774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
19786e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
1979921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
19806e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
19814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
19826e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
19838b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
19844d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
19854d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
19864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
19874d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
19883165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
19893165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
19904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
19914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
19924d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
1993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
19943165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
19954d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
19964d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
19974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
19984d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
19994d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
20004d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (result == NO_ERROR) {
20056710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        addClientLayer(client, *handle, *gbp, layer);
200696f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
2007edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
20084d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
20124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
20134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
201692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
20228f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2024edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20264d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
20274d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
20284d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
20294d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2030b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
20324d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
20334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
20344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2035edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
20384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
20394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20414d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
20424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2043b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
20444d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2045118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2046118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2047ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
20489a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
20496710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
20506710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
20516710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
20526710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
20536710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
20546710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
20556710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
20569a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
20579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
20589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
20599a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
206013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20626710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
20636710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
2064ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
206513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> l(layer.promote());
2066ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
20676710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
2068e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
2069ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
2070ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
2071ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
2072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2074b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2075b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
207613a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
207701e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
207813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
207913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
208013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
208101e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
208201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2083692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
208401e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
208513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
20864c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
20874c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
208813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
208913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
20902c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
20916547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
20926547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const nsecs_t period =
20936547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
20946547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
209513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
209613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
209713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
209813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
209913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
210013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
210113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
210213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
210313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
210413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
210513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
210613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
210713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
210813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
210913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
211013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
21112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
21122c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
21132c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
21142c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
21152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
21162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
211713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
21182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
21192c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2120c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2121c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2122c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
21232c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
21242c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
21252c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
21262c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
21272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2128c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
21292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
21302c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2131c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2132c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2133c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2134948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2135c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21372c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
21382c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
21392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2140c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2141948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2142948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2143cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2144cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2145cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2146c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
21472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
21482c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
21492c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
21502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
21512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2152b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21552c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
21562c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2157db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2158db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
21592c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2160b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
21612c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
21622c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
21632c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2164b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
21652c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2166db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
21672c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
21682c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mDisplay.get(), mMode);
21699e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
21702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
21712c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2172db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
21732c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2174db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2175b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2176b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2177b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
21782c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2179db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2180b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2181b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2182b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2183b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
218799b49840d309727678b77403d6cc9f920111623fMathias Agopian
2188bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2189bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2190bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2191bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2192bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
219374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2194bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
21969795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
21979795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
21989795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
21999795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
22009795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
22019795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
22029795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
22039795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
22049795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
220574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            result.append(
22069795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
22079795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
22089795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
22099795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
221082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
221182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
221225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
221325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
221425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
221525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
221625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
221774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
221835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
221925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
222025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
222125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
222225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
222382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
222474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
222535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
222682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
222725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
222825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
222925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
223025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
223174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
223235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
223325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2234c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2235c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2236c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2237c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2238c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2239c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2240c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
22421b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
224382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
224474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
224582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
224648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
224782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
224882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
224948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
225082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
225182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
225282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
225382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
225448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2255c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2256c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
225725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
225825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
225925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
226025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
226113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
226274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
226325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
226425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
226525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
226682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
226774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
226882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
226982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
227082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
227182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
227282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
227382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
227448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
22754b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    const nsecs_t period =
22764b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
227786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
22784b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
22794b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2280d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
22814b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
22824b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
22834b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const size_t count = currentLayers.size();
22844b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        for (size_t i=0 ; i<count ; i++) {
228513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
22864b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2287d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
22884b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
228982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
229082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
229182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2292ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
229325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2294c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
229525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
229625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
229725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
229825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
229925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
230025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
230125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
230225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
230325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
230425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
230513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
230625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2307d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
230825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
230925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
23104b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2311d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
231225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
231325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
23146547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
23156547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
23166547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
23176547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
23186547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const size_t count = drawingLayers.size();
23196547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
23206547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        const sp<Layer>& layer(drawingLayers[i]);
23216547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
23226547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
23236547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
23246547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
23256547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
23266547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
23274803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
23284803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
23294803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
23304803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
23314803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
23324803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
23334803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23344803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
23354803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
23364803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23374803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
23384803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
23394803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
23404803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
23414803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
23424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
23434803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
234474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
234574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
234682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
23473e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
23483e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
23493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
23503e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
23513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
23523e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
23533e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
23543e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
23553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
235682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
235782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
235882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
235982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
236082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
236182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2362bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
236382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
23644803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
23654803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
23663e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
23673e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
23684803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
23693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
23704803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
23714803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
23724803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
23734803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
23744803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
23753e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
2376ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
23773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
2378ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
2379ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
2380ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
238141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
238241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
238341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
238424cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
238524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
238641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS,
238741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY));
238841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
238941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
23904803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
239182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
239282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
239382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
239482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
23953e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
239686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Visible layers (count = %zu)\n", count);
23973e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
239882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
239913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
24003e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
240182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2402bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
240382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
24045f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
24055f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
24065f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
24073e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
240886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
24093e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
24105f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
24115f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
241274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
24135f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
24145f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
24155f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
241682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
241782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
24181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
24193e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
242074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
24213e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
24221b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2423888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
24244297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
2425ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
24263e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
24273e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
24283e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
24293e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
24303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
2431ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
2432ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
2433875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
24349795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
24354297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
24362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
24372c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
243874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
243982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
244082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2441c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
244282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
244382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
2444ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
2445ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
2446ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
244782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
244882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2449c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2450b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2451b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2452ed985574148a938bc3af24442eead313cc62521cMathias Agopian            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
2453ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
245482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
245574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
245682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
245782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
245874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
245982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
246082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
246182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
246282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
246382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
246474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
246582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
246682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
246782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
246882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
24693e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
247074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
24713e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
247274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  h/w composer %s and %s\n",
247382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
24749c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    (mDebugDisableHWC || mDebugRegion || mDaltonize
24759c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            || mHasColorMatrix) ? "disabled" : "enabled");
247674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
247782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
247882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
247982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
248082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
248182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
248282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
2483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
248513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
248648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
2487db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
248848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
248948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
249048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
249148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
249248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
249348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
249448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
249548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
249648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
249748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
249848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
249948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
250048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
2501cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
2502cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
250363f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
250463f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
250563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
250663f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
250763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
250863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
250963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
251063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
251163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
251224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
251363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
251463f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
251563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
251663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
251763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
251863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
251963f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
252063f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2526041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
2527698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
2529d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
2530d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
25312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
2532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2536a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
253799b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
253899b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2539e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2540375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2541375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
25431b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
25441b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
25451b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
25461b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
25471b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
25481b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
25491b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
25501b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
255199b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
255299b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2553e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
25541b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
25551b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
25561b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
25571b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
25601b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2563b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
256499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2565375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2566375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2567375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2568e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2569375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
257401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
257535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
258053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
258153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
258453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2585cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2586cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2587cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2588e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2589e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2590e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2591e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2592cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
25944d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
25954d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
25964d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
25974d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
259853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
259953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
260053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
260153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
260253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
260353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2604a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2605a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2606a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2607a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2608a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2609a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
261101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2614b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
261512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
26194297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
26204297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2621ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
2622ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
2623ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
2624ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
2625ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
2626ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
2627ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 1: mDaltonizer.setType(Daltonizer::protanomaly);   break;
2628ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break;
2629ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 3: mDaltonizer.setType(Daltonizer::tritanomaly);   break;
2630ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2631ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
2632ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::correction);
2633ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
2634ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::simulation);
2635ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2636ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                mDaltonize = n > 0;
2637ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
2638ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
26399c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
26409c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
26419c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
26429c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
26439c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
26449c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                mHasColorMatrix = n ? 1 : 0;
26459c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
26469c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
26479c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
26489c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
2649794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
2650794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      for (size_t j = 0; j < 4; j++) {
2651794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                          mColorMatrix[i][j] = data.readFloat();
2652794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      }
26539c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
26549c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
26559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
26569c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
26579c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
26589c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
26599c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
2660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2661f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
2662f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
2663f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
2664645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
2665645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
2666f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
2667f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
2668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
267353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
267487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
267599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
267653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
267753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
267859119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
26792a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
26802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
268159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
26822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
26832ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
26842ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
2685b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
2686b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
2687b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
2688b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
26892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
26902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
2691b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
2692b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
2693b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
2694b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
2695b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
2696b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
2697b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
2698b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
2699b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
2700b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
2701b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
2702b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
2703b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
2704b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
27052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
27062ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
27072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
27082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
27092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
2710b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
27112ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
27122ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
27132ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
27142ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
27162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
27172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
27182ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
27192ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27202ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
2721b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
2722b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
2723b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
27242ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
27252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
2726c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
27272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
27282ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
27292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
27302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
2731b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
2732b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
2733b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
2734b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
27352ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
27362ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
27372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
2738b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
2739b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
2740b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
27412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
27422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
27432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
2744c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
27452ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
27462ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
2748b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
27492ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
27502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
27512ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
2752b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
2753b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
2754b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
2755b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
2756c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng            result = impl->asBinder()->transact(code, data[0], reply);
27572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
2758b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
27592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
27602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
27612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
27622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
2764b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
2765b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
2766b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
2767b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
2768b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitRequested(false)
2769b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
2770b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
2771b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
27722ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
27732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
27742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
27752ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
27762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
27772ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
27782ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
2779b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
27802ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
2781aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
27822ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
2783b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
2784b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
2785b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
27862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
27872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
27882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
27892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27902ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
27912a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
27922a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
2793c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
2794c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
2795c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform) {
27962a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
27972a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
27982a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
27992a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
28002a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
28012a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
28022a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
28035ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
28045ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
28055ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
28065ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    if (!producer->asBinder()->localBinder()) {
28075ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        Mutex::Autolock _l(mStateLock);
28085ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        sp<const DisplayDevice> hw(getDisplayDevice(display));
28095ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        if (hw->getSecureLayerVisible()) {
28105ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            ALOGW("FB is protected: PERMISSION_DENIED");
28115ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            return PERMISSION_DENIED;
28125ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        }
28135ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    }
28145ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
28152a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
28162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
28172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
28182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
2819c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
28202a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
28212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
2822c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
28232a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
28242a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
28252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
28262a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
28272a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
2828c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
2829c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                uint32_t minLayerZ, uint32_t maxLayerZ,
2830c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                bool useIdentityTransform)
28312a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
2832c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
28332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
2834c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
28352a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              result(PERMISSION_DENIED)
28362a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
28372a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
28382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
28392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
28402a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
28412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
28422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
28432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
2844c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
2845c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
2846c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    useIdentityTransform);
28472ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
28482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
28492a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
28502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
28512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
28529eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // make sure to process transactions before screenshots -- a transaction
28539eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // might already be pending but scheduled for VSYNC; this guarantees we
28549eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // will handle it before the screenshot. When VSYNC finally arrives
28559eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // the scheduled transaction will be a no-op. If no transactions are
28569eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // scheduled at this time, this will end-up being a no-op as well.
28579eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    mEventQueue.invalidateTransactionNow();
28589eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
28592ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
28602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
28612ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
28622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
28632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
28642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
28652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
28662a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
28672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
2868c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
2869c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            useIdentityTransform);
28702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
28712ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
28722a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
28732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
28742a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
28752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
2876118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2877118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2878180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2879180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
2880180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
2881c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
2882180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ,
2883c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool yswap, bool useIdentityTransform)
2884180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
2885180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
28863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
2887180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2888180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
2889180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
2890180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
2891180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const bool filtering = reqWidth != hw_w || reqWidth != hw_h;
2892180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2893c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
2894c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
2895c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
2896c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
2897c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
2898c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
2899c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
2900c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
2901c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
2902c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
2903c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
2904be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.right > hw_w) {
2905be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
2906c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
2907c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
2908c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
2909c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
2910be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza    if (sourceCrop.bottom > hw_h) {
2911be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
2912c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
2913c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
2914180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
29153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
2916180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2917180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
2918c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, hw_h, yswap);
29193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
2920180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2921180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
29223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
2923180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2924180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const LayerVector& layers( mDrawingState.layersSortedByZ );
2925180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const size_t count = layers.size();
2926180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
2927180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<Layer>& layer(layers[i]);
29281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
2929180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
2930180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
2931180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
2932180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
2933c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    layer->draw(hw, useIdentityTransform);
2934180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
2935180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
2936180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
2937180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
2938180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
2939180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2940180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // compositionComplete is needed for older driver
2941180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    hw->compositionComplete();
2942931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
2943180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
2944180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2945180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
29462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
29472a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
29482a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
2949c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
2950c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
2951c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform)
295274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
2953fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
2954fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
2955180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
2956180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
2957180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
2958180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2959180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
2960180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
2961180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
2962180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
2963180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
2964180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
2965180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
2966180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
2967180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
29680aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
29690aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
297083cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
29710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
297274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
29730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    status_t result = NO_ERROR;
29740aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) {
29753ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
29763ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
29772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
29780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
29790aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
29804ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
29810aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
29820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
29832a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
29840aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
29850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
29860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
29870aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
29880aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
29890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
29900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
29910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
29920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
29930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
29940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
29950aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
29963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
29973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
29983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
29993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
30000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
30010aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
30020aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
30030aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3004c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                        renderScreenImplLocked(hw, sourceCrop, reqWidth, reqHeight,
3005c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                                minLayerZ, maxLayerZ, true, useIdentityTransform);
3006d555684cb36dfb959694db76962e570184f98838Mathias Agopian
30072d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        // Create a sync point and wait on it, so we know the buffer is
30082d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        // ready before we pass it along.  We can't trivially call glFlush(),
30092d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        // so we use a wait flag instead.
30102d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        // TODO: pass a sync fd to queueBuffer() and let the consumer wait.
30112d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
30122d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
30132d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
30142d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
30152d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            EGLint eglErr = eglGetError();
30162d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
30172d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            if (result == EGL_TIMEOUT_EXPIRED_KHR) {
30182d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                                ALOGW("captureScreen: fence wait timed out");
30192d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
30202d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                                ALOGW_IF(eglErr != EGL_SUCCESS,
30212d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                                        "captureScreen: error waiting on EGL fence: %#x", eglErr);
30222d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
30232d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        } else {
30242d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
30252d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            // not fatal
30262d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
30272d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden
3028d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3029d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3030d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3031d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3032d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3033d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3034d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3035d555684cb36dfb959694db76962e570184f98838Mathias Agopian
30360aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
30370aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
30380aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
30390aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
30400aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
30410aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
30420aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
30430aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
304474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
30450aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                window->queueBuffer(window, buffer, -1);
304674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
30470aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
30480aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
304974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
30500aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
305174c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
305274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
305374c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
305474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
305574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3056d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3057d555684cb36dfb959694db76962e570184f98838Mathias Agopian        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
3058fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3059d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3060d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3061d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3062fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3063fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3064fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3065fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3066fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3067fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
3068fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const LayerVector& layers( mDrawingState.layersSortedByZ );
3069fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const size_t count = layers.size();
3070fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
3071fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const sp<Layer>& layer(layers[i]);
3072fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
3073fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
3074fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
3075fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
307686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x",
3077fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
3078fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            i, layer->getName().string(), state.layerStack, state.z,
3079fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
3080fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3081fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3082fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian}
3083fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
30841b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
30851b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3086921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
3087921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3088921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3089921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
309013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : SortedVector<sp<Layer> >(rhs) {
3091921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3092921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3093921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
3094921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
3095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3096be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
309713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
309813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
3099be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
31001eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t ls = l->getCurrentState().layerStack;
31011eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rs = r->getCurrentState().layerStack;
3102be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
3103be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
3104be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
31051eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t lz = l->getCurrentState().z;
31061eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rz = r->getCurrentState().z;
3107be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
3108be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
3109be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
3110be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
3111921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3112921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3113921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
3114921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
31153ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
31163ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    : type(DisplayDevice::DISPLAY_ID_INVALID) {
3117e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
3118e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
31193ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
312001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0) {
3121da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
3122da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
3123b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
31247303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3125b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
312696f0819f81293076e652792794a961543e6750d7Mathias Agopian
3127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
31283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
31293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
31303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
31313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
31323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
31333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
31343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
31353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
31363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3137