SurfaceFlinger.cpp revision 784421160727c434c2a2897ed3345445fcc30f75
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <sys/types.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
2363f165fd6b86d04be94d4023e845e98560504a96Keun young Park#include <dlfcn.h>
2486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann#include <inttypes.h>
25b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall#include <stdatomic.h>
26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
27921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <EGL/egl.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/log.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IServiceManager.h>
347303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian#include <binder/MemoryHeapBase.h>
3599b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h>
367303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
37c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
3867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar#include <ui/DisplayStatInfo.h>
39c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
40921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <gui/BitTube.h>
411a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/BufferQueue.h>
424803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <gui/GuiConfig.h>
431a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/IDisplayEventConnection.h>
44e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
45392edd88cb63d71a21a86a02cf9c56ac97637128Jamie Gennis#include <gui/GraphicBufferAlloc.h>
46921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
47921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/GraphicBufferAllocator.h>
48921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <ui/PixelFormat.h>
494803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#include <ui/UiConfig.h>
50d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
51cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian#include <utils/misc.h>
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h>
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h>
551c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h>
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
57921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <private/android_filesystem_config.h>
58ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h>
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
603e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Client.h"
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h"
623e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian#include "Colorizer.h"
6390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include "DdmConnection.h"
640f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
65faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis#include "DispSync.h"
66d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis#include "EventControlThread.h"
67d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h"
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerDim.h"
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h"
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
72a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
73a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "DisplayHardware/HWComposer.h"
7499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/VirtualDisplaySurface.h"
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
76ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include "Effects/Daltonizer.h"
77ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
78875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
79ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian#include <cutils/compiler.h>
80875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DISPLAY_COUNT       1
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
83fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian/*
84fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
85fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian * black pixels.
86fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian */
87fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian#define DEBUG_SCREENSHOTS   false
88fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
89ca08833d5ea99130797e10ad68a651b50e99da74Mathias AgopianEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
90ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
92faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
93faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This is the phase offset in nanoseconds of the software vsync event
94faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// relative to the vsync event reported by HWComposer.  The software vsync
95faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// event is when SurfaceFlinger and Choreographer-based applications run each
96faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// frame.
97faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
98faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// This phase offset allows adjustment of the minimum latency from application
99faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// wake-up (by Choregographer) time to the time at which the resulting window
100faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// image is displayed.  This value may be either positive (after the HW vsync)
101faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// or negative (before the HW vsync).  Setting it to 0 will result in a
102faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// minimum latency of two vsync periods because the app and SurfaceFlinger
103faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will run just after the HW vsync.  Setting it to a positive number will
104faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// result in the minimum latency being:
105faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
106faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
107faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis//
108faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// Note that reducing this latency makes it more likely for the applications
109faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// to not have their window content image ready in time.  When this happens
110faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// the latency will end up being an additional vsync period, and animations
111faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// will hiccup.  Therefore, this latency should be tuned somewhat
112faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis// conservatively (or at least with awareness of the trade-off being made).
113faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisstatic const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
114faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
1150a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis// This is the phase offset at which SurfaceFlinger's composition runs.
1160a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennisstatic const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
1170a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12099b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sHardwareTest("android.permission.HARDWARE_TEST");
12199b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
12299b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
12399b49840d309727678b77403d6cc9f920111623fMathias Agopianconst String16 sDump("android.permission.DUMP");
12499b49840d309727678b77403d6cc9f920111623fMathias Agopian
12599b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------
12699b49840d309727678b77403d6cc9f920111623fMathias Agopian
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::SurfaceFlinger()
1284f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    :   BnSurfaceComposer(),
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mTransactionFlags(0),
1302d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mTransactionPending(false),
1312d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        mAnimTransactionPending(false),
132076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved(false),
13352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        mRepaintEverything(0),
134875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        mRenderEngine(NULL),
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mBootTime(systemTime()),
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mVisibleRegionsDirty(false),
137a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwWorkListDirty(false),
1384b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending(false),
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mDebugRegion(0),
1408afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian        mDebugDDMS(0),
14173d3ba9e50be1014aa21ec4bbdc874be394accb4Mathias Agopian        mDebugDisableHWC(0),
142a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian        mDebugDisableTransformHint(0),
1439795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInSwapBuffers(0),
1449795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastSwapBufferTime(0),
1459795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mDebugInTransaction(0),
1469795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        mLastTransactionTime(0),
147ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mBootFinished(false),
148faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled(false),
149948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable(false),
1509c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mDaltonize(false),
1519c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mHasColorMatrix(false)
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
153a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("SurfaceFlinger is starting");
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // debugging stuff...
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1578afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
158b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
15950210b9a8d19cb90fc283d8d99e46cd34ac17d2eMathias Agopian    mGpuToCpuSupported = !atoi(value);
160b4b1730abb7824dc084468c4942f010d94a7e039Mathias Agopian
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    property_get("debug.sf.showupdates", value, "0");
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDebugRegion = atoi(value);
1638afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian
1648afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    property_get("debug.sf.ddms", value, "0");
1658afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    mDebugDDMS = atoi(value);
1668afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    if (mDebugDDMS) {
16763f165fd6b86d04be94d4023e845e98560504a96Keun young Park        if (!startDdmConnection()) {
16863f165fd6b86d04be94d4023e845e98560504a96Keun young Park            // start failed, and DDMS debugging not enabled
16963f165fd6b86d04be94d4023e845e98560504a96Keun young Park            mDebugDDMS = 0;
17063f165fd6b86d04be94d4023e845e98560504a96Keun young Park        }
1718afb7e39a83a3e31170612d562eb08508e328388Mathias Agopian    }
172c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugRegion, "showupdates enabled");
173c1d359d42b753fcc2426d66a0f782f7c300893bcMathias Agopian    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::onFirstRef()
17799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
17899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.init(this);
17999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
18099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurfaceFlinger::~SurfaceFlinger()
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
183a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
184a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
185a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    eglTerminate(display);
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
188c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
18999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian{
19099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // the window manager died on us. prepare its eulogy.
19199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // restore initial conditions (default device unblank, etc)
19313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
19499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
19599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    // restart the boot-animation
196a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
19799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
19899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1997e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopiansp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
20196f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<ISurfaceComposerClient> bclient;
20296f0819f81293076e652792794a961543e6750d7Mathias Agopian    sp<Client> client(new Client(this));
20396f0819f81293076e652792794a961543e6750d7Mathias Agopian    status_t err = client->initCheck();
20496f0819f81293076e652792794a961543e6750d7Mathias Agopian    if (err == NO_ERROR) {
20596f0819f81293076e652792794a961543e6750d7Mathias Agopian        bclient = client;
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return bclient;
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennissp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
211dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool secure)
212e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
213e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    class DisplayToken : public BBinder {
214e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        sp<SurfaceFlinger> flinger;
215e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        virtual ~DisplayToken() {
216e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             // no more references, this display must be terminated
217e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             Mutex::Autolock _l(flinger->mStateLock);
218e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->mCurrentState.displays.removeItem(this);
219e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian             flinger->setTransactionFlags(eDisplayTransactionNeeded);
220e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian         }
221e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     public:
222e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        DisplayToken(const sp<SurfaceFlinger>& flinger)
223e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            : flinger(flinger) {
224e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
225e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    };
226e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
227e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    sp<BBinder> token = new DisplayToken(this);
228e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
229e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    Mutex::Autolock _l(mStateLock);
2303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL);
2318dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    info.displayName = displayName;
232dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis    info.isSecure = secure;
233e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    mCurrentState.displays.add(token, info);
234e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
235e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return token;
236e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
237e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2386c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hallvoid SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
2396c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    Mutex::Autolock _l(mStateLock);
2406c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2416c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    ssize_t idx = mCurrentState.displays.indexOfKey(display);
2426c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (idx < 0) {
2436c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGW("destroyDisplay: invalid display token");
2446c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2456c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2466c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2476c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
2486c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    if (!info.isVirtualDisplay()) {
2496c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        ALOGE("destroyDisplay called for non-virtual display");
2506c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        return;
2516c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    }
2526c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
2536c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    mCurrentState.displays.removeItemsAt(idx);
2546c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    setTransactionFlags(eDisplayTransactionNeeded);
2556c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall}
2566c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall
257692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hallvoid SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
258692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    ALOGW_IF(mBuiltinDisplays[type],
259692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            "Overwriting display token for display type %d", type);
260692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mBuiltinDisplays[type] = new BBinder();
261692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    DisplayDeviceState info(type);
262692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    // All non-virtual displays are currently considered secure.
263692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    info.isSecure = true;
264692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    mCurrentState.displays.add(mBuiltinDisplays[type], info);
265692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall}
266692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
267e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopiansp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
2689e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
269e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
270e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        return NULL;
271e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
272692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    return mBuiltinDisplays[id];
273e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
274e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2759a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennissp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
2769a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
2779a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
2789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    return gba;
2799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis}
280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::bootFinished()
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t now = systemTime();
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const nsecs_t duration = now - mBootTime;
285a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
2863330b203039dea366d4981db1408a460134b2d2cMathias Agopian    mBootFinished = true;
2871f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2881f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // wait patiently for the window manager death
2891f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    const String16 name("window");
2901f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    sp<IBinder> window(defaultServiceManager()->getService(name));
2911f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (window != 0) {
292921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
2931f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
2941f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
2951f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    // stop boot animation
296a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // formerly we would just kill the process, but we now ask it to exit so it
297a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // can choose where to stop the animation.
298a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "1");
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
302921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageDestroyGLTexture : public MessageBase {
3033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        RenderEngine& engine;
3043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        uint32_t texture;
305921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    public:
3063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
3073f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            : engine(engine), texture(texture) {
308921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
309921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        virtual bool handler() {
3103f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.deleteTextures(1, &texture);
311921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            return true;
312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        }
313921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    };
3143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
315921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
316921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
317faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisclass DispSyncSource : public VSyncSource, private DispSync::Callback {
318faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennispublic:
3195167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
3205167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden        const char* label) :
3210a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mValue(0),
3220a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mPhaseOffset(phaseOffset),
3230a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mTraceVsync(traceVsync),
3245167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            mVsyncOnLabel(String8::format("VsyncOn-%s", label)),
3255167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            mVsyncEventLabel(String8::format("VSYNC-%s", label)),
3260a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            mDispSync(dispSync) {}
327faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
328faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual ~DispSyncSource() {}
329faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
330faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setVSyncEnabled(bool enable) {
331faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        // Do NOT lock the mutex here so as to avoid any mutex ordering issues
332faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        // with locking it in the onDispSyncEvent callback.
333faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (enable) {
3340a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            status_t err = mDispSync->addEventListener(mPhaseOffset,
335faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
336faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
337faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error registering vsync callback: %s (%d)",
338faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
339faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3405167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 1);
341faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
342faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            status_t err = mDispSync->removeEventListener(
343faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                    static_cast<DispSync::Callback*>(this));
344faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            if (err != NO_ERROR) {
345faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                ALOGE("error unregistering vsync callback: %s (%d)",
346faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis                        strerror(-err), err);
347faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            }
3485167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            //ATRACE_INT(mVsyncOnLabel.string(), 0);
349faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
350faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
351faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        Mutex::Autolock lock(mMutex);
354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mCallback = callback;
355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
357faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisprivate:
358faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    virtual void onDispSyncEvent(nsecs_t when) {
359faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        sp<VSyncSource::Callback> callback;
360faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        {
361faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            Mutex::Autolock lock(mMutex);
362faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback = mCallback;
363a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
3640a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            if (mTraceVsync) {
3650a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis                mValue = (mValue + 1) % 2;
3665167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden                ATRACE_INT(mVsyncEventLabel.string(), mValue);
3670a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis            }
368faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
369faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
370faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (callback != NULL) {
371faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            callback->onVSyncEvent(when);
372faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
373faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
374faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
375faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    int mValue;
376faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
3770a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const nsecs_t mPhaseOffset;
3780a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    const bool mTraceVsync;
3795167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncOnLabel;
3805167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    const String8 mVsyncEventLabel;
3810a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis
382faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    DispSync* mDispSync;
383faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<VSyncSource::Callback> mCallback;
384faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex mMutex;
385faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis};
386faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
387faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::init() {
388a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ALOGI(  "SurfaceFlinger's main thread ready to run. "
389a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian            "Initializing graphics H/W...");
390a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
391b65f32ebe2c86869b07ac1c986660dfb2187b7d3Jesse Hall    status_t err;
392692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    Mutex::Autolock _l(mStateLock);
393692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
394b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // initialize EGL for the default display
39534a09ba1efd706323a15633da5044b352988eb5fJesse Hall    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
39634a09ba1efd706323a15633da5044b352988eb5fJesse Hall    eglInitialize(mEGLDisplay, NULL, NULL);
397a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
398b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // Initialize the H/W composer object.  There may or may not be an
399b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    // actual hardware composer underneath.
400b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden    mHwc = new HWComposer(this,
401b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            *static_cast<HWComposer::EventHandler *>(this));
402b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden
403875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // get a RenderEngine for the given display / config (can't fail)
40405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
405875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian
406875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    // retrieve the EGL context that was selected/created
407875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mEGLContext = mRenderEngine->getEGLContext();
408a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
409da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
410da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            "couldn't create EGLContext");
411da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
412cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian    // initialize our non-virtual displays
4139e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
414f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
415f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        // set-up the displays that are already connected
4169e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
417dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            // All non-virtual displays are currently considered secure.
418dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis            bool isSecure = true;
419692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked(type);
420692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            wp<IBinder> token = mBuiltinDisplays[i];
421692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall
422b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<IGraphicBufferProducer> producer;
423b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<IGraphicBufferConsumer> consumer;
424b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            BufferQueue::createBufferQueue(&producer, &consumer,
425b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    new GraphicBufferAlloc());
426b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza
427b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
428b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    consumer);
42919e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall            int32_t hwcId = allocateHwcDisplayId(type);
430f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            sp<DisplayDevice> hw = new DisplayDevice(this,
43119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
432b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    fbs, producer,
43305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                    mRenderEngine->getEGLConfig());
434f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            if (i > DisplayDevice::DISPLAY_PRIMARY) {
435c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden                // FIXME: currently we don't get blank/unblank requests
436f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // for displays other than the main display, so we always
437f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian                // assume a connected display is unblanked.
43886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann                ALOGD("marking display %zu as acquired/unblanked", i);
4392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                hw->setPowerMode(HWC_POWER_MODE_NORMAL);
440f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            }
441f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian            mDisplays.add(token, hw);
442f5a33928349bebc8eebc9f466618997e98c24e68Mathias Agopian        }
443e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
444cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
445a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // make the GLContext current so that we can create textures when creating Layers
446a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    // (which may happens before we render something)
447a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
448a6bb107434ad36739c21e1f72ac8d0107808a7b9Mathias Agopian
449028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian    // start the EventThread
4500a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4515167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            vsyncPhaseOffsetNs, true, "app");
452faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mEventThread = new EventThread(vsyncSrc);
4530a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
4545167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden            sfVsyncPhaseOffsetNs, true, "sf");
4550a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    mSFEventThread = new EventThread(sfVsyncSrc);
4560a645cc5a935e67a8d1effc7679a838160b971d8Jamie Gennis    mEventQueue.setEventThread(mSFEventThread);
457028508cad5ef63ef9fbd42c14e76658e4fd9ebf2Mathias Agopian
458d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread = new EventControlThread(this);
459d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
460d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
461faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    // set a fake vsync period if there is no HWComposer
462faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mHwc->initCheck() != NO_ERROR) {
463faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.setPeriod(16666667);
464faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
465faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
46692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    // initialize our drawing state
46792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    mDrawingState = mCurrentState;
4688630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
46913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    // set initial conditions (e.g. unblank default device)
47013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    initializeDisplays();
47113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
472a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian    // start boot animation
473a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    startBootAnim();
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
4779e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ?
4783ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian            type : mHwc->allocateDisplayId();
4793ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian}
4803ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
481a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopianvoid SurfaceFlinger::startBootAnim() {
482a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    // start boot animation
483a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("service.bootanim.exit", "0");
484a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian    property_set("ctl.start", "bootanim");
485a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian}
486a67e418e1fda219f6cc0a7e420bcf5cc4f9fe710Mathias Agopian
487875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxTextureSize() const {
488875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxTextureSize();
489a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
490a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
491875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiansize_t SurfaceFlinger::getMaxViewportDims() const {
492875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    return mRenderEngine->getMaxViewportDims();
493a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
494a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
496d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
497582270d69db94286a248bd829f1ae6f910d45124Jamie Gennisbool SurfaceFlinger::authenticateSurfaceTexture(
4982adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        const sp<IGraphicBufferProducer>& bufferProducer) const {
499134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    Mutex::Autolock _l(mStateLock);
5002adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    sp<IBinder> surfaceTextureBinder(bufferProducer->asBinder());
5016710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
502134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis}
503134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis
5047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stozastatus_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
5057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        Vector<DisplayInfo>* configs) {
5067f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    if (configs == NULL) {
5077f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        return BAD_VALUE;
5087f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    }
5097f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
510692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    int32_t type = NAME_NOT_FOUND;
5119e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
512692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (display == mBuiltinDisplays[i]) {
5131604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            type = i;
5141604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian            break;
5151604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5161604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    }
5171604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5181604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian    if (type < 0) {
5191604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        return type;
520c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
5218b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
5228b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    // TODO: Not sure if display density should handled by SF any longer
5238b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    class Density {
5248b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getDensityFromProperty(char const* propName) {
5258b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            char property[PROPERTY_VALUE_MAX];
5268b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            int density = 0;
5278b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            if (property_get(propName, property, NULL) > 0) {
5288b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian                density = atoi(property);
5298b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            }
5308b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return density;
5318b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        }
5328b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    public:
5338b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getEmuDensity() {
5348b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("qemu.sf.lcd_density"); }
5358b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian        static int getBuildDensity()  {
5368b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian            return getDensityFromProperty("ro.sf.lcd_density"); }
5378b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    };
5381604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian
5397f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    configs->clear();
5407f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5417f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    const Vector<HWComposer::DisplayConfig>& hwConfigs =
5427f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            getHwComposer().getConfigs(type);
5437f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    for (size_t c = 0; c < hwConfigs.size(); ++c) {
5447f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        const HWComposer::DisplayConfig& hwConfig = hwConfigs[c];
5457f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        DisplayInfo info = DisplayInfo();
5467f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5477f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        float xdpi = hwConfig.xdpi;
5487f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        float ydpi = hwConfig.ydpi;
5497f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5507f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        if (type == DisplayDevice::DISPLAY_PRIMARY) {
5517f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // The density of the device is provided by a build property
5527f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            float density = Density::getBuildDensity() / 160.0f;
5537f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (density == 0) {
5547f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // the build doesn't provide a density -- this is wrong!
5557f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // use xdpi instead
5567f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                ALOGE("ro.sf.lcd_density must be defined as a build property");
5577f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density = xdpi / 160.0f;
5587f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
5597f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            if (Density::getEmuDensity()) {
5607f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                // if "qemu.sf.lcd_density" is specified, it overrides everything
5617f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                xdpi = ydpi = density = Density::getEmuDensity();
5627f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza                density /= 160.0f;
5637f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            }
5647f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = density;
5657f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5667f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: this needs to go away (currently needed only by webkit)
5677f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
5687f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = hw->getOrientation();
5697f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        } else {
5707f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            // TODO: where should this value come from?
5717f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            static const int TV_DENSITY = 213;
5727f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.density = TV_DENSITY / 160.0f;
5737f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza            info.orientation = 0;
5741604f777d11c40daae8ec91d8ea75625996bfbacMathias Agopian        }
5757f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5767f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.w = hwConfig.width;
5777f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.h = hwConfig.height;
5787f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.xdpi = xdpi;
5797f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.ydpi = ydpi;
5807f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.fps = float(1e9 / hwConfig.refresh);
58191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
58291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden
58391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // This is how far in advance a buffer must be queued for
58491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // presentation at a given time.  If you want a buffer to appear
58591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // on the screen at time N, you must submit the buffer before
58691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // (N - presentationDeadline).
58791b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
58891b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // Normally it's one full refresh period (to give SF a chance to
58991b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // latch the buffer), but this can be reduced by configuring a
59091b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // DispSync offset.  Any additional delays introduced by the hardware
59191b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // composer or panel must be accounted for here.
59291b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        //
59391b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // We add an additional 1ms to allow for processing time and
59491b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        // differences between the ideal and actual refresh rate.
59591b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden        info.presentationDeadline =
59691b2ca8562763c981c4ce93148db80adb51d0cb6Andy McFadden                hwConfig.refresh - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
5977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
5987f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        // All non-virtual displays are currently considered secure.
5997f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        info.secure = true;
6007f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza
6017f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza        configs->push_back(info);
6028b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian    }
6038b736f138cfd9b239a2c7073347a13c489534ae1Mathias Agopian
6047f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    return NO_ERROR;
6057f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
606dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
60767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnarstatus_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& display,
60867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        DisplayStatInfo* stats) {
60967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    if (stats == NULL) {
61067d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar        return BAD_VALUE;
61167d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    }
61267d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
61367d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    // FIXME for now we always return stats for the primary display
61467d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    memset(stats, 0, sizeof(*stats));
61567d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
61667d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
61767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar    return NO_ERROR;
61867d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar}
61967d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar
6206c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
6216c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    return getDisplayDevice(display)->getActiveConfig();
6227f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza}
623dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
6246c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
6256c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
6266c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine          this);
6276c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int32_t type = hw->getDisplayType();
6286c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    int currentMode = hw->getActiveConfig();
6296c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6306c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (mode == currentMode) {
6316c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
6326c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6336c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6346c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6356c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
6366c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        ALOGW("Trying to set config for virtual display");
6376c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        return;
6386c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    }
6396c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6406c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    hw->setActiveConfig(mode);
6416c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    getHwComposer().setActiveConfig(type, mode);
6426c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
6436c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
6446c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinestatus_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
6456c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    class MessageSetActiveConfig: public MessageBase {
6466c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        SurfaceFlinger& mFlinger;
6476c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        sp<IBinder> mDisplay;
6486c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        int mMode;
6496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    public:
6506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
6516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                               int mode) :
6526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
6536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        virtual bool handler() {
6547306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            Vector<DisplayInfo> configs;
6557306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            mFlinger.getDisplayConfigs(mDisplay, &configs);
656784421160727c434c2a2897ed3345445fcc30f75Jesse Hall            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
6579ae79d869a37633fa956a4f16f3fa45b23c189f1Michael Lentine                ALOGE("Attempt to set active config = %d for display with %zu configs",
6587306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, configs.size());
6597306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine            }
6606c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
6616c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            if (hw == NULL) {
6626c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGE("Attempt to set active config = %d for null display %p",
6637306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
6646c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
6656c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                ALOGW("Attempt to set active config = %d for virtual display",
6666c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                        mMode);
6676c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            } else {
6686c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine                mFlinger.setActiveConfigInternal(hw, mMode);
6696c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            }
6706c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine            return true;
6716c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        }
6726c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    };
6736c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
6746c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    postMessageSync(msg);
675888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    return NO_ERROR;
676c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
677c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian
678d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::clearAnimationFrameStats() {
679d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
680d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
681d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
682d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
683d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
684d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
685d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    Mutex::Autolock _l(mStateLock);
686d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.getStats(outStats);
687d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
688d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
689d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
690d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ----------------------------------------------------------------------------
691d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
692d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiansp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
6938aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian    return mEventThread->createEventConnection();
694bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian}
695bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
69799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
69899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::waitForEvent() {
69999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.waitMessage();
70099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
70199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
70299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalTransaction() {
70399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
70499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
70599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
70699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalLayerUpdate() {
70799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.invalidate();
70899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
70999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
71099ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianvoid SurfaceFlinger::signalRefresh() {
71199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    mEventQueue.refresh();
71299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
71399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
71499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
715c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
71699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return mEventQueue.postMessage(msg, reltime);
71799ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
71899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
71999ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopianstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
720c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        nsecs_t reltime, uint32_t /* flags */) {
72199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    status_t res = mEventQueue.postMessage(msg, reltime);
72299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    if (res == NO_ERROR) {
72399ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        msg->wait();
72499ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    }
72599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    return res;
72699ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7284f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopianvoid SurfaceFlinger::run() {
7294f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    do {
7304f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian        waitForEvent();
7314f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian    } while (true);
73299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian}
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
734faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::enableHardwareVsync() {
735faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
736948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
737faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
738d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
739d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
740faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
74143601a2dc320a271ff8c3765ff61414a07221635Andy McFadden    }
742faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
743faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
744948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
745faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
746faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
747948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeAvailable) {
748948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = true;
749948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    } else if (!mHWVsyncAvailable) {
750948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
751948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        return;
752948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
753948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
754faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const nsecs_t period =
755faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
756faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
757faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.reset();
758faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mPrimaryDispSync.setPeriod(period);
759faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
760faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (!mPrimaryHWVsyncEnabled) {
761faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.beginResync();
762d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
763d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(true);
764faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = true;
765faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
766faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
767faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
768948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hallvoid SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
769faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    Mutex::Autolock _l(mHWVsyncLock);
770faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mPrimaryHWVsyncEnabled) {
771d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
772d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        mEventControlThread->setVsyncEnabled(false);
773faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryDispSync.endResync();
774faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mPrimaryHWVsyncEnabled = false;
775faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
776948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    if (makeUnavailable) {
777948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall        mHWVsyncAvailable = false;
778948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall    }
779faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis}
780faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
781faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
782d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    bool needsHwVsync = false;
783faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
784d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    { // Scope for the lock
785d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        Mutex::Autolock _l(mHWVsyncLock);
786d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        if (type == 0 && mPrimaryHWVsyncEnabled) {
787d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
788faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
789148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
790d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis
791d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    if (needsHwVsync) {
792d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        enableHardwareVsync();
793d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    } else {
794d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis        disableHardwareVsync(false);
795d1700756ec9520c3fba22f9a14fd064a6e288810Jamie Gennis    }
796148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
797148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
798148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) {
799148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    if (mEventThread == NULL) {
800148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // This is a temporary workaround for b/7145521.  A non-null pointer
801148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // does not mean EventThread has finished initializing, so this
802148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        // is not a correct fix.
803148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        ALOGW("WARNING: EventThread not started, ignoring hotplug");
804148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        return;
805148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    }
8069e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
8079e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
8089e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        Mutex::Autolock _l(mStateLock);
809692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall        if (connected) {
810692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            createBuiltinDisplayLocked((DisplayDevice::DisplayType)type);
8119e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        } else {
812692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
813692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall            mBuiltinDisplays[type].clear();
8149e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        }
8159e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        setTransactionFlags(eDisplayTransactionNeeded);
8169e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
8179e9689c11148521d2c16a121a0b87b062be0714cAndy McFadden        // Defer EventThread notification until SF has updated mDisplays.
8183ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    }
8198630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
8208630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
82181cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopianvoid SurfaceFlinger::eventControl(int disp, int event, int enabled) {
822faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    ATRACE_CALL();
82381cd5d3b94d21253a0be925f4ae58cc7f4afeef7Mathias Agopian    getHwComposer().eventControl(disp, event, enabled);
8248630320433bd15aca239522e54e711ef6372ab07Mathias Agopian}
8258630320433bd15aca239522e54e711ef6372ab07Mathias Agopian
8264fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::onMessageReceived(int32_t what) {
8271c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis    ATRACE_CALL();
82899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    switch (what) {
8299eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    case MessageQueue::TRANSACTION:
8309eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        handleMessageTransaction();
8319eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian        break;
8324fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::INVALIDATE:
8334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageTransaction();
8344fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageInvalidate();
8354fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        signalRefresh();
8364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
8374fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    case MessageQueue::REFRESH:
8384fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        handleMessageRefresh();
8394fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        break;
8404fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
8414fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8434fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageTransaction() {
844e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
8454fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (transactionFlags) {
84687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        handleTransaction(transactionFlags);
8474fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
8484fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
8504fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageInvalidate() {
851cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
85287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handlePageFlip();
8534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
8543a3cad30c40c8eb87671262a9fe7f0e214b6a934Mathias Agopian
8554fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::handleMessageRefresh() {
856cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
857cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    preComposition();
858cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    rebuildLayerStacks();
859cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    setUpHWComposer();
860cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doDebugFlashRegions();
861cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    doComposition();
862cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postComposition();
863cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
864cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
865cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDebugFlashRegions()
866cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
867cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // is debugging enabled
868cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (CC_LIKELY(!mDebugRegion))
869cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        return;
870cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
871cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    const bool repaintEverything = mRepaintEverything;
872cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
873cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
8742c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
875cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
876cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
877cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            if (!dirtyRegion.isEmpty()) {
878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // redraw the whole screen
879cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                doComposeSurfaces(hw, Region(hw->bounds()));
880cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
881cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                // and draw the dirty region
882cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                const int32_t height = hw->getHeight();
8833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                RenderEngine& engine(getRenderEngine());
8843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
8853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
886cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                hw->compositionComplete();
887da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                hw->swapBuffers(getHwComposer());
888cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            }
889cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
890cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
891cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
892cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    postFramebuffer();
893cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
894cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (mDebugRegion > 1) {
895cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        usleep(mDebugRegion * 1000);
896cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
897bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian
898bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    HWComposer& hwc(getHwComposer());
899bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
900bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        status_t err = hwc.prepare();
901bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
902bb53b0e4b97634bc31808965f81b3ab4193d0e84Mathias Agopian    }
903cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
904cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
905cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::preComposition()
906cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
907cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    bool needExtraInvalidate = false;
9081eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
9091eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
910cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
9111eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        if (layers[i]->onPreComposition()) {
912cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            needExtraInvalidate = true;
913cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        }
914cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
915cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (needExtraInvalidate) {
916cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        signalLayerUpdate();
917cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
918cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
919a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
920cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::postComposition()
921cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian{
9221eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
9231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const size_t count = layers.size();
924cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    for (size_t i=0 ; i<count ; i++) {
9251eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        layers[i]->onPostComposition();
926cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
9274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
928faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    const HWComposer& hwc = getHwComposer();
929faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
930faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
931faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (presentFence->isValid()) {
932faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (mPrimaryDispSync.addPresentFence(presentFence)) {
933faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
934faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        } else {
935948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(false);
936faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
937faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
938faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
9395167ec68fed047bf65b1eb0c6091534682135eefAndy McFadden    if (kIgnorePresentFences) {
940faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
9412c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
942faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            enableHardwareVsync();
943faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
944faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
945faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis
9464b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (mAnimCompositionPending) {
9474b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimCompositionPending = false;
9484b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
949a9a1b006e48320f5c501473e51e6c4a5f7a17b88Jesse Hall        if (presentFence->isValid()) {
9504b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentFence(presentFence);
9514b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        } else {
9524b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // The HWC doesn't support present fences, so use the refresh
9534b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            // timestamp instead.
9544b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
9554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            mAnimFrameTracker.setActualPresentTime(presentTime);
9564b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        }
9574b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        mAnimFrameTracker.advanceFrame();
9584b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    }
959cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
960cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
961cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::rebuildLayerStacks() {
962cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    // rebuild the visible layer list per screen
96352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
964cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        ATRACE_CALL();
96587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        mVisibleRegionsDirty = false;
96687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateHwcGeometry();
967ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian
9681eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const LayerVector& layers(mDrawingState.layersSortedByZ);
96992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
970ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region opaqueRegion;
971ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian            Region dirtyRegion;
97213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            Vector< sp<Layer> > layersSortedByZ;
9734297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            const sp<DisplayDevice>& hw(mDisplays[dpy]);
9747e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Transform& tr(hw->getTransform());
9757e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            const Rect bounds(hw->getBounds());
9762c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            if (hw->isDisplayOn()) {
9771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                SurfaceFlinger::computeVisibleRegions(layers,
978ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
9797e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian
9801eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const size_t count = layers.size();
981ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                for (size_t i=0 ; i<count ; i++) {
9821eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const sp<Layer>& layer(layers[i]);
9831eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                    const Layer::State& s(layer->getDrawingState());
984ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                    if (s.layerStack == hw->getLayerStack()) {
985a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        Region drawRegion(tr.transform(
986a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                                layer->visibleNonTransparentRegion));
987a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        drawRegion.andSelf(bounds);
988a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                        if (!drawRegion.isEmpty()) {
989ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                            layersSortedByZ.add(layer);
990ce3a0a541c3dde1330551bd7a048cd9d92335c00Mathias Agopian                        }
99187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                    }
99287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian                }
9933b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            }
9944297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->setVisibleLayersSortedByZ(layersSortedByZ);
9957e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.set(bounds);
9967e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
9977e7ed7f77a3963a3542bde529d2797a239e2798bMathias Agopian            hw->dirtyRegion.orSelf(dirtyRegion);
9983b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
9993b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
1000cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
10013b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
1002cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::setUpHWComposer() {
1003028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1004b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
1005b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
1006b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
1007b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1008b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If nothing has changed (!dirty), don't recompose.
1009b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // If something changed, but we don't currently have any visible layers,
1010b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   and didn't when we last did a composition, then skip it this time.
1011b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // The second rule does two things:
1012b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When all layers are removed from a display, we'll emit one black
1013b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   frame, then nothing more until we get new layers.
1014b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        // - When a display is created with a private layer stack, we won't
1015b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        //   emit any black frames until a layer is added to the layer stack.
1016b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        bool mustRecompose = dirty && !(empty && wasEmpty);
1017b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1018b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
1019b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
1020b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                mustRecompose ? "doing" : "skipping",
1021b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                dirty ? "+" : "-",
1022b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                empty ? "+" : "-",
1023b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall                wasEmpty ? "+" : "-");
1024b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
10257143316af216fa92c31a60d4407b707637382da1Dan Stoza        mDisplays[dpy]->beginFrame(mustRecompose);
1026b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall
1027b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        if (mustRecompose) {
1028b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
1029b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall        }
1030028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall    }
1031028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
103252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
103352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
103452bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // build the h/w work list
1035a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        if (CC_UNLIKELY(mHwWorkListDirty)) {
1036a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            mHwWorkListDirty = false;
1037a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
1038a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                sp<const DisplayDevice> hw(mDisplays[dpy]);
1039a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const int32_t id = hw->getHwcDisplayId();
1040a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                if (id >= 0) {
104113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const Vector< sp<Layer> >& currentLayers(
1042a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        hw->getVisibleLayersSortedByZ());
1043a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    const size_t count = currentLayers.size();
1044a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    if (hwc.createWorkList(id, count) == NO_ERROR) {
1045a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        HWComposer::LayerListIterator cur = hwc.begin(id);
1046a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        const HWComposer::LayerListIterator end = hwc.end(id);
1047a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
104813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                            const sp<Layer>& layer(currentLayers[i]);
1049a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            layer->setGeometry(hw, *cur);
10509c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
1051a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                                cur->setSkip(true);
1052a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                            }
1053a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                        }
1054a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    }
1055a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                }
1056a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis            }
1057a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        }
1058a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
1059a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis        // set the per-frame data
106092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
10614297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            sp<const DisplayDevice> hw(mDisplays[dpy]);
1062e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            const int32_t id = hw->getHwcDisplayId();
1063e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian            if (id >= 0) {
106413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                const Vector< sp<Layer> >& currentLayers(
1065cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                    hw->getVisibleLayersSortedByZ());
1066e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian                const size_t count = currentLayers.size();
1067a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                HWComposer::LayerListIterator cur = hwc.begin(id);
1068a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                const HWComposer::LayerListIterator end = hwc.end(id);
1069a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
1070a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    /*
1071a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * update the per-frame h/w composer data for each layer
1072a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     * and build the transparent region of the FB
1073a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                     */
107413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian                    const sp<Layer>& layer(currentLayers[i]);
1075a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis                    layer->setPerFrameData(hw, *cur);
10761e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian                }
107752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
107887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
1079a4310c8be2dc3406a668ee99020d52187173232fJamie Gennis
108003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        // If possible, attempt to use the cursor overlay on each display.
108103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
108203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            sp<const DisplayDevice> hw(mDisplays[dpy]);
108303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            const int32_t id = hw->getHwcDisplayId();
108403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            if (id >= 0) {
108503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const Vector< sp<Layer> >& currentLayers(
108603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    hw->getVisibleLayersSortedByZ());
108703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const size_t count = currentLayers.size();
108803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                HWComposer::LayerListIterator cur = hwc.begin(id);
108903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                const HWComposer::LayerListIterator end = hwc.end(id);
109003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
109103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    const sp<Layer>& layer(currentLayers[i]);
109203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    if (layer->isPotentialCursor()) {
109303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                        cur->setIsCursorLayerHint();
109403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                        break;
109503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    }
109603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                }
109703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
109803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
109903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
110052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        status_t err = hwc.prepare();
110152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
110238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall
110338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
110438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            sp<const DisplayDevice> hw(mDisplays[dpy]);
110538efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall            hw->prepareFrame(hwc);
110638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        }
110752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
1108cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
110952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
1110cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doComposition() {
1111cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    ATRACE_CALL();
111252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
111392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11144297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
11152c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        if (hw->isDisplayOn()) {
1116cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            // transform the dirty region into this screen's coordinate space
1117cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
111802b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
111902b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            // repaint the framebuffer (if needed)
112002b95105754b1859a97e234b79f41489a4677c20Mathias Agopian            doDisplayComposition(hw, dirtyRegion);
112102b95105754b1859a97e234b79f41489a4677c20Mathias Agopian
1122cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->dirtyRegion.clear();
1123cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->flip(hw->swapRegion);
1124cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian            hw->swapRegion.clear();
112587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        }
112652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        // inform the h/w that we're done compositing
11274297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        hw->compositionComplete();
11284fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
112952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    postFramebuffer();
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::postFramebuffer()
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1134841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1135b048cef231075a5e41d224b73fe11fec62f335b1Mathias Agopian
1136a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    const nsecs_t now = systemTime();
1137a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = now;
1138c5c5a14c06de249d8e0445fd24699e1d9aa04549Jesse Hall
113952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    HWComposer& hwc(getHwComposer());
1140ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall    if (hwc.initCheck() == NO_ERROR) {
11412a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        if (!hwc.supportsFramebufferTarget()) {
11422a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            // EGL spec says:
11432a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //   "surface must be bound to the calling thread's current context,
11442a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian            //    for the current rendering API."
1145875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
11462a23184e4109060ec772763e80dae2132cf9d2ebMathias Agopian        }
1147e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        hwc.commit();
114852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
114952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
11506da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // make the default display current because the VirtualDisplayDevice code cannot
11516da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // deal with dequeueBuffer() being called outside of the composition loop; however
11526da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // the code below can call glFlush() which is allowed (and does in some case) call
11536da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    // dequeueBuffer().
11546da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
11556da15f46f5f8b38e31384d641f8d3db2c3c6ea30Mathias Agopian
115692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
11574297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        sp<const DisplayDevice> hw(mDisplays[dpy]);
115813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
1159da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        hw->onSwapBuffersCompleted(hwc);
116052bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian        const size_t count = currentLayers.size();
1161e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        int32_t id = hw->getHwcDisplayId();
1162e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (id >=0 && hwc.initCheck() == NO_ERROR) {
11631e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            HWComposer::LayerListIterator cur = hwc.begin(id);
11641e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian            const HWComposer::LayerListIterator end = hwc.end(id);
116552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
1166d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, &*cur);
116752bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1168cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        } else {
116952bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            for (size_t i = 0; i < count; i++) {
1170d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian                currentLayers[i]->onLayerDisplayed(hw, NULL);
117152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian            }
1172ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        }
1173e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
1174e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
1175a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mLastSwapBufferTime = systemTime() - now;
1176a44b04163957d6086362f6f365443c4c93379031Mathias Agopian    mDebugInSwapBuffers = 0;
11776547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
11786547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
11796547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
11806547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        logFrameStats();
11816547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
118487baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
1185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1186841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1187841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
11887cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // here we keep a copy of the drawing state (that is the state that's
11897cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // going to be overwritten by handleTransactionLocked()) outside of
11907cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // mStateLock so that the side-effects of the State assignment
11917cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    // don't happen with mStateLock held (which can cause deadlocks).
11927cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian    State drawingState(mDrawingState);
11937cc6df59572582652078df5aeac9e6c67d7fa81eMathias Agopian
1194ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1195ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    const nsecs_t now = systemTime();
1196ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = now;
1197ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1198ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // Here we're guaranteed that some transaction flags are set
1199ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // so we can call handleTransactionLocked() unconditionally.
1200ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // We call getTransactionFlags(), which will also clear the flags,
1201ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // with mStateLock held to guarantee that mCurrentState won't change
1202ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // until the transaction is committed.
1203ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1204e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    transactionFlags = getTransactionFlags(eTransactionMask);
120587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    handleTransactionLocked(transactionFlags);
1206ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian
1207ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mLastTransactionTime = systemTime() - now;
1208ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    mDebugInTransaction = 0;
1209ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    invalidateHwcGeometry();
1210ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    // here the transaction has been committed
12113d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian}
1212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
121387baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
12143d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian{
12153d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
1216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t count = currentLayers.size();
1217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
1219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Traversal of the children
1220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * (perform the transaction for each of them if needed)
1221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
12233559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (transactionFlags & eTraversalNeeded) {
1224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
122513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
1226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
1227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!trFlags) continue;
1228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t flags = layer->doTransaction(0);
1230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (flags & Layer::eVisibleRegion)
1231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mVisibleRegionsDirty = true;
1232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
12363559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform display own transactions if needed
1237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
1238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1239e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (transactionFlags & eDisplayTransactionNeeded) {
124092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // here we take advantage of Vector's copy-on-write semantics to
124192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // improve performance by skipping the transaction entirely when
124292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        // know that the lists are identical
1243e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
1244e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
124592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        if (!curr.isIdenticalTo(draw)) {
1246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mVisibleRegionsDirty = true;
124792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            const size_t cc = curr.size();
124893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                  size_t dc = draw.size();
124992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
125092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find the displays that were removed
125192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in drawing state but not in current state)
125292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // also handle displays that changed
125392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: displays that are in both lists)
125492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<dc ; i++) {
1255e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
1256e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (j < 0) {
125792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // in drawing state but not in current state
12583ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    if (!draw[i].isMainDisplay()) {
125927ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // Call makeCurrent() on the primary display so we can
126027ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // be sure that nothing associated with this display
126127ec5739bc05330e08b02f25b62a8f597bad897aAndy McFadden                        // is current.
126202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
1263875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
126402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
126502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
126602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
12679e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
12687adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(draw[i].type, false);
126902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        mDisplays.removeItem(draw.keyAt(i));
127092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    } else {
127192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                        ALOGW("trying to remove the main display");
127292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
127392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                } else {
127492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    // this display is in both lists. see if something changed.
1275e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[j]);
12763ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    const wp<IBinder>& display(curr.keyAt(j));
1277111b2d89221722d38f5b5b3ba65904ec22421839Mathias Agopian                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
1278e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        // changing the surface is like destroying and
127993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // recreating the DisplayDevice, so we just remove it
128093997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // from the drawing state, so that it get re-added
128193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // below.
128202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        sp<DisplayDevice> hw(getDisplayDevice(display));
128302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        if (hw != NULL)
128402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                            hw->disconnect(getHwComposer());
128593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDisplays.removeItem(display);
128693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        mDrawingState.displays.removeItemsAt(i);
128793997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        dc--; i--;
128893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        // at this point we must loop to the next item
128993997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        continue;
129092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
129193997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian
1292db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian                    const sp<DisplayDevice> disp(getDisplayDevice(display));
129393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    if (disp != NULL) {
129493997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        if (state.layerStack != draw[i].layerStack) {
129593997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                            disp->setLayerStack(state.layerStack);
129693997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
129700e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        if ((state.orientation != draw[i].orientation)
129800e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.viewport != draw[i].viewport)
129900e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                                || (state.frame != draw[i].frame))
130000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                        {
130100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian                            disp->setProjection(state.orientation,
13024fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                    state.viewport, state.frame);
130393997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                        }
130447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        if (state.width != draw[i].width || state.height != draw[i].height) {
130547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            disp->setDisplaySize(state.width, state.height);
130647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                        }
130792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                    }
130892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
130992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
131092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
131192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // find displays that were added
131292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            // (ie: in current state but not in drawing state)
131392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            for (size_t i=0 ; i<cc ; i++) {
1314e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
1315e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                    const DisplayDeviceState& state(curr[i]);
1316cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
131799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    sp<DisplaySurface> dispSurface;
1318db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                    sp<IGraphicBufferProducer> producer;
1319b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferProducer> bqProducer;
1320b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    sp<IGraphicBufferConsumer> bqConsumer;
1321b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
1322b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                            new GraphicBufferAlloc());
1323db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
132402d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                    int32_t hwcDisplayId = -1;
132599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (state.isVirtualDisplay()) {
132602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // Virtual displays without a surface are dormant:
132702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // they have external state (layer stack, projection,
132802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        // etc.) but no internal state (i.e. a DisplayDevice).
132999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        if (state.surface != NULL) {
1330db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
13311f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int width = 0;
13321f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int status = state.surface->query(
13331f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    NATIVE_WINDOW_WIDTH, &width);
13341f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            ALOGE_IF(status != NO_ERROR,
13351f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    "Unable to query width (%d)", status);
13361f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            int height = 0;
13371f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            status = state.surface->query(
13381f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    NATIVE_WINDOW_HEIGHT, &height);
13391f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            ALOGE_IF(status != NO_ERROR,
13401f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    "Unable to query height (%d)", status);
13411f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            if (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 ||
13421f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                    (width <= MAX_VIRTUAL_DISPLAY_DIMENSION &&
13431f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                     height <= MAX_VIRTUAL_DISPLAY_DIMENSION)) {
13441f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                                hwcDisplayId = allocateHwcDisplayId(state.type);
13451f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza                            }
13461f3efb11ff8c884a254f4272f0d1ee0b77ceff2fDan Stoza
1347db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
1348b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    *mHwc, hwcDisplayId, state.surface,
1349b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                    bqProducer, bqConsumer, state.displayName);
1350db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian
1351db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian                            dispSurface = vds;
135247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                            producer = vds;
135399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        }
135499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    } else {
1355cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        ALOGE_IF(state.surface!=NULL,
1356cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "adding a supported display, but rendering "
1357cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                "surface is provided (%p), ignoring it",
1358cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                                state.surface.get());
135902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall                        hwcDisplayId = allocateHwcDisplayId(state.type);
1360cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // for supported (by hwc) displays we provide our
1361cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        // own rendering surface
1362b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        dispSurface = new FramebufferSurface(*mHwc, state.type,
1363b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                                bqConsumer);
1364b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza                        producer = bqProducer;
1365cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    }
1366cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian
1367cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                    const wp<IBinder>& display(curr.keyAt(i));
136899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    if (dispSurface != NULL) {
1369cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        sp<DisplayDevice> hw = new DisplayDevice(this,
137019e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                state.type, hwcDisplayId,
137119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall                                mHwc->getFormat(hwcDisplayId), state.isSecure,
137205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                display, dispSurface, producer,
137305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall                                mRenderEngine->getEGLConfig());
1374cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setLayerStack(state.layerStack);
1375cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        hw->setProjection(state.orientation,
13764fb3999cea652617be5125f8a42c257467bf3c77Jeff Brown                                state.viewport, state.frame);
13778dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden                        hw->setDisplayName(state.displayName);
1378cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian                        mDisplays.add(display, hw);
13791c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        if (state.isVirtualDisplay()) {
13801c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            if (hwcDisplayId >= 0) {
13811c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                mHwc->setVirtualDisplayProperties(hwcDisplayId,
13821c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getWidth(), hw->getHeight(),
13831c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                                        hw->getFormat());
13841c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                            }
13851c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        } else {
13867adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall                            mEventThread->onHotplugReceived(state.type, true);
13871c569c4d45f89ec05abf8f8fe3a560e68bf39a8eJesse Hall                        }
138893997a8a75942b4d06cf50925de5bede489cc134Mathias Agopian                    }
138992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian                }
139092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian            }
1391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
13923559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
1393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
13948430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
13958430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // The transform hint might have changed for some layers
13968430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (either because a display has changed, or because a layer
13978430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // as changed).
13988430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
13998430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // Walk through all the layers in currentLayers,
14008430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // and update their transform hint.
14018430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14028430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // If a layer is visible only on a single display, then that
14038430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // display is used to calculate the hint, otherwise we use the
14048430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // default display.
14058430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14068430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
14078430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // the hint is set before we acquire a buffer from the surface texture.
14088430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14098430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // NOTE: layer transactions have taken place already, so we use their
14108430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // drawing state. However, SurfaceFlinger's own transaction has not
14118430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // happened yet, so we must use the current state layer list
14128430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        // (soon to become the drawing state list).
14138430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        //
14148430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        sp<const DisplayDevice> disp;
14158430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        uint32_t currentlayerStack = 0;
14168430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        for (size_t i=0; i<count; i++) {
14178430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // NOTE: we rely on the fact that layers are sorted by
14188430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // layerStack first (so we don't have to traverse the list
14198430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            // of displays for every layer).
142013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
14211eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            uint32_t layerStack = layer->getDrawingState().layerStack;
14228430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            if (i==0 || currentlayerStack != layerStack) {
14238430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                currentlayerStack = layerStack;
14248430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // figure out if this layerstack is mirrored
14258430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // (more than one display) if so, pick the default display,
14268430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                // if not, pick the only display it's on.
14278430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                disp.clear();
14288430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
14298430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    sp<const DisplayDevice> hw(mDisplays[dpy]);
14308430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    if (hw->getLayerStack() == currentlayerStack) {
14318430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        if (disp == NULL) {
14328430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            disp = hw;
14338430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        } else {
143491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                            disp = NULL;
14358430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                            break;
14368430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                        }
14378430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                    }
14388430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian                }
14398430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
144091d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            if (disp == NULL) {
144191d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
144291d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // redraw after transform hint changes. See bug 8508397.
144391d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase
144491d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // could be null when this layer is using a layerStack
144591d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // that is not visible on any display. Also can occur at
144691d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                // screen off/on times.
144791d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase                disp = getDefaultDisplayDevice();
14488430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian            }
144991d25932b6651b20159a737da6140cf8a6aaaf08Chet Haase            layer->updateTransformHint(disp);
14508430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian        }
14518430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian    }
14528430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
14538430095879d2fa6878e68f8f12da4e704815ac09Mathias Agopian
14543559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    /*
14553559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     * Perform our own transaction if needed
14563559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian     */
1457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
14581eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
14591eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    if (currentLayers.size() > layers.size()) {
14603559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        // layers have been added
14613559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
14623559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    }
14633559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian
14643559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // some layers might have been removed, so
14653559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    // we need to update the regions they're exposing.
14663559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian    if (mLayersRemoved) {
14673559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mLayersRemoved = false;
14683559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        mVisibleRegionsDirty = true;
14691eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const size_t count = layers.size();
14703559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
14711eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian            const sp<Layer>& layer(layers[i]);
14723559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian            if (currentLayers.indexOf(layer) < 0) {
14733559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // this layer is not visible anymore
14743559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could traverse the tree from front to back and
14753559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                //       compute the actual visible region
14763559b07a885bcdff51a6dffb8e3a5ac5adf3a220Mathias Agopian                // TODO: we could cache the transformed region
14771eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian                const Layer::State& s(layer->getDrawingState());
14781501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                Region visibleReg = s.transform.transform(
14791501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                        Region(Rect(s.active.w, s.active.h)));
14801501d54d63c55dc4e8f4c6eeaeac35aca6660ffcMathias Agopian                invalidateLayerStack(s.layerStack, visibleReg);
14810aa758d64ac530833ce9a311b164c9175a7a054cMathias Agopian            }
1482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    commitTransaction();
148603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
148703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    updateCursorAsync();
148803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews}
148903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews
149003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrewsvoid SurfaceFlinger::updateCursorAsync()
149103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews{
149203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    HWComposer& hwc(getHwComposer());
149303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
149403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        sp<const DisplayDevice> hw(mDisplays[dpy]);
149503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const int32_t id = hw->getHwcDisplayId();
149603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        if (id < 0) {
149703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            continue;
149803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
149903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const Vector< sp<Layer> >& currentLayers(
150003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            hw->getVisibleLayersSortedByZ());
150103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const size_t count = currentLayers.size();
150203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        HWComposer::LayerListIterator cur = hwc.begin(id);
150303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        const HWComposer::LayerListIterator end = hwc.end(id);
150403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
150503414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) {
150603414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                continue;
150703414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            }
150803414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            const sp<Layer>& layer(currentLayers[i]);
150903414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            Rect cursorPos = layer->getPosition(hw);
151003414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            hwc.setCursorPositionAsync(id, cursorPos);
151103414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews            break;
151203414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews        }
151303414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews    }
15144fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian}
15154fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
15164fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopianvoid SurfaceFlinger::commitTransaction()
15174fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian{
15184fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    if (!mLayersPendingRemoval.isEmpty()) {
15194fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        // Notify removed layers now that they can't be drawn from
15204fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
15214fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            mLayersPendingRemoval[i]->onRemoved();
15224fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        }
15234fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian        mLayersPendingRemoval.clear();
15244fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
15254fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian
15264b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // If this transaction is part of a window animation then the next frame
15274b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    // we composite should be considered an animation as well.
15284b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    mAnimCompositionPending = mAnimTransactionPending;
15294b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
15304fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mDrawingState = mCurrentState;
15312d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mTransactionPending = false;
15322d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    mAnimTransactionPending = false;
15334fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    mTransactionCV.broadcast();
1534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid SurfaceFlinger::computeVisibleRegions(
153787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const LayerVector& currentLayers, uint32_t layerStack,
153887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        Region& outDirtyRegion, Region& outOpaqueRegion)
1539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
1540841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian    ATRACE_CALL();
1541841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
1542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveOpaqueLayers;
1543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region aboveCoveredLayers;
1544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    Region dirty;
1545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
154687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outDirtyRegion.clear();
1547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t i = currentLayers.size();
1549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (i--) {
155013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer = currentLayers[i];
1551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // start with the whole surface at its current location
15531eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
1554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
155501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall        // only consider the layers on the given layer stack
155687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        if (s.layerStack != layerStack)
155787baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            continue;
155887baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1559ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1560ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * opaqueRegion: area of a surface that is fully opaque.
1561ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region opaqueRegion;
1563ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1564ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1565ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visibleRegion: area of a surface that is visible on screen
1566ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * and not fully transparent. This is essentially the layer's
1567ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * footprint minus the opaque regions above it.
1568ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * Areas covered by a translucent surface are considered visible.
1569ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region visibleRegion;
1571ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1572ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        /*
1573ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * coveredRegion: area of a surface that is covered by all
1574ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         * visible regions above it (which includes the translucent areas).
1575ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian         */
1576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        Region coveredRegion;
1577ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1578a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        /*
1579a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparentRegion: area of a surface that is hinted to be completely
1580a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * transparent. This is only used to tell when the layer has no visible
1581a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * non-transparent regions and can be removed from the layer list. It
1582a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * does not affect the visibleRegion of this layer or any layers
1583a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * beneath it. The hint may not be correct if apps don't respect the
1584a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         * SurfaceView restrictions (which, sadly, some don't).
1585a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall         */
1586a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        Region transparentRegion;
1587a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall
1588ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1589ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // handle hidden surfaces by setting the visible region to empty
1590da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        if (CC_LIKELY(layer->isVisible())) {
15914125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            const bool translucent = !layer->isOpaque(s);
15925219a06d61ac4517506500363c5e8a5972dd7ac9Mathias Agopian            Rect bounds(s.transform.transform(layer->computeBounds()));
1593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            visibleRegion.set(bounds);
1594ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            if (!visibleRegion.isEmpty()) {
1595ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // Remove the transparent area from the visible region
1596ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (translucent) {
15974fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    const Transform tr(s.transform);
15984fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    if (tr.transformed()) {
15994fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        if (tr.preserveRects()) {
16004fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transform the transparent region
16012ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                            transparentRegion = tr.transform(s.activeTransparentRegion);
16024fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        } else {
16034fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transformation too complex, can't do the
16044fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                            // transparent region optimization.
1605a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                            transparentRegion.clear();
16064fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                        }
16074fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    } else {
16082ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian                        transparentRegion = s.activeTransparentRegion;
16094fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                    }
1610ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1612ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                // compute the opaque region
16134fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian                const int32_t layerOrientation = s.transform.getOrientation();
1614ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                if (s.alpha==255 && !translucent &&
1615ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
1616ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    // the opaque region is the layer's footprint
1617ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                    opaqueRegion = visibleRegion;
1618ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian                }
1619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1622ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Clip the covered region to the visible region
1623ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
1624ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1625ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveCoveredLayers for next (lower) layer
1626ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        aboveCoveredLayers.orSelf(visibleRegion);
1627ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian
1628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // subtract the opaque region covered by the layers above us
1629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        visibleRegion.subtractSelf(aboveOpaqueLayers);
1630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // compute this layer's dirty region
1632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (layer->contentDirty) {
1633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // we need to invalidate the whole region
1634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            dirty = visibleRegion;
1635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // as well, as the old visible region
16364fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            dirty.orSelf(layer->visibleRegion);
1637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            layer->contentDirty = false;
1638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1639a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian            /* compute the exposed region:
1640ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   the exposed region consists of two components:
1641ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   1) what's VISIBLE now and was COVERED before
1642ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *   2) what's EXPOSED now less what was EXPOSED before
1643ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1644ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * note that (1) is conservative, we start with the whole
1645ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * visible region but only keep what used to be covered by
1646ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * something -- which mean it may have been exposed.
1647ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             *
1648ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * (2) handles areas that were not covered by anything but got
1649ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian             * exposed because of a resize.
1650a8d44f75e1934072713371a2dcd143c63ffcbe0eMathias Agopian             */
1651ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region newExposed = visibleRegion - coveredRegion;
16524fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldVisibleRegion = layer->visibleRegion;
16534fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region oldCoveredRegion = layer->coveredRegion;
1654ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
1655ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
1656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        dirty.subtractSelf(aboveOpaqueLayers);
1658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // accumulate to the screen dirty region
166087baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        outDirtyRegion.orSelf(dirty);
1661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1662ab02873e8f4e235b0db800521dd0c969ed38c0b9Mathias Agopian        // Update aboveOpaqueLayers for next (lower) layer
1663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        aboveOpaqueLayers.orSelf(opaqueRegion);
16648b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
1665a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        // Store the visible region in screen space
1666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setVisibleRegion(visibleRegion);
1667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        layer->setCoveredRegion(coveredRegion);
1668a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall        layer->setVisibleNonTransparentRegion(
1669a8026d21f3f2f09e3416cbd33c277fbd15d8cf4eJesse Hall                visibleRegion.subtract(transparentRegion));
1670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
167287baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    outOpaqueRegion = aboveOpaqueLayers;
1673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
167587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
167687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& dirty) {
167792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
16784297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        const sp<DisplayDevice>& hw(mDisplays[dpy]);
16794297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        if (hw->getLayerStack() == layerStack) {
16804297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->dirtyRegion.orSelf(dirty);
168192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        }
168292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
168387baae104a3e4c2059990b01c393476065c558b0Mathias Agopian}
168487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
168587baae104a3e4c2059990b01c393476065c558b0Mathias Agopianvoid SurfaceFlinger::handlePageFlip()
1686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
16874fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    Region dirtyRegion;
168899ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
16894fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    bool visibleRegions = false;
16901eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    const LayerVector& layers(mDrawingState.layersSortedByZ);
169151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner
169251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Store the set of layers that need updates. This set must not change as
169351c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // buffers are being latched, as this could result in a deadlock.
169451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Example: Two producers share the same command stream and:
169551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 1.) Layer 0 is latched
169651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 0 gets a new frame
169751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 2.) Layer 1 gets a new frame
169851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // 3.) Layer 1 is latched.
169951c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // Display is now waiting on Layer 1's frame, which is behind layer 0's
170051c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    // second frame. But layer 0's second frame could be waiting on display.
170151c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    Vector<Layer*> layersWithQueuedFrames;
170251c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layers.size(); i<count ; i++) {
17031eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const sp<Layer>& layer(layers[i]);
170451c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner        if (layer->hasQueuedFrame())
170551c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner            layersWithQueuedFrames.push_back(layer.get());
170651c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    }
170751c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner    for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
170851c59cd1e73be3787eb75bebd87fc41739c65adbEric Penner        Layer* layer = layersWithQueuedFrames[i];
170987baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region dirty(layer->latchBuffer(visibleRegions));
17101eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& s(layer->getDrawingState());
171187baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        invalidateLayerStack(s.layerStack, dirty);
17124fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian    }
17134da751999358fffa4cefc4c8046dab72045925f6Mathias Agopian
17143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleRegionsDirty |= visibleRegions;
1715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1717ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopianvoid SurfaceFlinger::invalidateHwcGeometry()
1718ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian{
1719ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian    mHwWorkListDirty = true;
1720ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian}
1721ad456f9878ff7c176499e7b992f9ff1cb3e9cdeeMathias Agopian
172299ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian
1723cd60f99aba9e750700a967db30b74a29145739cfMathias Agopianvoid SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
172487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian        const Region& inDirtyRegion)
1725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17267143316af216fa92c31a60d4407b707637382da1Dan Stoza    // We only need to actually compose the display if:
17277143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 1) It is being handled by hardware composer, which may need this to
17287143316af216fa92c31a60d4407b707637382da1Dan Stoza    //    keep its virtual display state machine in sync, or
17297143316af216fa92c31a60d4407b707637382da1Dan Stoza    // 2) There is work to be done (the dirty region isn't empty)
17307143316af216fa92c31a60d4407b707637382da1Dan Stoza    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
17317143316af216fa92c31a60d4407b707637382da1Dan Stoza    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
17327143316af216fa92c31a60d4407b707637382da1Dan Stoza        return;
17337143316af216fa92c31a60d4407b707637382da1Dan Stoza    }
17347143316af216fa92c31a60d4407b707637382da1Dan Stoza
173587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    Region dirtyRegion(inDirtyRegion);
173687baae104a3e4c2059990b01c393476065c558b0Mathias Agopian
1737b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian    // compute the invalid region
17384297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17404297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    uint32_t flags = hw->getFlags();
17410f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian    if (flags & DisplayDevice::SWAP_RECTANGLE) {
174229d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
174329d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // takes a rectangle, we must make sure to update that whole
174429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        // rectangle in that case
17454297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian        dirtyRegion.set(hw->swapRegion.bounds());
1746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
17470f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian        if (flags & DisplayDevice::PARTIAL_UPDATES) {
174829d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // We need to redraw the rectangle that will be updated
1749df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian            // (pushed to the framebuffer).
175095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian            // This is needed because PARTIAL_UPDATES only takes one
17510f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian            // rectangle instead of a region (see DisplayDevice::flip())
17524297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->swapRegion.bounds());
1753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
175429d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian            // we need to redraw everything (the whole screen)
17554297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            dirtyRegion.set(hw->bounds());
17564297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian            hw->swapRegion = dirtyRegion;
1757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17609c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
17613f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine        if (!doComposeSurfaces(hw, dirtyRegion)) return;
1762ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    } else {
1763ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        RenderEngine& engine(getRenderEngine());
17649c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        mat4 colorMatrix = mColorMatrix;
17659c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        if (mDaltonize) {
17669c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            colorMatrix = colorMatrix * mDaltonizer();
17679c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        }
17689c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette        engine.beginGroup(colorMatrix);
1769ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        doComposeSurfaces(hw, dirtyRegion);
1770ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        engine.endGroup();
1771ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    }
1772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17739c6e297271ec9af9d974242d89cfa08cb6ceaa0aMathias Agopian    // update the swap region and clear the dirty region
17744297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->swapRegion.orSelf(dirtyRegion);
1775da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
1776da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    // swap buffers (presentation)
1777da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    hw->swapBuffers(getHwComposer());
1778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17803f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentinebool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
1781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
17823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
178385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const int32_t id = hw->getHwcDisplayId();
17848630320433bd15aca239522e54e711ef6372ab07Mathias Agopian    HWComposer& hwc(getHwComposer());
17851e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    HWComposer::LayerListIterator cur = hwc.begin(id);
17861e26087493ac0e7d7dc6dea8ad85cfef08b3271fMathias Agopian    const HWComposer::LayerListIterator end = hwc.end(id);
1787a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1788d05a17fbb3772051d287f1f8830a7f00964f7ec2Jesse Hall    bool hasGlesComposition = hwc.hasGlesComposition(id);
178985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (hasGlesComposition) {
1790875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
1791c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
1792c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock                  hw->getDisplayName().string());
17933f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
17943f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
17953f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
17963f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            }
17973f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine            return false;
1798c8c71096195de0128e57574b1ddf685838ceb2f0Michael Chock        }
1799a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1800a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        // Never touch the framebuffer if we don't have any framebuffer layers
180185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        const bool hasHwcComposition = hwc.hasHwcComposition(id);
1802e60b0687c8d49871d0c8786cabe6851f7a7783b5Mathias Agopian        if (hasHwcComposition) {
1803b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // when using overlays, we assume a fully transparent framebuffer
1804b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // NOTE: we could reduce how much we need to clear, for instance
1805b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // remove where there are opaque FB layers. however, on some
18063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            // GPUs doing a "clean slate" clear might be more efficient.
1807b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // We'll revisit later if needed.
18083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            engine.clearWithColor(0, 0, 0, 0);
1809b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian        } else {
1810766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we start with the whole screen area
1811766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region bounds(hw->getBounds());
1812766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1813766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we remove the scissor part
1814766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // we're left with the letterbox region
1815766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // (common case is that letterbox ends-up being empty)
1816766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Region letterbox(bounds.subtract(hw->getScissor()));
1817766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1818766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // compute the area to clear
1819766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            Region region(hw->undefinedRegion.merge(letterbox));
1820766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1821766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // but limit it to the dirty region
1822766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            region.andSelf(dirty);
1823766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian
1824b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            // screen is already cleared here
182587baae104a3e4c2059990b01c393476065c558b0Mathias Agopian            if (!region.isEmpty()) {
1826b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                // can happen with SurfaceView
182755801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian                drawWormhole(hw, region);
1828b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian            }
1829a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian        }
1830f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1831766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
1832766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            // just to be on the safe side, we don't set the
1833f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // scissor on the main display. It should never be needed
1834f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            // anyways (though in theory it could since the API allows it).
1835f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            const Rect& bounds(hw->getBounds());
1836766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian            const Rect& scissor(hw->getScissor());
1837f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            if (scissor != bounds) {
1838f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // scissor doesn't match the screen's dimensions, so we
1839f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // need to clear everything outside of it and enable
1840f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // the GL scissor so we don't draw anything where we shouldn't
18413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1842f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian                // enable scissor for this frame
18433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                const uint32_t height = hw->getHeight();
18443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                engine.setScissor(scissor.left, height - scissor.bottom,
18453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                        scissor.getWidth(), scissor.getHeight());
1846f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian            }
1847f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian        }
184885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    }
18494b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
185085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    /*
185185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     * and then, render the layers targeted at the framebuffer
185285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian     */
18534b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian
185413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
185585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const size_t count = layers.size();
185685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    const Transform& tr = hw->getTransform();
185785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    if (cur != end) {
185885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're using h/w composer
185985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
186013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
18614fec873a98f7b4380720cd1ad006f74c8cdc73daMathias Agopian            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
186285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
186385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                switch (cur->getCompositionType()) {
186403414a1cfe6c1222fd7723949bd622f9cba145aaRiley Andrews                    case HWC_CURSOR_OVERLAY:
186585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_OVERLAY: {
1866ac68302e1cde8b931073929311fd6654a3253fc7Mathias Agopian                        const Layer::State& state(layer->getDrawingState());
186785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
186885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && i
18694125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                                && layer->isOpaque(state) && (state.alpha == 0xFF)
187085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                                && hasGlesComposition) {
1871cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // never clear the very first layer since we're
1872cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            // guaranteed the FB is already cleared
1873cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                            layer->clearWithOpenGL(hw, clip);
1874cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        }
187585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
187685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    }
187785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    case HWC_FRAMEBUFFER: {
1878cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                        layer->draw(hw, clip);
187985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                        break;
1880a2f4e56fec0fb36c4a370eb23d6e9dc57f250b59Mathias Agopian                    }
1881da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    case HWC_FRAMEBUFFER_TARGET: {
1882da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // this should not happen as the iterator shouldn't
1883da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        // let us get there.
188486efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i);
1885da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                        break;
1886da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian                    }
1887cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian                }
1888a6b32db164e7834e211261046f3229bf50bc0098Jesse Hall            }
188985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            layer->setAcquireFence(hw, *cur);
189085d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        }
189185d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian    } else {
189285d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        // we're not using h/w composer
189385d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
189413127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(layers[i]);
189585d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            const Region clip(dirty.intersect(
189685d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                    tr.transform(layer->visibleRegion)));
189785d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            if (!clip.isEmpty()) {
189885d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian                layer->draw(hw, clip);
189985d751cba5d4386c739dbf9dd8f7bbf8c493ade9Mathias Agopian            }
19004b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian        }
19014b2ba53423ac2dc795a5a0bf72f6d787d9dc8950Mathias Agopian    }
1902f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian
1903f45c510009edab4a3e93f8d66b2e30aa26759fedMathias Agopian    // disable scissor at the end of the frame
19043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableScissor();
19053f121fc650d72d0103cef8e6a651093fb1589e0aMichael Lentine    return true;
1906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
190955801e41e6d7306d75d8134dd69d7d8cbbfbc63cMathias Agopian    const int32_t height = hw->getHeight();
19103f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
19113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
1912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1914ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianvoid SurfaceFlinger::addClientLayer(const sp<Client>& client,
1915ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        const sp<IBinder>& handle,
19166710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        const sp<IGraphicBufferProducer>& gbc,
191713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& lbc)
19181b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian{
191996f0819f81293076e652792794a961543e6750d7Mathias Agopian    // attach this layer to the client
1920ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    client->attachLayer(handle, lbc);
19214f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
192296f0819f81293076e652792794a961543e6750d7Mathias Agopian    // add this layer to the current state list
1923921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    Mutex::Autolock _l(mStateLock);
1924921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    mCurrentState.layersSortedByZ.add(lbc);
19256710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    mGraphicBufferProducerList.add(gbc->asBinder());
192696f0819f81293076e652792794a961543e6750d7Mathias Agopian}
192796f0819f81293076e652792794a961543e6750d7Mathias Agopian
19283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
192996f0819f81293076e652792794a961543e6750d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
193013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
1931edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (index >= 0) {
19326710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        mLayersPendingRemoval.push(layer);
1933076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mLayersRemoved = true;
19346710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        setTransactionFlags(eTransactionNeeded);
1935edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
1936edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
19373d57964a81cd631d80aa9575647e1ce35b5e82d5Mathias Agopian    return status_t(index);
1938edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1940c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozauint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
1941dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian    return android_atomic_release_load(&mTransactionFlags);
1942dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian}
1943dea20b1f343012d58ca9eb381684b26a168dc127Mathias Agopian
19443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
1945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return android_atomic_and(~flags, &mTransactionFlags) & flags;
1946edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
1949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1950edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((old & flags)==0) { // wake the server up
195199ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian        signalTransaction();
1952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return old;
1954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1955edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19568b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopianvoid SurfaceFlinger::setTransactionState(
19578b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<ComposerState>& state,
19588b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        const Vector<DisplayState>& displays,
19598b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian        uint32_t flags)
19608b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian{
19617c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis    ATRACE_CALL();
1962698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    Mutex::Autolock _l(mStateLock);
196328378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    uint32_t transactionFlags = 0;
1964e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
19652d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    if (flags & eAnimation) {
19662d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // For window updates that are part of an animation we must wait for
19672d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        // previous animation "frames" to be handled.
19682d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mAnimTransactionPending) {
19697c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
19702d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            if (CC_UNLIKELY(err != NO_ERROR)) {
19712d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                // just in case something goes wrong in SF, return to the
19727c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                // caller after a few seconds.
19737c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
19747c41bf7092b75dba6029cd3bbc842d3a2661b0aaJamie Gennis                        "waiting for previous animation frame");
19752d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mAnimTransactionPending = false;
19762d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                break;
19772d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            }
19782d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
19792d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis    }
19802d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis
1981e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    size_t count = displays.size();
1982e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1983e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const DisplayState& s(displays[i]);
1984e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        transactionFlags |= setDisplayStateLocked(s);
1985b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis    }
1986b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis
1987e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    count = state.size();
1988698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
1989698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        const ComposerState& s(state[i]);
1990d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // Here we need to check that the interface we're given is indeed
1991d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // one of our own. A malicious client could give us a NULL
1992d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // IInterface, or one of its own or even one of our own but a
1993d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // different type. All these situations would cause us to crash.
1994d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        //
1995d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // NOTE: it would be better to use RTTI as we could directly check
1996d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        // that we have a Client*. however, RTTI is disabled in Android.
1997d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        if (s.client != NULL) {
1998d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            sp<IBinder> binder = s.client->asBinder();
1999d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            if (binder != NULL) {
2000d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                String16 desc(binder->getInterfaceDescriptor());
2001d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                if (desc == ISurfaceComposerClient::descriptor) {
2002d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    sp<Client> client( static_cast<Client *>(s.client.get()) );
2003d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                    transactionFlags |= setClientStateLocked(client, s.state);
2004d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian                }
2005d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian            }
2006d17e3b5f6cf71eb52bc81f37719254ce08244b34Mathias Agopian        }
2007698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian    }
2008386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian
200928378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis    if (transactionFlags) {
2010386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // this triggers the transaction
201128378392fd5aa3e0a392c9eb64634055678c3987Jamie Gennis        setTransactionFlags(transactionFlags);
2012698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian
2013386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // if this is a synchronous transaction, wait for it to take effect
2014386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        // before returning.
2015386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        if (flags & eSynchronous) {
20162d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mTransactionPending = true;
20172d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        }
20182d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        if (flags & eAnimation) {
20192d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis            mAnimTransactionPending = true;
2020386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian        }
20212d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis        while (mTransactionPending) {
2022386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
2023386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            if (CC_UNLIKELY(err != NO_ERROR)) {
2024386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // just in case something goes wrong in SF, return to the
2025386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                // called after a few seconds.
20262d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
20272d5e230292c27d59f4c096bc742a0a19abf811c1Jamie Gennis                mTransactionPending = false;
2028386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian                break;
2029386aa98c4ffb9b805303e683f0a7b925b44d04dbMathias Agopian            }
2030cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        }
2031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2034e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
2035e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
20369a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
20379a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    if (dpyIdx < 0)
20389a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall        return 0;
20399a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall
2040e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
20419a14392256354538f1f43a5e80fe46c2c2b965cbJesse Hall    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
20423ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    if (disp.isValid()) {
2043e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2044e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eSurfaceChanged) {
2045e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.surface->asBinder() != s.surface->asBinder()) {
2046e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.surface = s.surface;
2047e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2048e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2049e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2050e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & DisplayState::eLayerStackChanged) {
2051e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.layerStack != s.layerStack) {
2052e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.layerStack = s.layerStack;
2053e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2054e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2055e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
205600e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        if (what & DisplayState::eDisplayProjectionChanged) {
2057e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.orientation != s.orientation) {
2058e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.orientation = s.orientation;
2059e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2060e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2061e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.frame != s.frame) {
2062e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.frame = s.frame;
2063e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2064e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2065e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (disp.viewport != s.viewport) {
2066e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                disp.viewport = s.viewport;
2067e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eDisplayTransactionNeeded;
2068e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2069e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
207047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        if (what & DisplayState::eDisplaySizeChanged) {
207147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.width != s.width) {
207247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.width = s.width;
207347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
207447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
207547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            if (disp.height != s.height) {
207647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                disp.height = s.height;
207747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                flags |= eDisplayTransactionNeeded;
207847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine            }
207947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine        }
2080e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2081e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2082e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2083e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
2084e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopianuint32_t SurfaceFlinger::setClientStateLocked(
2085e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const sp<Client>& client,
2086e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const layer_state_t& s)
2087e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian{
2088e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    uint32_t flags = 0;
208913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> layer(client->getLayerUser(s.surface));
2090e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    if (layer != 0) {
2091e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        const uint32_t what = s.what;
2092e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::ePositionChanged) {
2093e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setPosition(s.x, s.y))
2094e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2095e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2096e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerChanged) {
2097e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2098e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
2099e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayer(s.z)) {
2100e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2101e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2102e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2103e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2104e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2105e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2106e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2107e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eSizeChanged) {
2108e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setSize(s.w, s.h)) {
2109e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2110e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2111e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2112e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eAlphaChanged) {
2113e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
2114e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2115e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2116e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eMatrixChanged) {
2117e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setMatrix(s.matrix))
2118e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2119e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2120e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eTransparentRegionChanged) {
2121e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setTransparentRegionHint(s.transparentRegion))
2122e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2123e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
21244125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden        if ((what & layer_state_t::eVisibilityChanged) ||
21254125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden                (what & layer_state_t::eOpacityChanged)) {
21264125a4ffaf374ca9c0773f256998557d3325343eAndy McFadden            // TODO: should we just use an eFlagsChanged for this?
2127e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setFlags(s.flags, s.mask))
2128e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2129e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2130e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eCropChanged) {
2131e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setCrop(s.crop))
2132e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTraversalNeeded;
2133e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2134e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        if (what & layer_state_t::eLayerStackChanged) {
2135e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            // NOTE: index needs to be calculated before we update the state
2136e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
2137e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            if (layer->setLayerStack(s.layerStack)) {
2138e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.removeAt(idx);
2139e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                mCurrentState.layersSortedByZ.add(layer);
2140e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // we need traversal (state changed)
2141e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                // AND transaction (list changed)
2142e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                flags |= eTransactionNeeded|eTraversalNeeded;
2143e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian            }
2144e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        }
2145e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
2146e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    return flags;
2147e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
2148e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
21494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createLayer(
21500ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const String8& name,
21510ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian        const sp<Client>& client,
21524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
21534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
2154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
21554d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
21566e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    if (int32_t(w|h) < 0) {
2157921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
21586e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian                int(w), int(h));
21594d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        return BAD_VALUE;
21606e2d6483fe14362187c78c91dc03024fbb31d431Mathias Agopian    }
21618b42e8a5d87dcdc8ea31368ab88de49b72ab5432Andreas Huber
21624d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t result = NO_ERROR;
21634d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
21644d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    sp<Layer> layer;
21654d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
21663165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
21673165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceNormal:
21684d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createNormalLayer(client,
21694d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags, format,
21704d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
2171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
21723165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian        case ISurfaceComposerClient::eFXSurfaceDim:
21734d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = createDimLayer(client,
21744d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    name, w, h, flags,
21754d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp, &layer);
21764d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            break;
21774d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        default:
21784d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = BAD_VALUE;
2179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
2180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (result == NO_ERROR) {
21836710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        addClientLayer(client, *handle, *gbp, layer);
218496f0819f81293076e652792794a961543e6750d7Mathias Agopian        setTransactionFlags(eTransactionNeeded);
2185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
21864d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return result;
2187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21894d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
21904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
21914d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize the surfaces
219492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    switch (format) {
2195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSPARENT:
2196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_TRANSLUCENT:
2197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        format = PIXEL_FORMAT_RGBA_8888;
2198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case PIXEL_FORMAT_OPAQUE:
22008f10540cd59e980dcdb5a8f4f2dbec0d94177f5fMathias Agopian        format = PIXEL_FORMAT_RGBX_8888;
2201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
2202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new Layer(this, client, name, w, h, flags);
22054d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
22064d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    if (err == NO_ERROR) {
22074d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        *handle = (*outLayer)->getHandle();
2208b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza        *gbp = (*outLayer)->getProducer();
2209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
22104d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian
22114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
22124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return err;
2213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22154d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
22164d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
22174d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
2218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
22194d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *outLayer = new LayerDim(this, client, name, w, h, flags);
22204d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    *handle = (*outLayer)->getHandle();
2221b9b088375d33a87b201cdbe18be71802e2607717Dan Stoza    *gbp = (*outLayer)->getProducer();
22224d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian    return NO_ERROR;
2223118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
2224118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
2225ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
22269a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{
22276710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by the window manager when it wants to remove a Layer
22286710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    status_t err = NO_ERROR;
22296710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    sp<Layer> l(client->getLayerUser(handle));
22306710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    if (l != NULL) {
22316710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
22326710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
22336710604286401d4205c27235a252dd0e5008cc08Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
22349a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    }
22359a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian    return err;
22369a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian}
22379a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian
223813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianstatus_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
2239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
22406710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // called by ~LayerCleaner() when all references to the IBinder (handle)
22416710604286401d4205c27235a252dd0e5008cc08Mathias Agopian    // are gone
2242ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    status_t err = NO_ERROR;
224313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> l(layer.promote());
2244ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    if (l != NULL) {
22456710604286401d4205c27235a252dd0e5008cc08Mathias Agopian        err = removeLayer(l);
2246e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
2247ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian                "error removing layer=%p (%s)", l.get(), strerror(-err));
2248ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    }
2249ca4d3602c07837d0b2ac6878685a8e327b5f30f0Mathias Agopian    return err;
2250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2252b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2253b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
225413a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::onInitializeDisplays() {
225501e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    // reset screen orientation and use primary layer stack
225613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<ComposerState> state;
225713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    Vector<DisplayState> displays;
225813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    DisplayState d;
225901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.what = DisplayState::eDisplayProjectionChanged |
226001e29054e672301e4adbbca15b3562a59a20f267Jesse Hall             DisplayState::eLayerStackChanged;
2261692c723e84e6f2747447d871d468ff50e5c73f19Jesse Hall    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
226201e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    d.layerStack = 0;
226313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    d.orientation = DisplayState::eOrientationDefault;
22644c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.frame.makeInvalid();
22654c05dd175ee3bd5119eecf368742b6510a8cfa6cJeff Brown    d.viewport.makeInvalid();
226647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.width = 0;
226747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    d.height = 0;
226813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    displays.add(d);
226913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    setTransactionState(state, displays, 0);
22702c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
22716547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
22726547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const nsecs_t period =
22736547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
22746547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.setDisplayRefreshPeriod(period);
227513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
227613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
227713a082e160c2d1d8006b93a555a57035213d568bAndy McFaddenvoid SurfaceFlinger::initializeDisplays() {
227813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    class MessageScreenInitialized : public MessageBase {
227913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        SurfaceFlinger* flinger;
228013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    public:
228113a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
228213a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        virtual bool handler() {
228313a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            flinger->onInitializeDisplays();
228413a082e160c2d1d8006b93a555a57035213d568bAndy McFadden            return true;
228513a082e160c2d1d8006b93a555a57035213d568bAndy McFadden        }
228613a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    };
228713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    sp<MessageBase> msg = new MessageScreenInitialized(this);
228813a082e160c2d1d8006b93a555a57035213d568bAndy McFadden    postMessageAsync(msg);  // we may be called from main thread, use async message
228913a082e160c2d1d8006b93a555a57035213d568bAndy McFadden}
229013a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
22912c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
22922c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mode) {
22932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
22942c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            this);
22952c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int32_t type = hw->getDisplayType();
22962c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    int currentMode = hw->getPowerMode();
229713a082e160c2d1d8006b93a555a57035213d568bAndy McFadden
22982c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (mode == currentMode) {
22992c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
2300c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        return;
2301c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    }
2302c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
23032c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    hw->setPowerMode(mode);
23042c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
23052c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        ALOGW("Trying to set power mode for virtual display");
23062c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        return;
23072c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2308c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
23092c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    if (currentMode == HWC_POWER_MODE_OFF) {
23102c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2311c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2312c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            // FIXME: eventthread only knows about the main display right now
2313c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden            mEventThread->onScreenAcquired();
2314948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            resyncToHardwareVsync(true);
2315c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        }
2316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
23182c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        repaintEverything();
23192c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else if (mode == HWC_POWER_MODE_OFF) {
2320c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden        if (type == DisplayDevice::DISPLAY_PRIMARY) {
2321948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall            disableHardwareVsync(true); // also cancels any in-progress resync
2322948fe0ce74c13e1bbff233883c158519fa8fb293Jesse Hall
2323cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            // FIXME: eventthread only knows about the main display right now
2324cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian            mEventThread->onScreenReleased();
2325cde87a3b9d3f8dc15232d927b56ee9e5e520f58dMathias Agopian        }
2326c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden
23272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
23282c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        mVisibleRegionsDirty = true;
23292c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        // from this point on, SF will stop drawing on this display
23302c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    } else {
23312c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        getHwComposer().setPowerMode(type, mode);
2332b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    }
2333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23352c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
23362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    class MessageSetPowerMode: public MessageBase {
2337db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        SurfaceFlinger& mFlinger;
2338db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian        sp<IBinder> mDisplay;
23392c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        int mMode;
2340b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    public:
23412c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        MessageSetPowerMode(SurfaceFlinger& flinger,
23422c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
23432c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                    mDisplay(disp) { mMode = mode; }
2344b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        virtual bool handler() {
23452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
2346db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            if (hw == NULL) {
23472c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGE("Attempt to set power mode = %d for null display %p",
23487306c670eb3ddb471d983a7458eb9f522afd0763Michael Lentine                        mMode, mDisplay.get());
23499e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
23502c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                ALOGW("Attempt to set power mode = %d for virtual display",
23512c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                        mMode);
2352db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            } else {
23532c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                mFlinger.setPowerModeInternal(hw, mMode);
2354db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian            }
2355b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian            return true;
2356b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian        }
2357b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian    };
23582c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
2359db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    postMessageSync(msg);
2360b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian}
2361b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2362b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian// ---------------------------------------------------------------------------
2363b60314a12f3336b27d73920805ab07cbc498d857Mathias Agopian
2364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
2365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String8 result;
236799b49840d309727678b77403d6cc9f920111623fMathias Agopian
2368bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    IPCThreadState* ipc = IPCThreadState::self();
2369bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int pid = ipc->getCallingPid();
2370bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    const int uid = ipc->getCallingUid();
2371bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian    if ((uid != AID_SHELL) &&
2372bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian            !PermissionCache::checkPermission(sDump, pid, uid)) {
237374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("Permission Denial: "
2374bd1153382e7a9d89922bea999a52ca21d46d6caaMathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
2375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
23769795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // Try to get the main lock, but don't insist if we can't
23779795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // (this would indicate SF is stuck, but we want to be able to
23789795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        // print something in dumpsys).
23799795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        int retry = 3;
23809795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        while (mStateLock.tryLock()<0 && --retry>=0) {
23819795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian            usleep(1000000);
23829795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
23839795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        const bool locked(retry >= 0);
23849795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        if (!locked) {
238574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            result.append(
23869795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "SurfaceFlinger appears to be unresponsive, "
23879795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian                    "dumping anyways (no locks held)\n");
23889795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian        }
23899795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
239082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        bool dumpAll = true;
239182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        size_t index = 0;
239225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        size_t numArgs = args.size();
239325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (numArgs) {
239425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
239525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--list"))) {
239625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
239774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                listLayersLocked(args, index, result);
239835aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
239925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
240025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
240125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
240225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency"))) {
240382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian                index++;
240474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                dumpStatsLocked(args, index, result);
240535aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
240682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            }
240725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
240825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            if ((index < numArgs) &&
240925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                    (args[index] == String16("--latency-clear"))) {
241025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian                index++;
241174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian                clearStatsLocked(args, index, result);
241235aadd6be249da4bd4851692e6aff757c91b32a7Mathias Agopian                dumpAll = false;
241325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian            }
2414c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden
2415c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            if ((index < numArgs) &&
2416c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                    (args[index] == String16("--dispsync"))) {
2417c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                index++;
2418c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                mPrimaryDispSync.dump(result);
2419c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden                dumpAll = false;
2420c751e92c56de5f335a36e68607c7a6c627dcd0dcAndy McFadden            }
2421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
24221b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
242382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (dumpAll) {
242474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian            dumpAllLocked(args, index, result);
242582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
242648b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
242782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        if (locked) {
242882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mStateLock.unlock();
242948b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian        }
243082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
243182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    write(fd, result.string(), result.size());
243282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    return NO_ERROR;
243382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
243448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
2435c701401f8cec2e5309f8b57e2b97baced5093274Dan Stozavoid SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
2436c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        size_t& /* index */, String8& result) const
243725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
243825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
243925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
244025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
244113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
244274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        result.appendFormat("%s\n", layer->getName().string());
244325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
244425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
244525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
244682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopianvoid SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
244774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
244882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
244982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    String8 name;
245082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    if (index < args.size()) {
245182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        name = String8(args[index]);
245282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        index++;
245382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
245448b888aab9fdcfba250722dffbdffe61f11c64f3Mathias Agopian
24554b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    const nsecs_t period =
24564b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
245786efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("%" PRId64 "\n", period);
24584b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
24594b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    if (name.isEmpty()) {
2460d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        mAnimFrameTracker.dumpStats(result);
24614b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis    } else {
24624b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
24634b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        const size_t count = currentLayers.size();
24644b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis        for (size_t i=0 ; i<count ; i++) {
246513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian            const sp<Layer>& layer(currentLayers[i]);
24664b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            if (name == layer->getName()) {
2467d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav                layer->dumpFrameStats(result);
24684b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis            }
246982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian        }
247082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
247182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian}
2472ad70186f80355e55ddad2a66b5fd174a1c019c2dMathias Agopian
247325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopianvoid SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
2474c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        String8& /* result */)
247525e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian{
247625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    String8 name;
247725e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    if (index < args.size()) {
247825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        name = String8(args[index]);
247925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        index++;
248025e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
248125e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
248225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
248325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    const size_t count = currentLayers.size();
248425e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
248513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
248625e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        if (name.isEmpty() || (name == layer->getName())) {
2487d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav            layer->clearFrameStats();
248825e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian        }
248925e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian    }
24904b0eba949cc026ffb2c75313042d8a7bcb3fcf86Jamie Gennis
2491d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    mAnimFrameTracker.clearStats();
249225e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian}
249325e66fc324bbc004fa8902b2d4699e41bb601104Mathias Agopian
24946547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// This should only be called from the main thread.  Otherwise it would need
24956547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis// the lock and should use mCurrentState rather than mDrawingState.
24966547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennisvoid SurfaceFlinger::logFrameStats() {
24976547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
24986547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    const size_t count = drawingLayers.size();
24996547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    for (size_t i=0 ; i<count ; i++) {
25006547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        const sp<Layer>& layer(drawingLayers[i]);
25016547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis        layer->logFrameStats();
25026547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    }
25036547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
25046547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
25056547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis}
25066547ff4327aa320fbc9635668d3fc66db7dd78f6Jamie Gennis
25074803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
25084803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden{
25094803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    static const char* config =
25104803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " [sf"
25114803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef HAS_CONTEXT_PRIORITY
25124803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " HAS_CONTEXT_PRIORITY"
25134803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
25144803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
25154803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " NEVER_DEFAULT_TO_ASYNC_MODE"
25164803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
25174803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
25184803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            " TARGET_DISABLE_TRIPLE_BUFFERING"
25194803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden#endif
25204803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden            "]";
25214803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append(config);
25224803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden}
25234803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
252474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
252574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        String8& result) const
252682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian{
25273e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    bool colorize = false;
25283e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    if (index < args.size()
25293e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            && (args[index] == String16("--color"))) {
25303e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        colorize = true;
25313e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        index++;
25323e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    }
25333e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
25343e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    Colorizer colorizer(colorize);
25353e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
253682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    // figure out if we're stuck somewhere
253782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t now = systemTime();
253882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
253982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const nsecs_t inTransaction(mDebugInTransaction);
254082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
254182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
2542bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
254382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
25444803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     * Dump library configuration.
25454803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden     */
25463e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian
25473e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
25484803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("Build configuration:");
25493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
25504803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendSfConfigString(result);
25514803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendUiConfigString(result);
25524803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    appendGuiConfigString(result);
25534803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    result.append("\n");
25544803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden
25553e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
2556ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("Sync configuration: ");
25573e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
2558ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append(SyncFeatures::getInstance().toString());
2559ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian    result.append("\n");
2560ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
256141d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.bold(result);
256241d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("DispSync configuration: ");
256341d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    colorizer.reset(result);
256424cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
256524cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            "present offset %d ns (refresh %" PRId64 " ns)",
256641d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS,
256741d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden        mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY));
256841d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden    result.append("\n");
256941d67d7ab4da1c393497a620a116a854b3c618e7Andy McFadden
25704803b74e2a12a508f7bbfde6f6a962fe3299c61cAndy McFadden    /*
257182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump the visible layer list
257282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
257382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
257482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const size_t count = currentLayers.size();
25753e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
257686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Visible layers (count = %zu)\n", count);
25773e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
257882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    for (size_t i=0 ; i<count ; i++) {
257913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(currentLayers[i]);
25803e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian        layer->dump(result, colorizer);
258182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    }
2582bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
258382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
25845f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     * Dump Display state
25855f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian     */
25865f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
25873e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
258886efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
25893e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
25905f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
25915f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
259274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian        hw->dump(result);
25935f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    }
25945f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
25955f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    /*
259682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump SurfaceFlinger global state
259782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
25981b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
25993e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
260074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("SurfaceFlinger global state:\n");
26013e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
26021b5e1021b8c9b87113b70d94dfb7b50f8c5b01b8Mathias Agopian
2603888c822c4cb6976aab9256c58bae9e17e3e55c5cMathias Agopian    HWComposer& hwc(getHwComposer());
26044297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
2605ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
26063e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
26073e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("EGL implementation : %s\n",
26083e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
26093e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
26103e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    result.appendFormat("%s\n",
2611ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
2612ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian
2613875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mRenderEngine->dump(result);
26149795c42e557cfa37b9fd353ef7a2a7977a77f504Mathias Agopian
26154297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    hw->undefinedRegion.dump(result, "undefinedRegion");
26162c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
26172c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani            hw->getOrientation(), hw->isDisplayOn());
261874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
261982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last eglSwapBuffers() time: %f us\n"
262082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  last transaction time     : %f us\n"
2621c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            "  transaction-flags         : %08x\n"
262282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  refresh-rate              : %f fps\n"
262382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            "  x-dpi                     : %f\n"
2624ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  y-dpi                     : %f\n"
2625ed985574148a938bc3af24442eead313cc62521cMathias Agopian            "  gpu_to_cpu_unsupported    : %d\n"
2626ed985574148a938bc3af24442eead313cc62521cMathias Agopian            ,
262782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastSwapBufferTime/1000.0,
262882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            mLastTransactionTime/1000.0,
2629c95dbdc236acf002b5f8aed8c8a9e43047fc75b5Mathias Agopian            mTransactionFlags,
2630b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
2631b0d1dd36f104c0b581674adc7f830cbf44b7db06Andy McFadden            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
2632ed985574148a938bc3af24442eead313cc62521cMathias Agopian            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
2633ed985574148a938bc3af24442eead313cc62521cMathias Agopian            !mGpuToCpuSupported);
263482d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
263574d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  eglSwapBuffers time: %f us\n",
263682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inSwapBuffersDuration/1000.0);
263782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
263874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  transaction time: %f us\n",
263982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            inTransactionDuration/1000.0);
264082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
264182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
264282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * VSYNC state
264382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
264474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    mEventThread->dump(result);
264582d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
264682d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
264782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump HWComposer state
264882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
26493e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.bold(result);
265074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.append("h/w composer state:\n");
26513e25fd8609b100a75721be82d1d499f0ae9083cbMathias Agopian    colorizer.reset(result);
265274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat("  h/w composer %s and %s\n",
265382d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian            hwc.initCheck()==NO_ERROR ? "present" : "not present",
26549c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    (mDebugDisableHWC || mDebugRegion || mDaltonize
26559c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                            || mHasColorMatrix) ? "disabled" : "enabled");
265674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    hwc.dump(result);
265782d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian
265882d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    /*
265982d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     * Dump gralloc state
266082d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian     */
266182d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
266282d7ab6c7e0cf971e515134ccf072682dd1a2cdbMathias Agopian    alloc.dump(result);
2663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
266513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >&
266648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse HallSurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
2667db9b41fd157279d1b988a854e0d7c5b43c2fac38Mathias Agopian    // Note: mStateLock is held here
266848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    wp<IBinder> dpy;
266948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    for (size_t i=0 ; i<mDisplays.size() ; i++) {
267048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
267148bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            dpy = mDisplays.keyAt(i);
267248bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall            break;
267348bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        }
267448bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
267548bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    if (dpy == NULL) {
267648bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
267748bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        // Just use the primary display so we have something to return
267848bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
267948bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    }
268048bc05b56df9919fc39c5f2e3ea6535560eec98fJesse Hall    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
2681cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian}
2682cb55857bbde34a06c19dde3db5064d1717a0173eMathias Agopian
268363f165fd6b86d04be94d4023e845e98560504a96Keun young Parkbool SurfaceFlinger::startDdmConnection()
268463f165fd6b86d04be94d4023e845e98560504a96Keun young Park{
268563f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void* libddmconnection_dso =
268663f165fd6b86d04be94d4023e845e98560504a96Keun young Park            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
268763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!libddmconnection_dso) {
268863f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
268963f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
269063f165fd6b86d04be94d4023e845e98560504a96Keun young Park    void (*DdmConnection_start)(const char* name);
269163f165fd6b86d04be94d4023e845e98560504a96Keun young Park    DdmConnection_start =
269224cd98eef88ac93f80c327f8d74f0a1ae0aceee4Jesse Hall            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
269363f165fd6b86d04be94d4023e845e98560504a96Keun young Park    if (!DdmConnection_start) {
269463f165fd6b86d04be94d4023e845e98560504a96Keun young Park        dlclose(libddmconnection_dso);
269563f165fd6b86d04be94d4023e845e98560504a96Keun young Park        return false;
269663f165fd6b86d04be94d4023e845e98560504a96Keun young Park    }
269763f165fd6b86d04be94d4023e845e98560504a96Keun young Park    (*DdmConnection_start)(getServiceName());
269863f165fd6b86d04be94d4023e845e98560504a96Keun young Park    return true;
269963f165fd6b86d04be94d4023e845e98560504a96Keun young Park}
270063f165fd6b86d04be94d4023e845e98560504a96Keun young Park
2701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t SurfaceFlinger::onTransact(
2702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
2703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
2704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (code) {
2705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case CREATE_CONNECTION:
2706041a075262ef5fc886e46fd4eec3dd79ee2e60c0Mathias Agopian        case CREATE_DISPLAY:
2707698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian        case SET_TRANSACTION_STATE:
2708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case BOOT_FINISHED:
2709d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case CLEAR_ANIMATION_FRAME_STATS:
2710d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        case GET_ANIMATION_FRAME_STATS:
27112c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani        case SET_POWER_MODE:
2712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
2713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // codes that require permission check
2714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            IPCThreadState* ipc = IPCThreadState::self();
2715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const int pid = ipc->getCallingPid();
2716a1ecca920e15ce04fe56ebf4f1b52ba711f9eb2dMathias Agopian            const int uid = ipc->getCallingUid();
271799b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
271899b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
2719e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
2720375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2721375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                return PERMISSION_DENIED;
2722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
27231b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
27241b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        }
27251b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        case CAPTURE_SCREEN:
27261b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian        {
27271b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            // codes that require permission check
27281b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
27291b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int pid = ipc->getCallingPid();
27301b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            const int uid = ipc->getCallingUid();
273199b49840d309727678b77403d6cc9f920111623fMathias Agopian            if ((uid != AID_GRAPHICS) &&
273299b49840d309727678b77403d6cc9f920111623fMathias Agopian                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
2733e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                ALOGE("Permission Denial: "
27341b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
27351b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian                return PERMISSION_DENIED;
27361b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            }
27371b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian            break;
2738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
27401b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
2741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
2742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
2743b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        CHECK_INTERFACE(ISurfaceComposer, data, reply);
274499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
2745375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            IPCThreadState* ipc = IPCThreadState::self();
2746375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int pid = ipc->getCallingPid();
2747375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian            const int uid = ipc->getCallingUid();
2748e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Permission Denial: "
2749375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
2750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return PERMISSION_DENIED;
2751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int n;
2753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        switch (code) {
275401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
275535b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
2756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1002:  // SHOW_UPDATES
2758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                n = data.readInt32();
2759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
276053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
276153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1004:{ // repaint everything
276453331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
2765cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2766cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
2767cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            case 1005:{ // force transaction
2768e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                setTransactionFlags(
2769e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTransactionNeeded|
2770e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eDisplayTransactionNeeded|
2771e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian                        eTraversalNeeded);
2772cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                return NO_ERROR;
2773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
27744d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            case 1006:{ // send empty update
27754d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                signalRefresh();
27764d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian                return NO_ERROR;
27774d143eed994778d37eb09bb5d452c26f12bca6e1Mathias Agopian            }
277853331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian            case 1008:  // toggle use of hw composer
277953331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                n = data.readInt32();
278053331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                mDebugDisableHWC = n ? 1 : 0;
278153331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                invalidateHwcGeometry();
278253331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                repaintEverything();
278353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian                return NO_ERROR;
2784a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian            case 1009:  // toggle use of transform hint
2785a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                n = data.readInt32();
2786a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                mDebugDisableTransformHint = n ? 1 : 0;
2787a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                invalidateHwcGeometry();
2788a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                repaintEverything();
2789a45836466c301d49d8df286b5317dfa99cb83b70Mathias Agopian                return NO_ERROR;
2790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1010:  // interrogate.
279101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian                reply->writeInt32(0);
2792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(0);
2793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                reply->writeInt32(mDebugRegion);
2794b9494d5c9d44e4a59b6d510fea1665de434f3c6bMathias Agopian                reply->writeInt32(0);
279512839bee29bdcc65731b4d42029cc59e2320c5c4Dianne Hackborn                reply->writeInt32(mDebugDisableHWC);
2796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return NO_ERROR;
2797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case 1013: {
2798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                Mutex::Autolock _l(mStateLock);
27994297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
28004297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian                reply->writeInt32(hw->getPageFlipCount());
2801ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                return NO_ERROR;
2802ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            }
2803ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian            case 1014: {
2804ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                // daltonize
2805ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                n = data.readInt32();
2806ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                switch (n % 10) {
2807ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 1: mDaltonizer.setType(Daltonizer::protanomaly);   break;
2808ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 2: mDaltonizer.setType(Daltonizer::deuteranomaly); break;
2809ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    case 3: mDaltonizer.setType(Daltonizer::tritanomaly);   break;
2810ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2811ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                if (n >= 10) {
2812ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::correction);
2813ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                } else {
2814ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                    mDaltonizer.setMode(Daltonizer::simulation);
2815ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                }
2816ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                mDaltonize = n > 0;
2817ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                invalidateHwcGeometry();
2818ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian                repaintEverything();
28199c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
28209c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            }
28219c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette            case 1015: {
28229c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                // apply a color matrix
28239c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                n = data.readInt32();
28249c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                mHasColorMatrix = n ? 1 : 0;
28259c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                if (n) {
28269c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // color matrix is sent as mat3 matrix followed by vec3
28279c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // offset, then packed into a mat4 where the last row is
28289c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    // the offset and extra values are 0
2829794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                    for (size_t i = 0 ; i < 4; i++) {
2830794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      for (size_t j = 0; j < 4; j++) {
2831794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                          mColorMatrix[i][j] = data.readFloat();
2832794c5ba973f6d107a8277f3f389cb3051c6ce5d7Alan Viverette                      }
28339c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    }
28349c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                } else {
28359c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                    mColorMatrix = mat4();
28369c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                }
28379c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                invalidateHwcGeometry();
28389c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                repaintEverything();
28399c5a3335110769993d3fe997bdf1d594954d4304Alan Viverette                return NO_ERROR;
2840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
2841f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // This is an experimental interface
2842f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            // Needs to be shifted to proper binder interface when we productize
2843f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            case 1016: {
2844645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                n = data.readInt32();
2845645b1f7ffb41d21a60765d1ec54ba82f14a36a59Andy McFadden                mPrimaryDispSync.setRefreshSkipCount(n);
2846f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi                return NO_ERROR;
2847f52b3c88f18c0546526996c839fbce74172e11c7Ruchi Kandoi            }
2848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
2849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
2850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return err;
2851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
2852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
285353331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopianvoid SurfaceFlinger::repaintEverything() {
285487baae104a3e4c2059990b01c393476065c558b0Mathias Agopian    android_atomic_or(1, &mRepaintEverything);
285599ce5cdeb383216dee95af4d90e47406b0948ea1Mathias Agopian    signalTransaction();
285653331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian}
285753331da007b56e0cb4201728de99c8c29bcfaa9aMathias Agopian
285859119e658a12279e8fff508f8773843de2d90917Mathias Agopian// ---------------------------------------------------------------------------
28592a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// Capture screen into an IGraphiBufferProducer
28602a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian// ---------------------------------------------------------------------------
286159119e658a12279e8fff508f8773843de2d90917Mathias Agopian
28622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian/* The code below is here to handle b/8734824
28632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian *
28642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian * We create a IGraphicBufferProducer wrapper that forwards all calls
2865b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * from the surfaceflinger thread to the calling binder thread, where they
2866b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * are executed. This allows the calling thread in the calling process to be
2867b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * reused and not depend on having "enough" binder threads to handle the
2868b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall * requests.
28692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian */
28702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianclass GraphicProducerWrapper : public BBinder, public MessageHandler {
2871b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    /* Parts of GraphicProducerWrapper are run on two different threads,
2872b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * communicating by sending messages via Looper but also by shared member
2873b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * data. Coherence maintenance is subtle and in places implicit (ugh).
2874b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
2875b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Don't rely on Looper's sendMessage/handleMessage providing
2876b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * release/acquire semantics for any data not actually in the Message.
2877b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Data going from surfaceflinger to binder threads needs to be
2878b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * synchronized explicitly.
2879b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     *
2880b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Barrier open/wait do provide release/acquire semantics. This provides
2881b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * implicit synchronization for data coming back from binder to
2882b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * surfaceflinger threads.
2883b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     */
2884b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
28852ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<IGraphicBufferProducer> impl;
28862ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<Looper> looper;
28872ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t result;
28882ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitPending;
28892ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    bool exitRequested;
2890b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    Barrier barrier;
28912ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    uint32_t code;
28922ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel const* data;
28932ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    Parcel* reply;
28942ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
28952ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    enum {
28962ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_API_CALL,
28972ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        MSG_EXIT
28982ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    };
28992ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29002ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
2901b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * Called on surfaceflinger thread. This is called by our "fake"
2902b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * BpGraphicBufferProducer. We package the data and reply Parcel and
2903b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * forward them to the binder thread.
29042ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
29052ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual status_t transact(uint32_t code,
2906c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
29072ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->code = code;
29082ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->data = &data;
29092ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        this->reply = reply;
29102ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        if (exitPending) {
2911b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // if we've exited, we run the message synchronously right here.
2912b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // note (JH): as far as I can tell from looking at the code, this
2913b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // never actually happens. if it does, i'm not sure if it happens
2914b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // on the surfaceflinger or binder thread.
29152ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            handleMessage(Message(MSG_API_CALL));
29162ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } else {
29172ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.close();
2918b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // Prevent stores to this->{code, data, reply} from being
2919b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            // reordered later than the construction of Message.
2920b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall            atomic_thread_fence(memory_order_release);
29212ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->sendMessage(this, Message(MSG_API_CALL));
29222ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.wait();
29232ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
2924c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng        return result;
29252ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
29262ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29272ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    /*
2928b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall     * here we run on the binder thread. All we've got to do is
29292ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     * call the real BpGraphicBufferProducer.
29302ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian     */
29312ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    virtual void handleMessage(const Message& message) {
2932b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        int what = message.what;
2933b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Prevent reads below from happening before the read from Message
2934b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_acquire);
2935b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        if (what == MSG_API_CALL) {
2936c2633ce19bdbca4cbf8d6a225ede68a0afd693b9bdeng            result = impl->asBinder()->transact(code, data[0], reply);
29372ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            barrier.open();
2938b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        } else if (what == MSG_EXIT) {
29392ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            exitRequested = true;
29402ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        }
29412ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
29422ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29432ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopianpublic:
2944b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
2945b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    :   impl(impl),
2946b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        looper(new Looper(true)),
2947b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitPending(false),
2948b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        exitRequested(false)
2949b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    {}
2950b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall
2951b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Binder thread
29522ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t waitForResponse() {
29532ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        do {
29542ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            looper->pollOnce(-1);
29552ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        } while (!exitRequested);
29562ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        return result;
29572ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
29582ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
2959b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall    // Client thread
29602ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    void exit(status_t result) {
2961aaff4ef717c08f6aed7ccd96e1d65222ceb4fd17Mike J. Chen        this->result = result;
29622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        exitPending = true;
2963b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // Ensure this->result is visible to the binder thread before it
2964b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        // handles the message.
2965b154c42c39c1499c26d88fff8ca642cd86f91098Jesse Hall        atomic_thread_fence(memory_order_release);
29662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        looper->sendMessage(this, Message(MSG_EXIT));
29672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    }
29682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian};
29692ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
29712a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
29722a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
2973c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
2974c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
2975c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
29762a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
29772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(display == 0))
29782a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
29792a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
29802a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (CC_UNLIKELY(producer == 0))
29812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        return BAD_VALUE;
29822a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
29835ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // if we have secure windows on this display, never allow the screen capture
29845ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // unless the producer interface is local (i.e.: we can take a screenshot for
29855ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    // ourselves).
29865ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    if (!producer->asBinder()->localBinder()) {
29875ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        Mutex::Autolock _l(mStateLock);
29885ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        sp<const DisplayDevice> hw(getDisplayDevice(display));
29895ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        if (hw->getSecureLayerVisible()) {
29905ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            ALOGW("FB is protected: PERMISSION_DENIED");
29915ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian            return PERMISSION_DENIED;
29925ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian        }
29935ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian    }
29945ff5a84e4829bad9eb44cc9a32d8579ca089051bMathias Agopian
2995c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Convert to surfaceflinger's internal rotation type.
2996c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    Transform::orientation_flags rotationFlags;
2997c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
2998c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotateNone:
2999c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3000c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3001c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate90:
3002c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_90;
3003c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3004c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate180:
3005c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_180;
3006c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3007c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case ISurfaceComposer::eRotate270:
3008c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_270;
3009c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3010c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
3011c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            rotationFlags = Transform::ROT_0;
3012c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
3013c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
3014c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
3015c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
30162a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    class MessageCaptureScreen : public MessageBase {
30172a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        SurfaceFlinger* flinger;
30182a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IBinder> display;
30192a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        sp<IGraphicBufferProducer> producer;
3020c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop;
30212a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t reqWidth, reqHeight;
30222a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        uint32_t minLayerZ,maxLayerZ;
3023c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        bool useIdentityTransform;
3024c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation;
30252a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t result;
30262a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    public:
30272a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        MessageCaptureScreen(SurfaceFlinger* flinger,
30282a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IBinder>& display,
30292a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                const sp<IGraphicBufferProducer>& producer,
3030c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3031c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                uint32_t minLayerZ, uint32_t maxLayerZ,
3032c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                bool useIdentityTransform, Transform::orientation_flags rotation)
30332a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            : flinger(flinger), display(display), producer(producer),
3034c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
30352a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
3036c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza              useIdentityTransform(useIdentityTransform),
3037c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews              rotation(rotation),
30382a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian              result(PERMISSION_DENIED)
30392a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        {
30402a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
30412a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        status_t getResult() const {
30422a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return result;
30432a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
30442a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        virtual bool handler() {
30452a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            Mutex::Autolock _l(flinger->mStateLock);
30462a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
3047c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            result = flinger->captureScreenImplLocked(hw, producer,
3048c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3049c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                    useIdentityTransform, rotation);
30502ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
30512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            return true;
30522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        }
30532a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    };
30542a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
30559eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // make sure to process transactions before screenshots -- a transaction
30569eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // might already be pending but scheduled for VSYNC; this guarantees we
30579eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // will handle it before the screenshot. When VSYNC finally arrives
30589eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // the scheduled transaction will be a no-op. If no transactions are
30599eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    // scheduled at this time, this will end-up being a no-op as well.
30609eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian    mEventQueue.invalidateTransactionNow();
30619eb1f0558b5fc78920602afe7bcfa3115bb1f6beMathias Agopian
30622ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // this creates a "fake" BBinder which will serve as a "fake" remote
30632ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // binder to receive the marshaled calls and forward them to the
30642ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // real remote (a BpGraphicBufferProducer)
30652ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
30662ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
30672ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
30682ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    // which does the marshaling work forwards to our "fake remote" above.
30692a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    sp<MessageBase> msg = new MessageCaptureScreen(this,
30702ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian            display, IGraphicBufferProducer::asInterface( wrapper ),
3071c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
3072c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            useIdentityTransform, rotationFlags);
30732ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian
30742ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian    status_t res = postMessageAsync(msg);
30752a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    if (res == NO_ERROR) {
30762ed0fe59b482f8d6b35a50ebc8e9e060813f4568Mathias Agopian        res = wrapper->waitForResponse();
30772a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    }
30782a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian    return res;
3079118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian}
3080118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian
3081180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3082180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopianvoid SurfaceFlinger::renderScreenImplLocked(
3083180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<const DisplayDevice>& hw,
3084c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3085180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        uint32_t minLayerZ, uint32_t maxLayerZ,
3086c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
3087180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian{
3088180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    ATRACE_CALL();
30893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    RenderEngine& engine(getRenderEngine());
3090180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3091180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
3092180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
3093180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
3094180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const bool filtering = reqWidth != hw_w || reqWidth != hw_h;
3095180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3096c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // if a default or invalid sourceCrop is passed in, set reasonable values
3097c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
3098c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            !sourceCrop.isValid()) {
3099c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setLeftTop(Point(0, 0));
3100c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        sourceCrop.setRightBottom(Point(hw_w, hw_h));
3101c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3102c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3103c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // ensure that sourceCrop is inside screen
3104c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.left < 0) {
3105c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
3106c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3107784421160727c434c2a2897ed3345445fcc30f75Jesse Hall    if (static_cast<uint32_t>(sourceCrop.right) > hw_w) {
3108be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
3109c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3110c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (sourceCrop.top < 0) {
3111c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
3112c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3113784421160727c434c2a2897ed3345445fcc30f75Jesse Hall    if (static_cast<uint32_t>(sourceCrop.bottom) > hw_h) {
3114be31f447984b3ab4ac011353b6b53216b4335e04Dan Stoza        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
3115c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
3116c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
3117180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // make sure to clear all GL error flags
31183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.checkErrors();
3119180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3120180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // set-up our viewport
3121c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    engine.setViewportAndProjection(
3122c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
31233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.disableTexturing();
3124180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3125180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // redraw the screen entirely...
31263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    engine.clearWithColor(0, 0, 0, 1);
3127180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3128180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const LayerVector& layers( mDrawingState.layersSortedByZ );
3129180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const size_t count = layers.size();
3130180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    for (size_t i=0 ; i<count ; ++i) {
3131180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        const sp<Layer>& layer(layers[i]);
31321eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian        const Layer::State& state(layer->getDrawingState());
3133180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        if (state.layerStack == hw->getLayerStack()) {
3134180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
3135180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                if (layer->isVisible()) {
3136180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(true);
3137c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza                    layer->draw(hw, useIdentityTransform);
3138180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                    if (filtering) layer->setFiltering(false);
3139180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                }
3140180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian            }
3141180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        }
3142180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3143180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3144180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // compositionComplete is needed for older driver
3145180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    hw->compositionComplete();
3146931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    hw->setViewportAndProjection();
3147180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian}
3148180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3149180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
31502a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopianstatus_t SurfaceFlinger::captureScreenImplLocked(
31512a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<const DisplayDevice>& hw,
31522a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
3153c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
3154c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza        uint32_t minLayerZ, uint32_t maxLayerZ,
3155c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        bool useIdentityTransform, Transform::orientation_flags rotation)
315674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian{
3157fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian    ATRACE_CALL();
3158fddc28d87136b55f0d9613e5f8ecd64a6aca018dMathias Agopian
3159180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    // get screen geometry
3160180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_w = hw->getWidth();
3161180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    const uint32_t hw_h = hw->getHeight();
3162180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3163180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
3164180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        ALOGE("size mismatch (%d, %d) > (%d, %d)",
3165180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian                reqWidth, reqHeight, hw_w, hw_h);
3166180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian        return BAD_VALUE;
3167180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    }
3168180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
3169180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
3170180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian    reqHeight = (!reqHeight) ? hw_h : reqHeight;
3171180f10de6f504d2ba56ff32ae8ed53c58bb458e9Mathias Agopian
31720aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // create a surface (because we're a producer, and we need to
31730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    // dequeue/queue a buffer)
317483cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    sp<Surface> sur = new Surface(producer, false);
31750aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    ANativeWindow* window = sur.get();
317674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
31770aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    status_t result = NO_ERROR;
31780aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian    if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) {
31793ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
31803ca76f416bc8665a97636ca8a2d0128b9da9d92cMathias Agopian                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
31812a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
31820aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        int err = 0;
31830aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
31844ceff3d5efd27c164788bb2b3f0fd17c691a0204Mathias Agopian        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
31850aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
31860aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        err |= native_window_set_usage(window, usage);
31872a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian
31880aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        if (err == NO_ERROR) {
31890aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            ANativeWindowBuffer* buffer;
31900aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            /* TODO: Once we have the sync framework everywhere this can use
31910aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             * server-side waits on the fence that dequeueBuffer returns.
31920aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian             */
31930aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
31940aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            if (result == NO_ERROR) {
3195866399093f9f60e7305f291e688abb456bace710Riley Andrews                int syncFd = -1;
31960aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // create an EGLImage from the buffer so we can later
31970aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                // turn it into a texture
31980aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
31990aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
32000aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                if (image != EGL_NO_IMAGE_KHR) {
32013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // this binds the given EGLImage as a framebuffer for the
32023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    // duration of this scope.
32033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
32043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                    if (imageBond.getStatus() == NO_ERROR) {
32050aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // this will in fact render into our dequeued buffer
32060aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // via an FBO, which means we didn't have to create
32070aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // an EGLSurface and therefore we're not
32080aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        // dependent on the context's EGLConfig.
3209c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                        renderScreenImplLocked(
3210c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
3211c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews                            useIdentityTransform, rotation);
3212d555684cb36dfb959694db76962e570184f98838Mathias Agopian
3213866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // Attempt to create a sync khr object that can produce a sync point. If that
3214866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // isn't available, create a non-dupable sync object in the fallback path and
3215866399093f9f60e7305f291e688abb456bace710Riley Andrews                        // wait on it directly.
3216866399093f9f60e7305f291e688abb456bace710Riley Andrews                        EGLSyncKHR sync;
3217866399093f9f60e7305f291e688abb456bace710Riley Andrews                        if (!DEBUG_SCREENSHOTS) {
3218866399093f9f60e7305f291e688abb456bace710Riley Andrews                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
32199707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           // native fence fd will not be populated until flush() is done.
32209707f4df640c3369f873a934bb05ffa5a68a5640Riley Andrews                           getRenderEngine().flush();
3221866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3222866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = EGL_NO_SYNC_KHR;
3223866399093f9f60e7305f291e688abb456bace710Riley Andrews                        }
32242d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        if (sync != EGL_NO_SYNC_KHR) {
3225866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // get the sync fd
3226866399093f9f60e7305f291e688abb456bace710Riley Andrews                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
3227866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
3228866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: failed to dup sync khr object");
3229866399093f9f60e7305f291e688abb456bace710Riley Andrews                                syncFd = -1;
3230866399093f9f60e7305f291e688abb456bace710Riley Andrews                            }
32312d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            eglDestroySyncKHR(mEGLDisplay, sync);
3232866399093f9f60e7305f291e688abb456bace710Riley Andrews                        } else {
3233866399093f9f60e7305f291e688abb456bace710Riley Andrews                            // fallback path
3234866399093f9f60e7305f291e688abb456bace710Riley Andrews                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
3235866399093f9f60e7305f291e688abb456bace710Riley Andrews                            if (sync != EGL_NO_SYNC_KHR) {
3236866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
3237866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
3238866399093f9f60e7305f291e688abb456bace710Riley Andrews                                EGLint eglErr = eglGetError();
3239866399093f9f60e7305f291e688abb456bace710Riley Andrews                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
3240866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW("captureScreen: fence wait timed out");
3241866399093f9f60e7305f291e688abb456bace710Riley Andrews                                } else {
3242866399093f9f60e7305f291e688abb456bace710Riley Andrews                                    ALOGW_IF(eglErr != EGL_SUCCESS,
3243866399093f9f60e7305f291e688abb456bace710Riley Andrews                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
3244866399093f9f60e7305f291e688abb456bace710Riley Andrews                                }
3245866399093f9f60e7305f291e688abb456bace710Riley Andrews                                eglDestroySyncKHR(mEGLDisplay, sync);
32462d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            } else {
3247866399093f9f60e7305f291e688abb456bace710Riley Andrews                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
32482d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                            }
32492d8d120dc175c131a75e93fb1de61a9f432ddce9Andy McFadden                        }
3250d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        if (DEBUG_SCREENSHOTS) {
3251d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
3252d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
3253d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
3254d555684cb36dfb959694db76962e570184f98838Mathias Agopian                                    hw, minLayerZ, maxLayerZ);
3255d555684cb36dfb959694db76962e570184f98838Mathias Agopian                            delete [] pixels;
3256d555684cb36dfb959694db76962e570184f98838Mathias Agopian                        }
3257d555684cb36dfb959694db76962e570184f98838Mathias Agopian
32580aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    } else {
32590aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
32600aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                        result = INVALID_OPERATION;
32610aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    }
32620aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    // destroy our image
32630aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    eglDestroyImageKHR(mEGLDisplay, image);
32640aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                } else {
32650aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian                    result = BAD_VALUE;
326674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian                }
3267afe2b1fadd29149ceed639357e44e06e97c3a5caJesse Hall                // queueBuffer takes ownership of syncFd
3268866399093f9f60e7305f291e688abb456bace710Riley Andrews                window->queueBuffer(window, buffer, syncFd);
326974c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian            }
32700aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        } else {
32710aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian            result = BAD_VALUE;
327274c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian        }
32730aea53ff3f71f9f8df55d1cf58fd586442582643Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
327474c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    }
327574c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
327674c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian    return result;
327774c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian}
327874c40c0a273dbfd7d10617c4cc1b0c066bfc812eMathias Agopian
3279d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
3280d555684cb36dfb959694db76962e570184f98838Mathias Agopian        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
3281fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    if (DEBUG_SCREENSHOTS) {
3282d555684cb36dfb959694db76962e570184f98838Mathias Agopian        for (size_t y=0 ; y<h ; y++) {
3283d555684cb36dfb959694db76962e570184f98838Mathias Agopian            uint32_t const * p = (uint32_t const *)vaddr + y*s;
3284d555684cb36dfb959694db76962e570184f98838Mathias Agopian            for (size_t x=0 ; x<w ; x++) {
3285fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                if (p[x] != 0xFF000000) return;
3286fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            }
3287fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3288fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        ALOGE("*** we just took a black screenshot ***\n"
3289fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                "requested minz=%d, maxz=%d, layerStack=%d",
3290fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                minLayerZ, maxLayerZ, hw->getLayerStack());
3291fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const LayerVector& layers( mDrawingState.layersSortedByZ );
3292fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        const size_t count = layers.size();
3293fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        for (size_t i=0 ; i<count ; ++i) {
3294fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const sp<Layer>& layer(layers[i]);
3295fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const Layer::State& state(layer->getDrawingState());
3296fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian            const bool visible = (state.layerStack == hw->getLayerStack())
3297fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
3298fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                                && (layer->isVisible());
329986efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x",
3300fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                    visible ? '+' : '-',
3301fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            i, layer->getName().string(), state.layerStack, state.z,
3302fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian                            layer->isVisible(), state.flags, state.alpha);
3303fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian        }
3304fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian    }
3305fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian}
3306fee2b463c5fbe8fa0132d03634ccc02ea55c1505Mathias Agopian
33071b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian// ---------------------------------------------------------------------------
33081b0b30d04304392748a8a4ab5a69e52a19f51b3aMathias Agopian
3309921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector() {
3310921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3311921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3312921e6ac4b7610a178285898d191eb0e3afe906c0Mathias AgopianSurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
331313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    : SortedVector<sp<Layer> >(rhs) {
3314921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3315921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3316921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopianint SurfaceFlinger::LayerVector::do_compare(const void* lhs,
3317921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    const void* rhs) const
3318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
3319be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    // sort layers per layer-stack, then by z-order and finally by sequence
332013127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
332113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
3322be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
33231eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t ls = l->getCurrentState().layerStack;
33241eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rs = r->getCurrentState().layerStack;
3325be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (ls != rs)
3326be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return ls - rs;
3327be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
33281eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t lz = l->getCurrentState().z;
33291eae0ee49402c39f1b08cc8fec129023f86494b7Mathias Agopian    uint32_t rz = r->getCurrentState().z;
3330be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    if (lz != rz)
3331be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian        return lz - rz;
3332be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian
3333be246f86bd6378a5110e81e9d9068ab03c3b077eMathias Agopian    return l->sequence - r->sequence;
3334921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian}
3335921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
3336921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian// ---------------------------------------------------------------------------
3337921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian
33383ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
333947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    : type(DisplayDevice::DISPLAY_ID_INVALID), width(0), height(0) {
3340e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian}
3341e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
33423ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias AgopianSurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
334347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0), width(0), height(0) {
3344da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    viewport.makeInvalid();
3345da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    frame.makeInvalid();
3346b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
33477303c6bf1a8b00a0e7d8165d774a1f259b4ccda9Mathias Agopian
3348b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// ---------------------------------------------------------------------------
334996f0819f81293076e652792794a961543e6750d7Mathias Agopian
3350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
33513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
33523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
33533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl_h_)
33543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl/gl.h in this file"
33553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
33563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
33573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#if defined(__gl2_h_)
33583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#error "don't include gl2/gl2.h in this file"
33593f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#endif
3360