SurfaceFlinger.cpp revision 9a14392256354538f1f43a5e80fe46c2c2b965cb
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/* 2a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk * Copyright (C) 2007 The Android Open Source Project 3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License. 6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at 7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * http://www.apache.org/licenses/LICENSE-2.0 9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * 10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software 11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and 14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License. 15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */ 16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#define ATRACE_TAG ATRACE_TAG_GRAPHICS 18326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 19326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <stdint.h> 205ae678f2e68e25bd74cdc408df354c3b6fe481bfMathias Agopian#include <sys/types.h> 21326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <errno.h> 22158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <math.h> 23158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <dlfcn.h> 247bf29ddc35450d8064541c42c99a1f48be6cf0ddJason Sams 25158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <EGL/egl.h> 2676371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato#include <GLES/gl.h> 2776371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato 28158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <cutils/log.h> 298d957fa762eff6c03a93ddea9405d9575665f1ecJason Sams#include <cutils/properties.h> 308d957fa762eff6c03a93ddea9405d9575665f1ecJason Sams 31158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams#include <binder/IPCThreadState.h> 32326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <binder/IServiceManager.h> 33326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <binder/MemoryHeapBase.h> 34326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <binder/PermissionCache.h> 35fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams 36ca3f09c0924e9515901dfd47fa5f95385d53cf80Stephen Hines#include <ui/DisplayInfo.h> 37326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 38afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk#include <gui/BitTube.h> 396b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams#include <gui/BufferQueue.h> 406b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams#include <gui/GuiConfig.h> 414b3de47071d875faaa7d419d050a464b09538797Jason Sams#include <gui/IDisplayEventConnection.h> 425c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams#include <gui/SurfaceTextureClient.h> 43af12ac6a08651464f8d823add667c706f993b587Steve Block 445c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams#include <ui/GraphicBufferAllocator.h> 456b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams#include <ui/PixelFormat.h> 466b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams#include <ui/UiConfig.h> 476b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams 485c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams#include <utils/misc.h> 49326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <utils/String8.h> 50326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include <utils/String16.h> 51afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk#include <utils/StopWatch.h> 524b3de47071d875faaa7d419d050a464b09538797Jason Sams#include <utils/Trace.h> 5333b6e3b91329080e5cdd0b8fdbcd3e6a906032aeJason Sams 5433b6e3b91329080e5cdd0b8fdbcd3e6a906032aeJason Sams#include <private/android_filesystem_config.h> 5560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams 5660709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams#include "clz.h" 57c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "DdmConnection.h" 58c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "DisplayDevice.h" 59c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "Client.h" 60c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "EventThread.h" 61c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "GLExtensions.h" 62c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "Layer.h" 63c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "LayerDim.h" 6460709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams#include "LayerScreenshot.h" 6560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams#include "SurfaceFlinger.h" 6660709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams 67c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "DisplayHardware/FramebufferSurface.h" 68c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "DisplayHardware/GraphicBufferAlloc.h" 69c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#include "DisplayHardware/HWComposer.h" 70c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams 71c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams 72c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams#define EGL_VERSION_HW_ANDROID 0x3143 73c946b614ee6c983215cc3de7834a7a334f860d68Jason Sams 7460709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams#define DISPLAY_COUNT 1 7560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams 7633b6e3b91329080e5cdd0b8fdbcd3e6a906032aeJason Samsnamespace android { 77afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk// --------------------------------------------------------------------------- 7860709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams 791030893d9b99b72468034da13df025bda479bb97Jason Samsconst String16 sHardwareTest("android.permission.HARDWARE_TEST"); 80c61346b91434307c5003029017b54ce9c49112beJason Samsconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 81c9d43db4d216b01b13aebfdb31d5615909591b33Jason Samsconst String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 821030893d9b99b72468034da13df025bda479bb97Jason Samsconst String16 sDump("android.permission.DUMP"); 831030893d9b99b72468034da13df025bda479bb97Jason Sams 84afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk// --------------------------------------------------------------------------- 852dca84dd6c07992f78ad050177975f16486dd77eJason Sams 868c401effb0837155fc39ca0364f57a882d127d38Jason SamsSurfaceFlinger::SurfaceFlinger() 872382aba4a55c6ae74789c478eead8fbd96593321Jason Sams : BnSurfaceComposer(), Thread(false), 88c61346b91434307c5003029017b54ce9c49112beJason Sams mTransactionFlags(0), 892382aba4a55c6ae74789c478eead8fbd96593321Jason Sams mTransationPending(false), 908cfdd24fec22080b72266d33f61befc4a98b77c6Jason Sams mLayersRemoved(false), 9124371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mRepaintEverything(0), 9224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mBootTime(systemTime()), 93cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams mVisibleRegionsDirty(false), 94afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk mHwWorkListDirty(false), 95b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk mDebugRegion(0), 9624371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mDebugDDMS(0), 9724371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mDebugDisableHWC(0), 9824371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mDebugDisableTransformHint(0), 99b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk mDebugInSwapBuffers(0), 100b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk mLastSwapBufferTime(0), 101b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk mDebugInTransaction(0), 10224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mLastTransactionTime(0), 103cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams mBootFinished(false) 104afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk{ 10524371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams ALOGI("SurfaceFlinger is starting"); 10624371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams 10724371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams // debugging stuff... 10824371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams char value[PROPERTY_VALUE_MAX]; 109cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams 110afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk property_get("debug.sf.showupdates", value, "0"); 11124371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mDebugRegion = atoi(value); 1121d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams 1131d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams property_get("debug.sf.ddms", value, "0"); 11424371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mDebugDDMS = atoi(value); 115c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk if (mDebugDDMS) { 116c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk if (!startDdmConnection()) { 117c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk // start failed, and DDMS debugging not enabled 11824371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams mDebugDDMS = 0; 11924371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams } 12024371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams } 121afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk ALOGI_IF(mDebugRegion, "showupdates enabled"); 1221d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); 1231d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams} 124c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk 125c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchoukvoid SurfaceFlinger::onFirstRef() 126c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk{ 127c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk mEventQueue.init(this); 128afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk 129c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 130c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk 131c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk // Wait for the main thread to be done with its initialization 132c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk mReadyToRunBarrier.wait(); 133c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk} 1341d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams 1351d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams 136afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukSurfaceFlinger::~SurfaceFlinger() 13724371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams{ 13824371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 13924371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 14024371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams eglTerminate(display); 14124371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams} 14224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams 143afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid SurfaceFlinger::binderDied(const wp<IBinder>& who) 14424371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams{ 14524371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams // the window manager died on us. prepare its eulogy. 14624371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams 14724371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams // restore initial conditions (default device unblank, etc) 1481d54f10f3c23e0d7ec57e52ec3b0701a2a5ed24eJason Sams initializeDisplays(); 1492dca84dd6c07992f78ad050177975f16486dd77eJason Sams 1502dca84dd6c07992f78ad050177975f16486dd77eJason Sams // restart the boot-animation 1512dca84dd6c07992f78ad050177975f16486dd77eJason Sams startBootAnim(); 15224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams} 1532dca84dd6c07992f78ad050177975f16486dd77eJason Sams 1542dca84dd6c07992f78ad050177975f16486dd77eJason Samssp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 1556598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block{ 1562dca84dd6c07992f78ad050177975f16486dd77eJason Sams sp<ISurfaceComposerClient> bclient; 1572dca84dd6c07992f78ad050177975f16486dd77eJason Sams sp<Client> client(new Client(this)); 1582dca84dd6c07992f78ad050177975f16486dd77eJason Sams status_t err = client->initCheck(); 1592dca84dd6c07992f78ad050177975f16486dd77eJason Sams if (err == NO_ERROR) { 160c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk bclient = client; 161c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk } 1622dca84dd6c07992f78ad050177975f16486dd77eJason Sams return bclient; 163326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 164326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 165afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouksp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName) 166900f1616bf33c7ba13cf2a737832a95bcd176388Jason Sams{ 167721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams class DisplayToken : public BBinder { 168c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk sp<SurfaceFlinger> flinger; 169721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams virtual ~DisplayToken() { 170c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk // no more references, this display must be terminated 171c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchouk Mutex::Autolock _l(flinger->mStateLock); 172a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams flinger->mCurrentState.displays.removeItem(this); 173326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams flinger->setTransactionFlags(eDisplayTransactionNeeded); 174326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 175889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk public: 176721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams DisplayToken(const sp<SurfaceFlinger>& flinger) 177889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk : flinger(flinger) { 178889fe50e7aaebed8cb8284b16a0e51e64e8a3a9cAlex Sakhartchouk } 179afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk }; 18076371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato 1811fddd90849deaae89b546ff492c345d485bbce42Jason Sams sp<BBinder> token = new DisplayToken(this); 18276371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato 18376371fff76412fd020e24ddb8bf1ddb5c75f0ed1Joe Onorato Mutex::Autolock _l(mStateLock); 184326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL); 185afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk info.displayName = displayName; 1860cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk mCurrentState.displays.add(token, info); 187c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk 188ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk return token; 189ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk} 19009c67356bbeee0a97a20a06c95b66756838cb541Alex Sakhartchouk 1910cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouksp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { 1921809bde133e0d66f06cea65887d9ceb3c70f8b95Alex Sakhartchouk if (uint32_t(id) >= DisplayDevice::NUM_DISPLAY_TYPES) { 1931809bde133e0d66f06cea65887d9ceb3c70f8b95Alex Sakhartchouk ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); 19409c67356bbeee0a97a20a06c95b66756838cb541Alex Sakhartchouk return NULL; 195ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk } 196c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouk return mDefaultDisplays[id]; 1970cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk} 19809c67356bbeee0a97a20a06c95b66756838cb541Alex Sakhartchouk 199c8fb69e4a3e01501a3d38a6d3ea185e583d3f493Alex Sakhartchouksp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 2000cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk{ 2011809bde133e0d66f06cea65887d9ceb3c70f8b95Alex Sakhartchouk sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 202ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk return gba; 2030cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk} 2040cae59f7d8dd63d1bf0ca4abedecb4cfa3ab1921Alex Sakhartchouk 205afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid SurfaceFlinger::bootFinished() 20683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams{ 207b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk const nsecs_t now = systemTime(); 20883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams const nsecs_t duration = now - mBootTime; 20983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 21083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams mBootFinished = true; 211b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 21283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // wait patiently for the window manager death 21383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams const String16 name("window"); 21483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams sp<IBinder> window(defaultServiceManager()->getService(name)); 21583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams if (window != 0) { 21683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); 21783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams } 21883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 21983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // stop boot animation 22083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // formerly we would just kill the process, but we now ask it to exit so it 221d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams // can choose where to stop the animation. 222af12ac6a08651464f8d823add667c706f993b587Steve Block property_set("service.bootanim.exit", "1"); 22383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams} 22483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 22583c451a4ef4388e002482e383d488ca9b7b7600dJason Samsvoid SurfaceFlinger::deleteTextureAsync(GLuint texture) { 22683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams class MessageDestroyGLTexture : public MessageBase { 22783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams GLuint texture; 228d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams public: 229d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams MessageDestroyGLTexture(GLuint texture) 230d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams : texture(texture) { 231d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams } 232d3e7107c60ce06d637d83fa0db783ecdd0ad534cJason Sams virtual bool handler() { 23383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams glDeleteTextures(1, &texture); 23483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams return true; 23583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams } 23683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams }; 23783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams postMessageAsync(new MessageDestroyGLTexture(texture)); 23883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams} 23983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 24083c451a4ef4388e002482e383d488ca9b7b7600dJason Samsstatus_t SurfaceFlinger::selectConfigForAttribute( 24183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams EGLDisplay dpy, 24283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams EGLint const* attrs, 243c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk EGLint attribute, EGLint wanted, 244da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk EGLConfig* outConfig) 24583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams{ 24683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams EGLConfig config = NULL; 24783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams EGLint numConfigs = -1, n=0; 24883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams eglGetConfigs(dpy, NULL, 0, &numConfigs); 249e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams EGLConfig* const configs = new EGLConfig[numConfigs]; 250e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams eglChooseConfig(dpy, attrs, configs, numConfigs, &n); 251e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams 25283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams if (n) { 253e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams if (attribute != EGL_NONE) { 254e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams for (int i=0 ; i<n ; i++) { 255dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams EGLint value = 0; 256dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams eglGetConfigAttrib(dpy, configs[i], attribute, &value); 257dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams if (wanted == value) { 258dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams *outConfig = configs[i]; 259dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams delete [] configs; 260e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams return NO_ERROR; 261e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams } 262e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams } 26383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams } else { 2647257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk // just pick the first one 26583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams *outConfig = configs[0]; 26683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams delete [] configs; 267e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams return NO_ERROR; 268e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams } 269dc314a172d48479053f258b485d7d0284b5b5b1fJason Sams } 27083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams delete [] configs; 27183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams return NAME_NOT_FOUND; 27283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams} 27383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams 27483c451a4ef4388e002482e383d488ca9b7b7600dJason Samsclass EGLAttributeVector { 275e0aab4a8ff1cffd8cfaedc2623db94072549e0e5Jason Sams struct Attribute; 27683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams class Adder; 27783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams friend class Adder; 27883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams KeyedVector<Attribute, EGLint> mList; 27983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams struct Attribute { 28083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams Attribute() {}; 28183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams Attribute(EGLint v) : v(v) { } 282ca7c202abc3853e96d1d0d77b672789622eff99dJason Sams EGLint v; 283ca7c202abc3853e96d1d0d77b672789622eff99dJason Sams bool operator < (const Attribute& other) const { 28483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams // this places EGL_NONE at the end 28583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams EGLint lhs(v); 28683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams EGLint rhs(other.v); 2876598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block if (lhs == EGL_NONE) lhs = 0x7FFFFFFF; 28883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams if (rhs == EGL_NONE) rhs = 0x7FFFFFFF; 28983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams return lhs < rhs; 29083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams } 29183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams }; 29283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams class Adder { 29383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams friend class EGLAttributeVector; 29483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams EGLAttributeVector& v; 2956598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block EGLint attribute; 29683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams Adder(EGLAttributeVector& v, EGLint attribute) 297326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams : v(v), attribute(attribute) { 298326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 299741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams public: 3006598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block void operator = (EGLint value) { 3012e8665de7c0eb4514c67baf8693d61c892e5303dJason Sams if (attribute != EGL_NONE) { 302741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams v.mList.add(attribute, value); 303741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams } 304741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams } 305741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams operator EGLint () const { return v.mList[attribute]; } 306741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams }; 307741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Samspublic: 308741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams EGLAttributeVector() { 309741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams mList.add(EGL_NONE, EGL_NONE); 310741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams } 311741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams void remove(EGLint attribute) { 312741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams if (attribute != EGL_NONE) { 313741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams mList.removeItem(attribute); 314c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk } 315da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk } 316741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams Adder operator [] (EGLint attribute) { 317c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams return Adder(*this, attribute); 3186598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block } 319cf912de17f1e086ccea707d8607a3d2eda56b98fJason Sams EGLint operator [] (EGLint attribute) const { 320741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams return mList[attribute]; 321741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams } 3222382aba4a55c6ae74789c478eead8fbd96593321Jason Sams // cast-operator to (EGLint const*) 3232382aba4a55c6ae74789c478eead8fbd96593321Jason Sams operator EGLint const* () const { return &mList.keyAt(0).v; } 324ee803446857b14d97f3e90a4f530604b6be9c867Jason Sams}; 325af12ac6a08651464f8d823add667c706f993b587Steve Block 326ee803446857b14d97f3e90a4f530604b6be9c867Jason SamsEGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) { 327ee803446857b14d97f3e90a4f530604b6be9c867Jason Sams // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if 328af12ac6a08651464f8d823add667c706f993b587Steve Block // it is to be used with WIFI displays 329ee803446857b14d97f3e90a4f530604b6be9c867Jason Sams EGLConfig config; 3302382aba4a55c6ae74789c478eead8fbd96593321Jason Sams EGLint dummy; 3312382aba4a55c6ae74789c478eead8fbd96593321Jason Sams status_t err; 3322382aba4a55c6ae74789c478eead8fbd96593321Jason Sams 333afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk EGLAttributeVector attribs; 334158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams attribs[EGL_SURFACE_TYPE] = EGL_WINDOW_BIT; 335158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams attribs[EGL_RECORDABLE_ANDROID] = EGL_TRUE; 336158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE; 337158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams attribs[EGL_RED_SIZE] = 8; 3382dca84dd6c07992f78ad050177975f16486dd77eJason Sams attribs[EGL_GREEN_SIZE] = 8; 339158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams attribs[EGL_BLUE_SIZE] = 8; 340158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams 341158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams err = selectConfigForAttribute(display, attribs, EGL_NONE, EGL_NONE, &config); 342158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams if (!err) 343158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams goto success; 344158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams 345158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams // maybe we failed because of EGL_FRAMEBUFFER_TARGET_ANDROID 346158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams ALOGW("no suitable EGLConfig found, trying without EGL_FRAMEBUFFER_TARGET_ANDROID"); 347158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams attribs.remove(EGL_FRAMEBUFFER_TARGET_ANDROID); 3487bf29ddc35450d8064541c42c99a1f48be6cf0ddJason Sams err = selectConfigForAttribute(display, attribs, 349158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams EGL_NATIVE_VISUAL_ID, nativeVisualId, &config); 350158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams if (!err) 351158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams goto success; 352afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk 3535c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams // maybe we failed because of EGL_RECORDABLE_ANDROID 354326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGW("no suitable EGLConfig found, trying without EGL_RECORDABLE_ANDROID"); 355326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams attribs.remove(EGL_RECORDABLE_ANDROID); 35686f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams err = selectConfigForAttribute(display, attribs, 357e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams EGL_NATIVE_VISUAL_ID, nativeVisualId, &config); 358a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams if (!err) 359cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines goto success; 3607b3e9bd825901e33661e3c385e3e7c6f40ca6000Alex Sakhartchouk 361b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk // allow less than 24-bit color; the non-gpu-accelerated emulator only 36286c6b5fecb3e4e68668fdb5640770545501e778fStephen Hines // supports 16-bit color 3635c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams ALOGW("no suitable EGLConfig found, trying with 16-bit color allowed"); 3645c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams attribs.remove(EGL_RED_SIZE); 365afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk attribs.remove(EGL_GREEN_SIZE); 3665c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams attribs.remove(EGL_BLUE_SIZE); 367b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk err = selectConfigForAttribute(display, attribs, 3685c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams EGL_NATIVE_VISUAL_ID, nativeVisualId, &config); 3695c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams if (!err) 3705c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams goto success; 3715c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams 3725c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams // this EGL is too lame for Android 3735c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams ALOGE("no suitable EGLConfig found, giving up"); 3745c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams 375b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk return 0; 376b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 377b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouksuccess: 378b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy)) 379b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!"); 380b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk return config; 381afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk} 3825c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams 3835c1c79a54c63b9de8c391f7ed890c02f280ec17fJason SamsEGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) { 3841a4efa363916977ef9aeab756725b3bdc880a15bJason Sams // Also create our EGLContext 3852382aba4a55c6ae74789c478eead8fbd96593321Jason Sams EGLint contextAttributes[] = { 3861a4efa363916977ef9aeab756725b3bdc880a15bJason Sams#ifdef EGL_IMG_context_priority 3875c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams#ifdef HAS_CONTEXT_PRIORITY 3885c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams#warning "using EGL_IMG_context_priority" 3896b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, 3906b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams#endif 3916b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams#endif 3926b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams EGL_NONE, EGL_NONE 3936b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams }; 394a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); 3956b8552a4f6a44848255d77222e66aa92dd21b1b5Jason Sams ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); 396326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return ctxt; 397a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams} 398a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams 399a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Samsvoid SurfaceFlinger::initializeGL(EGLDisplay display) { 400fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams GLExtensions& extensions(GLExtensions::getInstance()); 401fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams extensions.initWithGLStrings( 402fb03a22ad2adadc1ff50a8b50d43ad7fcc3fa6edJason Sams glGetString(GL_VENDOR), 403e57691037aea219562ac686429b4b98202aab7bcJason Sams glGetString(GL_RENDERER), 404a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams glGetString(GL_VERSION), 405a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams glGetString(GL_EXTENSIONS), 406af12ac6a08651464f8d823add667c706f993b587Steve Block eglQueryString(display, EGL_VENDOR), 4075c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams eglQueryString(display, EGL_VERSION), 408a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams eglQueryString(display, EGL_EXTENSIONS)); 409a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams 4107257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); 411992a0b70d8fd7a14f0c57bc3c7e16c1f269a6609Jason Sams glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); 41224371d93cdb6999971c4058f78974da3c3d5fc64Jason Sams 413a891933b4c5ab1b63103add167269cfc404c2adfJason Sams glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 4145086938044e0a9b6b1138f915d0d252fe046e102Jason Sams glPixelStorei(GL_PACK_ALIGNMENT, 4); 415a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams glEnableClientState(GL_VERTEX_ARRAY); 416326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams glShadeModel(GL_FLAT); 417af12ac6a08651464f8d823add667c706f993b587Steve Block glDisable(GL_DITHER); 4185c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams glDisable(GL_CULL_FACE); 4197bf29ddc35450d8064541c42c99a1f48be6cf0ddJason Sams 420afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk struct pack565 { 421181334092f78273d0da2d854ebbe7b24508d3bfcJason Sams inline uint16_t operator() (int r, int g, int b) const { 422181334092f78273d0da2d854ebbe7b24508d3bfcJason Sams return (r<<11)|(g<<5)|b; 423181334092f78273d0da2d854ebbe7b24508d3bfcJason Sams } 4245c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams } pack565; 425af12ac6a08651464f8d823add667c706f993b587Steve Block 4265c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 4275c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams glGenTextures(1, &mProtectedTexName); 4285c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 429a658e905f14fe500bfee3812b213a73cb37ef6f2Jason Sams glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4305c1c79a54c63b9de8c391f7ed890c02f280ec17fJason Sams glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 431326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 432326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 433afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 4346598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 435cf912de17f1e086ccea707d8607a3d2eda56b98fJason Sams 436b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk // print some debugging info 437b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk EGLint r,g,b,a; 438b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE, &r); 439b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g); 440b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE, &b); 441b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a); 442326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGI("EGL informations:"); 443b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("vendor : %s", extensions.getEglVendor()); 444b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("version : %s", extensions.getEglVersion()); 445326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGI("extensions: %s", extensions.getEglExtension()); 446b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); 447b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig); 448b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("OpenGL ES informations:"); 449249d453869cca82dcb57123f6d1c8df3ca9f4372Jason Sams ALOGI("vendor : %s", extensions.getVendor()); 450b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("renderer : %s", extensions.getRenderer()); 451b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("version : %s", extensions.getVersion()); 452b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("extensions: %s", extensions.getExtension()); 453b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); 454b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); 455b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk} 456b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk 457326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsstatus_t SurfaceFlinger::readyToRun() 4586598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block{ 459326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGI( "SurfaceFlinger's main thread ready to run. " 460326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams "Initializing graphics H/W..."); 4617257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk 4624820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams // initialize EGL for the default display 4634b3de47071d875faaa7d419d050a464b09538797Jason Sams mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 464458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams eglInitialize(mEGLDisplay, NULL, NULL); 4657257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk 4664b3de47071d875faaa7d419d050a464b09538797Jason Sams // Initialize the H/W composer object. There may or may not be an 4674b3de47071d875faaa7d419d050a464b09538797Jason Sams // actual hardware composer underneath. 468613cad1702dbb76eb2a6ba0cfcb43b9fe207cebcJason Sams mHwc = new HWComposer(this, 4694b3de47071d875faaa7d419d050a464b09538797Jason Sams *static_cast<HWComposer::EventHandler *>(this)); 470771565f47fc44608444c00aa8fa3bda769ceaeceJason Sams 471a544b6368d7ddae47985da92d6bcf86798b376c6Alex Sakhartchouk // initialize the config and context 472458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams EGLint format = mHwc->getVisualID(); 473458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams mEGLConfig = selectEGLConfig(mEGLDisplay, format); 474458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams mEGLContext = createGLContext(mEGLDisplay, mEGLConfig); 475a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk 476a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, 477a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk "couldn't create EGLContext"); 478a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk 479a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk // initialize our non-virtual displays 480a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) { 481a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); 482a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk mDefaultDisplays[i] = new BBinder(); 483a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk wp<IBinder> token = mDefaultDisplays[i]; 484a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk 485a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk // set-up the displays that are already connected 486a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { 487a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk mCurrentState.displays.add(token, DisplayDeviceState(type)); 488a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i); 489a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk sp<SurfaceTextureClient> stc = new SurfaceTextureClient( 490a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue())); 491a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk sp<DisplayDevice> hw = new DisplayDevice(this, 492a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk type, token, stc, fbs, mEGLConfig); 493a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk if (i > DisplayDevice::DISPLAY_PRIMARY) { 494a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk // FIXME: currently we don't get blank/unblank requests 495a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk // for displays other than the main display, so we always 496a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk // assume a connected display is unblanked. 497a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk ALOGD("marking display %d as acquired/unblanked", i); 498a74a8f635ce4fae0a9d4b9c79e9fa412787bf6a2Alex Sakhartchouk hw->acquireScreen(); 499afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk } 5004820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams mDisplays.add(token, hw); 50186f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams } 50286f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams } 50386f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams 504afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk // we need a GL context current in a few places, when initializing 5054820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams // OpenGL ES (see below), or creating a layer, 50686f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams // or when a texture is (asynchronously) destroyed, and for that 50786f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams // we need a valid surface, so it's convenient to use the main display 50886f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams // for that. 509afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk sp<const DisplayDevice> hw = getDefaultDisplayDevice(); 5104820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams 511326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // initialize OpenGL ES 512326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); 513326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams initializeGL(mEGLDisplay); 51460709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams 5154820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams // start the EventThread 5168ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams mEventThread = new EventThread(this); 5178ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams mEventQueue.setEventThread(mEventThread); 5188ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams 5198ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams // initialize our drawing state 5208ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams mDrawingState = mCurrentState; 521326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 522326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 52360709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams // We're now ready to accept clients... 5244820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams mReadyToRunBarrier.open(); 5258ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams 5268ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams // set initial conditions (e.g. unblank default device) 5278ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams initializeDisplays(); 5288ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams 5298ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams // start boot animation 530cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams startBootAnim(); 531cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams 53260709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams return NO_ERROR; 5334820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams} 5345fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams 5355fd09d847586f9680b4f495413b6ca5fbb69af6eJason Samsint32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { 5365fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ? 5375fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams type : mHwc->allocateDisplayId(); 5385fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams} 5395fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams 5405fd09d847586f9680b4f495413b6ca5fbb69af6eJason Samsvoid SurfaceFlinger::startBootAnim() { 54160709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams // start boot animation 5424820e8bb83b1f78e6232ebe853221f737da2a1eaJason Sams property_set("service.bootanim.exit", "0"); 5438ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams property_set("ctl.start", "bootanim"); 5448ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams} 5458ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams 5468ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Samsuint32_t SurfaceFlinger::getMaxTextureSize() const { 5478ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams return mMaxTextureSize; 548326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams} 549326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 550afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukuint32_t SurfaceFlinger::getMaxViewportDims() const { 551d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return mMaxViewportDims[0] < mMaxViewportDims[1] ? 552d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mMaxViewportDims[0] : mMaxViewportDims[1]; 553d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 554d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 555d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk// ---------------------------------------------------------------------------- 556d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 557d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukbool SurfaceFlinger::authenticateSurfaceTexture( 558d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const sp<ISurfaceTexture>& surfaceTexture) const { 559afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk Mutex::Autolock _l(mStateLock); 560a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder()); 561a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams 562a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams // Check the visible layer list for the ISurface 563a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 564a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams size_t count = currentLayers.size(); 565afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk for (size_t i=0 ; i<count ; i++) { 566afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk const sp<LayerBase>& layer(currentLayers[i]); 567a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 568a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams if (lbc != NULL) { 569a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 570a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams if (lbcBinder == surfaceTextureBinder) { 571a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams return true; 572a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams } 573a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams } 5741a4efa363916977ef9aeab756725b3bdc880a15bJason Sams } 5751a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 576aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams // Check the layers in the purgatory. This check is here so that if a 577aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams // SurfaceTexture gets destroyed before all the clients are done using it, 5781a4efa363916977ef9aeab756725b3bdc880a15bJason Sams // the error will not be reported as "surface XYZ is not authenticated", but 5791a4efa363916977ef9aeab756725b3bdc880a15bJason Sams // will instead fail later on when the client tries to use the surface, 5808c401effb0837155fc39ca0364f57a882d127d38Jason Sams // which should be reported as "surface XYZ returned an -ENODEV". The 5818c401effb0837155fc39ca0364f57a882d127d38Jason Sams // purgatorized layers are no less authentic than the visible ones, so this 58287319de2b16a185cf360827c96a42cf1fcaae744Jason Sams // should not cause any harm. 58387319de2b16a185cf360827c96a42cf1fcaae744Jason Sams size_t purgatorySize = mLayerPurgatory.size(); 5841a4efa363916977ef9aeab756725b3bdc880a15bJason Sams for (size_t i=0 ; i<purgatorySize ; i++) { 5851a4efa363916977ef9aeab756725b3bdc880a15bJason Sams const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 5868c401effb0837155fc39ca0364f57a882d127d38Jason Sams sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 5878c401effb0837155fc39ca0364f57a882d127d38Jason Sams if (lbc != NULL) { 588afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); 589afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk if (lbcBinder == surfaceTextureBinder) { 5908c401effb0837155fc39ca0364f57a882d127d38Jason Sams return true; 5918c401effb0837155fc39ca0364f57a882d127d38Jason Sams } 5928c401effb0837155fc39ca0364f57a882d127d38Jason Sams } 5938c401effb0837155fc39ca0364f57a882d127d38Jason Sams } 594afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk 5951a4efa363916977ef9aeab756725b3bdc880a15bJason Sams return false; 5968c401effb0837155fc39ca0364f57a882d127d38Jason Sams} 5975086938044e0a9b6b1138f915d0d252fe046e102Jason Sams 59887319de2b16a185cf360827c96a42cf1fcaae744Jason Samsstatus_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) { 599a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams int32_t type = BAD_VALUE; 600aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams for (int i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) { 601a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams if (display == mDefaultDisplays[i]) { 602a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams type = i; 603a2cf755a28a1e7ffff2955df656d714f40e4d715Jason Sams break; 604afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk } 605af12ac6a08651464f8d823add667c706f993b587Steve Block } 606af12ac6a08651464f8d823add667c706f993b587Steve Block 60713e2634a71a30d289ed8d821aef61c7d1687460eJason Sams if (type < 0) { 608af12ac6a08651464f8d823add667c706f993b587Steve Block return type; 609af12ac6a08651464f8d823add667c706f993b587Steve Block } 610af12ac6a08651464f8d823add667c706f993b587Steve Block 61113e2634a71a30d289ed8d821aef61c7d1687460eJason Sams const HWComposer& hwc(getHwComposer()); 612a4a54e42fc710a62b47cbcb9d64c34a190429d9eJason Sams if (!hwc.isConnected(type)) { 613326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return NAME_NOT_FOUND; 614a44cb29164726cd9d812117819abdd7b60dfdd93Jason Sams } 615326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 616326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams float xdpi = hwc.getDpiX(type); 617326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams float ydpi = hwc.getDpiY(type); 618326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 619afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk // TODO: Not sure if display density should handled by SF any longer 6208c88090e8cccab103eebe2ff569e116e9f5fb208Jason Sams class Density { 621326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams static int getDensityFromProperty(char const* propName) { 622afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk char property[PROPERTY_VALUE_MAX]; 623326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams int density = 0; 624326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (property_get(propName, property, NULL) > 0) { 625326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams density = atoi(property); 626326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 627afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk return density; 628326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 629326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams public: 630326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams static int getEmuDensity() { 631af12ac6a08651464f8d823add667c706f993b587Steve Block return getDensityFromProperty("qemu.sf.lcd_density"); } 632326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams static int getBuildDensity() { 633326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams return getDensityFromProperty("ro.sf.lcd_density"); } 634326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams }; 635326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 636326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams if (type == DisplayDevice::DISPLAY_PRIMARY) { 637326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // The density of the device is provided by a build property 638afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk float density = Density::getBuildDensity() / 160.0f; 639ccc010bb7c0f89e162bf60033968a20be90a903aJason Sams if (density == 0) { 64060709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams // the build doesn't provide a density -- this is wrong! 641326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // use xdpi instead 642326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams ALOGE("ro.sf.lcd_density must be defined as a build property"); 643afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk density = xdpi / 160.0f; 644326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } 64560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams if (Density::getEmuDensity()) { 646326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // if "qemu.sf.lcd_density" is specified, it overrides everything 647326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams xdpi = ydpi = density = Density::getEmuDensity(); 648afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk density /= 160.0f; 6495fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams } 65060709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams info->density = density; 6515fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams 6525fd09d847586f9680b4f495413b6ca5fbb69af6eJason Sams // TODO: this needs to go away (currently needed only by webkit) 653afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 654326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams info->orientation = hw->getOrientation(); 65560709257bbdeb0c50f39b9c8969dc76264d6e142Jason Sams getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo); 656326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams } else { 657326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams // TODO: where should this value come from? 658afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk static const int TV_DENSITY = 213; 659d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk info->density = TV_DENSITY / 160.0f; 660d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk info->orientation = 0; 661d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 662d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 663b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk info->w = hwc.getWidth(type); 664a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams info->h = hwc.getHeight(type); 66570b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchouk info->xdpi = xdpi; 666a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216Jason Sams info->ydpi = ydpi; 667326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams info->fps = float(1e9 / hwc.getRefreshPeriod(type)); 668afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk return NO_ERROR; 6692353ae303868d04e3a26002b2f2dc456c15e8170Jason Sams} 670707aaf341a4b068e6ccadf923af85acdd85fd775Jason Sams 6719397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams// ---------------------------------------------------------------------------- 672707aaf341a4b068e6ccadf923af85acdd85fd775Jason Sams 673707aaf341a4b068e6ccadf923af85acdd85fd775Jason Samssp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { 674afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk return mEventThread->createEventConnection(); 67586f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams} 67686f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams 67786f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Samsvoid SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture>& surface) { 678afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk 67986f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams sp<IBinder> token; 68086f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams { // scope for the lock 68186f1b23aaaf9b8822a009d8c3e585e46768abb6aJason Sams Mutex::Autolock _l(mStateLock); 6827257c7ee4b66f00c43d9235f3ac600061ae79968Alex Sakhartchouk token = mExtDisplayToken; 683fa4028663712dbb1a3d13c507c3bc13c6e4be80dMathias Agopian } 684613cad1702dbb76eb2a6ba0cfcb43b9fe207cebcJason Sams 685613cad1702dbb76eb2a6ba0cfcb43b9fe207cebcJason Sams if (token == 0) { 686afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk token = createDisplay(String8("Display from connectDisplay")); 687158324456b8dbf40f684dd0a4af3493b9549f3f5Jason Sams } 688458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams 689458f2dc26b7d34c2138c7bfbd95914240084e6bdJason Sams { // scope for the lock 690afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk Mutex::Autolock _l(mStateLock); 691c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams if (surface == 0) { 692c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams // release our current display. we're guarantee to have 693c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams // a reference to it (token), while we hold the lock 694741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams mExtDisplayToken = 0; 695b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk } else { 6961dcefab7178f0644b0e0a6998007b1acae5261cfJason Sams mExtDisplayToken = token; 6971dcefab7178f0644b0e0a6998007b1acae5261cfJason Sams } 698c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams 6996598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block DisplayDeviceState& info(mCurrentState.displays.editValueFor(token)); 700741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams info.surface = surface; 701741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams setTransactionFlags(eDisplayTransactionNeeded); 7026598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block } 703741aac95b777b2e6cb90f484a05e489a79a6ef05Jason Sams} 704326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams 705326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams// ---------------------------------------------------------------------------- 706c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams 707186e59154a0fb86e05e283e9c083b69878c06720Jason Samsvoid SurfaceFlinger::waitForEvent() { 7081a4efa363916977ef9aeab756725b3bdc880a15bJason Sams mEventQueue.waitMessage(); 7091a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 710aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Sams 711aad4bc5231dd7059fc5148b34a951117d9b5f4adJason Samsvoid SurfaceFlinger::signalTransaction() { 712c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams mEventQueue.invalidate(); 713186e59154a0fb86e05e283e9c083b69878c06720Jason Sams} 7141a4efa363916977ef9aeab756725b3bdc880a15bJason Sams 715186e59154a0fb86e05e283e9c083b69878c06720Jason Samsvoid SurfaceFlinger::signalLayerUpdate() { 716186e59154a0fb86e05e283e9c083b69878c06720Jason Sams mEventQueue.invalidate(); 7171a4efa363916977ef9aeab756725b3bdc880a15bJason Sams} 7188c401effb0837155fc39ca0364f57a882d127d38Jason Sams 7198c401effb0837155fc39ca0364f57a882d127d38Jason Samsvoid SurfaceFlinger::signalRefresh() { 720c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams mEventQueue.refresh(); 7218c401effb0837155fc39ca0364f57a882d127d38Jason Sams} 7228c401effb0837155fc39ca0364f57a882d127d38Jason Sams 7238c401effb0837155fc39ca0364f57a882d127d38Jason Samsstatus_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 724c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams nsecs_t reltime, uint32_t flags) { 7258c401effb0837155fc39ca0364f57a882d127d38Jason Sams return mEventQueue.postMessage(msg, reltime); 7268c401effb0837155fc39ca0364f57a882d127d38Jason Sams} 7278c401effb0837155fc39ca0364f57a882d127d38Jason Sams 728c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsstatus_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 729c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams nsecs_t reltime, uint32_t flags) { 730c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams status_t res = mEventQueue.postMessage(msg, reltime); 731cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines if (res == NO_ERROR) { 732cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines msg->wait(); 7336598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block } 734789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams return res; 735789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams} 736cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines 737cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hinesbool SurfaceFlinger::threadLoop() { 738cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines waitForEvent(); 739789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams return true; 740789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams} 741789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams 742789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Samsvoid SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) { 743cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines if (mEventThread == NULL) { 744cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines // This is a temporary workaround for b/7145521. A non-null pointer 7456598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block // does not mean EventThread has finished initializing, so this 746789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams // is not a correct fix. 747789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams ALOGW("WARNING: EventThread not started, ignoring vsync"); 7489544f76195de22f655fd7a1894934667e7e55f6aJason Sams return; 749cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines } 7509544f76195de22f655fd7a1894934667e7e55f6aJason Sams if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) { 7519544f76195de22f655fd7a1894934667e7e55f6aJason Sams // we should only receive DisplayDevice::DisplayType from the vsync callback 7526598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block mEventThread->onVSyncReceived(type, timestamp); 753789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams } 754789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams} 755789ca83c794cb7196c9bac97d39eaf1f7947af2aJason Sams 756dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchoukvoid SurfaceFlinger::onHotplugReceived(int type, bool connected) { 757dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk if (mEventThread == NULL) { 758afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk // This is a temporary workaround for b/7145521. A non-null pointer 759dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk // does not mean EventThread has finished initializing, so this 760dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk // is not a correct fix. 761dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk ALOGW("WARNING: EventThread not started, ignoring hotplug"); 762 return; 763 } 764 765 if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) { 766 Mutex::Autolock _l(mStateLock); 767 if (connected == false) { 768 mCurrentState.displays.removeItem(mDefaultDisplays[type]); 769 } else { 770 DisplayDeviceState info((DisplayDevice::DisplayType)type); 771 mCurrentState.displays.add(mDefaultDisplays[type], info); 772 } 773 setTransactionFlags(eDisplayTransactionNeeded); 774 775 // we should only receive DisplayDevice::DisplayType from the vsync callback 776 mEventThread->onHotplugReceived(type, connected); 777 } 778} 779 780void SurfaceFlinger::eventControl(int disp, int event, int enabled) { 781 getHwComposer().eventControl(disp, event, enabled); 782} 783 784void SurfaceFlinger::onMessageReceived(int32_t what) { 785 ATRACE_CALL(); 786 switch (what) { 787 case MessageQueue::INVALIDATE: 788 handleMessageTransaction(); 789 handleMessageInvalidate(); 790 signalRefresh(); 791 break; 792 case MessageQueue::REFRESH: 793 handleMessageRefresh(); 794 break; 795 } 796} 797 798void SurfaceFlinger::handleMessageTransaction() { 799 uint32_t transactionFlags = peekTransactionFlags(eTransactionMask); 800 if (transactionFlags) { 801 handleTransaction(transactionFlags); 802 } 803} 804 805void SurfaceFlinger::handleMessageInvalidate() { 806 ATRACE_CALL(); 807 handlePageFlip(); 808} 809 810void SurfaceFlinger::handleMessageRefresh() { 811 ATRACE_CALL(); 812 preComposition(); 813 rebuildLayerStacks(); 814 setUpHWComposer(); 815 doDebugFlashRegions(); 816 doComposition(); 817 postComposition(); 818} 819 820void SurfaceFlinger::doDebugFlashRegions() 821{ 822 // is debugging enabled 823 if (CC_LIKELY(!mDebugRegion)) 824 return; 825 826 const bool repaintEverything = mRepaintEverything; 827 for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 828 const sp<DisplayDevice>& hw(mDisplays[dpy]); 829 if (hw->canDraw()) { 830 // transform the dirty region into this screen's coordinate space 831 const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 832 if (!dirtyRegion.isEmpty()) { 833 // redraw the whole screen 834 doComposeSurfaces(hw, Region(hw->bounds())); 835 836 // and draw the dirty region 837 glDisable(GL_TEXTURE_EXTERNAL_OES); 838 glDisable(GL_TEXTURE_2D); 839 glDisable(GL_BLEND); 840 glColor4f(1, 0, 1, 1); 841 const int32_t height = hw->getHeight(); 842 Region::const_iterator it = dirtyRegion.begin(); 843 Region::const_iterator const end = dirtyRegion.end(); 844 while (it != end) { 845 const Rect& r = *it++; 846 GLfloat vertices[][2] = { 847 { r.left, height - r.top }, 848 { r.left, height - r.bottom }, 849 { r.right, height - r.bottom }, 850 { r.right, height - r.top } 851 }; 852 glVertexPointer(2, GL_FLOAT, 0, vertices); 853 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 854 } 855 hw->compositionComplete(); 856 hw->swapBuffers(getHwComposer()); 857 } 858 } 859 } 860 861 postFramebuffer(); 862 863 if (mDebugRegion > 1) { 864 usleep(mDebugRegion * 1000); 865 } 866 867 HWComposer& hwc(getHwComposer()); 868 if (hwc.initCheck() == NO_ERROR) { 869 status_t err = hwc.prepare(); 870 ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 871 } 872} 873 874void SurfaceFlinger::preComposition() 875{ 876 bool needExtraInvalidate = false; 877 const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 878 const size_t count = currentLayers.size(); 879 for (size_t i=0 ; i<count ; i++) { 880 if (currentLayers[i]->onPreComposition()) { 881 needExtraInvalidate = true; 882 } 883 } 884 if (needExtraInvalidate) { 885 signalLayerUpdate(); 886 } 887} 888 889void SurfaceFlinger::postComposition() 890{ 891 const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 892 const size_t count = currentLayers.size(); 893 for (size_t i=0 ; i<count ; i++) { 894 currentLayers[i]->onPostComposition(); 895 } 896} 897 898void SurfaceFlinger::rebuildLayerStacks() { 899 // rebuild the visible layer list per screen 900 if (CC_UNLIKELY(mVisibleRegionsDirty)) { 901 ATRACE_CALL(); 902 mVisibleRegionsDirty = false; 903 invalidateHwcGeometry(); 904 905 const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 906 for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 907 Region opaqueRegion; 908 Region dirtyRegion; 909 Vector< sp<LayerBase> > layersSortedByZ; 910 const sp<DisplayDevice>& hw(mDisplays[dpy]); 911 const Transform& tr(hw->getTransform()); 912 const Rect bounds(hw->getBounds()); 913 if (hw->canDraw()) { 914 SurfaceFlinger::computeVisibleRegions(currentLayers, 915 hw->getLayerStack(), dirtyRegion, opaqueRegion); 916 917 const size_t count = currentLayers.size(); 918 for (size_t i=0 ; i<count ; i++) { 919 const sp<LayerBase>& layer(currentLayers[i]); 920 const Layer::State& s(layer->drawingState()); 921 if (s.layerStack == hw->getLayerStack()) { 922 Region drawRegion(tr.transform( 923 layer->visibleNonTransparentRegion)); 924 drawRegion.andSelf(bounds); 925 if (!drawRegion.isEmpty()) { 926 layersSortedByZ.add(layer); 927 } 928 } 929 } 930 } 931 hw->setVisibleLayersSortedByZ(layersSortedByZ); 932 hw->undefinedRegion.set(bounds); 933 hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion)); 934 hw->dirtyRegion.orSelf(dirtyRegion); 935 } 936 } 937} 938 939void SurfaceFlinger::setUpHWComposer() { 940 HWComposer& hwc(getHwComposer()); 941 if (hwc.initCheck() == NO_ERROR) { 942 // build the h/w work list 943 if (CC_UNLIKELY(mHwWorkListDirty)) { 944 mHwWorkListDirty = false; 945 for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 946 sp<const DisplayDevice> hw(mDisplays[dpy]); 947 const int32_t id = hw->getHwcDisplayId(); 948 if (id >= 0) { 949 const Vector< sp<LayerBase> >& currentLayers( 950 hw->getVisibleLayersSortedByZ()); 951 const size_t count = currentLayers.size(); 952 if (hwc.createWorkList(id, count) == NO_ERROR) { 953 HWComposer::LayerListIterator cur = hwc.begin(id); 954 const HWComposer::LayerListIterator end = hwc.end(id); 955 for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 956 const sp<LayerBase>& layer(currentLayers[i]); 957 layer->setGeometry(hw, *cur); 958 if (mDebugDisableHWC || mDebugRegion) { 959 cur->setSkip(true); 960 } 961 } 962 } 963 } 964 } 965 } 966 967 // set the per-frame data 968 for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 969 sp<const DisplayDevice> hw(mDisplays[dpy]); 970 const int32_t id = hw->getHwcDisplayId(); 971 if (id >= 0) { 972 const Vector< sp<LayerBase> >& currentLayers( 973 hw->getVisibleLayersSortedByZ()); 974 const size_t count = currentLayers.size(); 975 HWComposer::LayerListIterator cur = hwc.begin(id); 976 const HWComposer::LayerListIterator end = hwc.end(id); 977 for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { 978 /* 979 * update the per-frame h/w composer data for each layer 980 * and build the transparent region of the FB 981 */ 982 const sp<LayerBase>& layer(currentLayers[i]); 983 layer->setPerFrameData(hw, *cur); 984 } 985 } 986 } 987 988 status_t err = hwc.prepare(); 989 ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 990 } 991} 992 993void SurfaceFlinger::doComposition() { 994 ATRACE_CALL(); 995 const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); 996 for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 997 const sp<DisplayDevice>& hw(mDisplays[dpy]); 998 if (hw->canDraw()) { 999 // transform the dirty region into this screen's coordinate space 1000 const Region dirtyRegion(hw->getDirtyRegion(repaintEverything)); 1001 if (!dirtyRegion.isEmpty()) { 1002 // repaint the framebuffer (if needed) 1003 doDisplayComposition(hw, dirtyRegion); 1004 } 1005 hw->dirtyRegion.clear(); 1006 hw->flip(hw->swapRegion); 1007 hw->swapRegion.clear(); 1008 } 1009 // inform the h/w that we're done compositing 1010 hw->compositionComplete(); 1011 } 1012 postFramebuffer(); 1013} 1014 1015void SurfaceFlinger::postFramebuffer() 1016{ 1017 ATRACE_CALL(); 1018 1019 const nsecs_t now = systemTime(); 1020 mDebugInSwapBuffers = now; 1021 1022 HWComposer& hwc(getHwComposer()); 1023 if (hwc.initCheck() == NO_ERROR) { 1024 if (!hwc.supportsFramebufferTarget()) { 1025 // EGL spec says: 1026 // "surface must be bound to the calling thread's current context, 1027 // for the current rendering API." 1028 DisplayDevice::makeCurrent(mEGLDisplay, 1029 getDefaultDisplayDevice(), mEGLContext); 1030 } 1031 hwc.commit(); 1032 } 1033 1034 for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1035 sp<const DisplayDevice> hw(mDisplays[dpy]); 1036 const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ()); 1037 hw->onSwapBuffersCompleted(hwc); 1038 const size_t count = currentLayers.size(); 1039 int32_t id = hw->getHwcDisplayId(); 1040 if (id >=0 && hwc.initCheck() == NO_ERROR) { 1041 HWComposer::LayerListIterator cur = hwc.begin(id); 1042 const HWComposer::LayerListIterator end = hwc.end(id); 1043 for (size_t i = 0; cur != end && i < count; ++i, ++cur) { 1044 currentLayers[i]->onLayerDisplayed(hw, &*cur); 1045 } 1046 } else { 1047 for (size_t i = 0; i < count; i++) { 1048 currentLayers[i]->onLayerDisplayed(hw, NULL); 1049 } 1050 } 1051 } 1052 1053 mLastSwapBufferTime = systemTime() - now; 1054 mDebugInSwapBuffers = 0; 1055} 1056 1057void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 1058{ 1059 ATRACE_CALL(); 1060 1061 Mutex::Autolock _l(mStateLock); 1062 const nsecs_t now = systemTime(); 1063 mDebugInTransaction = now; 1064 1065 // Here we're guaranteed that some transaction flags are set 1066 // so we can call handleTransactionLocked() unconditionally. 1067 // We call getTransactionFlags(), which will also clear the flags, 1068 // with mStateLock held to guarantee that mCurrentState won't change 1069 // until the transaction is committed. 1070 1071 transactionFlags = getTransactionFlags(eTransactionMask); 1072 handleTransactionLocked(transactionFlags); 1073 1074 mLastTransactionTime = systemTime() - now; 1075 mDebugInTransaction = 0; 1076 invalidateHwcGeometry(); 1077 // here the transaction has been committed 1078} 1079 1080void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 1081{ 1082 const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 1083 const size_t count = currentLayers.size(); 1084 1085 /* 1086 * Traversal of the children 1087 * (perform the transaction for each of them if needed) 1088 */ 1089 1090 if (transactionFlags & eTraversalNeeded) { 1091 for (size_t i=0 ; i<count ; i++) { 1092 const sp<LayerBase>& layer = currentLayers[i]; 1093 uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 1094 if (!trFlags) continue; 1095 1096 const uint32_t flags = layer->doTransaction(0); 1097 if (flags & Layer::eVisibleRegion) 1098 mVisibleRegionsDirty = true; 1099 } 1100 } 1101 1102 /* 1103 * Perform display own transactions if needed 1104 */ 1105 1106 if (transactionFlags & eDisplayTransactionNeeded) { 1107 // here we take advantage of Vector's copy-on-write semantics to 1108 // improve performance by skipping the transaction entirely when 1109 // know that the lists are identical 1110 const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays); 1111 const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays); 1112 if (!curr.isIdenticalTo(draw)) { 1113 mVisibleRegionsDirty = true; 1114 const size_t cc = curr.size(); 1115 size_t dc = draw.size(); 1116 1117 // find the displays that were removed 1118 // (ie: in drawing state but not in current state) 1119 // also handle displays that changed 1120 // (ie: displays that are in both lists) 1121 for (size_t i=0 ; i<dc ; i++) { 1122 const ssize_t j = curr.indexOfKey(draw.keyAt(i)); 1123 if (j < 0) { 1124 // in drawing state but not in current state 1125 if (!draw[i].isMainDisplay()) { 1126 // Call makeCurrent() on the primary display so we can 1127 // be sure that nothing associated with this display 1128 // is current. 1129 const sp<const DisplayDevice>& hw(getDefaultDisplayDevice()); 1130 DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); 1131 mDisplays.removeItem(draw.keyAt(i)); 1132 getHwComposer().disconnectDisplay(draw[i].type); 1133 } else { 1134 ALOGW("trying to remove the main display"); 1135 } 1136 } else { 1137 // this display is in both lists. see if something changed. 1138 const DisplayDeviceState& state(curr[j]); 1139 const wp<IBinder>& display(curr.keyAt(j)); 1140 if (state.surface->asBinder() != draw[i].surface->asBinder()) { 1141 // changing the surface is like destroying and 1142 // recreating the DisplayDevice, so we just remove it 1143 // from the drawing state, so that it get re-added 1144 // below. 1145 mDisplays.removeItem(display); 1146 mDrawingState.displays.removeItemsAt(i); 1147 dc--; i--; 1148 // at this point we must loop to the next item 1149 continue; 1150 } 1151 1152 const sp<DisplayDevice>& disp(getDisplayDevice(display)); 1153 if (disp != NULL) { 1154 if (state.layerStack != draw[i].layerStack) { 1155 disp->setLayerStack(state.layerStack); 1156 } 1157 if ((state.orientation != draw[i].orientation) 1158 || (state.viewport != draw[i].viewport) 1159 || (state.frame != draw[i].frame)) 1160 { 1161 disp->setProjection(state.orientation, 1162 state.viewport, state.frame); 1163 } 1164 1165 // Walk through all the layers in currentLayers, 1166 // and update their transform hint. 1167 // 1168 // TODO: we could be much more clever about which 1169 // layers we touch and how often we do these updates 1170 // (e.g. only touch the layers associated with this 1171 // display, and only on a rotation). 1172 for (size_t i = 0; i < count; i++) { 1173 const sp<LayerBase>& layerBase = currentLayers[i]; 1174 layerBase->updateTransformHint(); 1175 } 1176 } 1177 } 1178 } 1179 1180 // find displays that were added 1181 // (ie: in current state but not in drawing state) 1182 for (size_t i=0 ; i<cc ; i++) { 1183 if (draw.indexOfKey(curr.keyAt(i)) < 0) { 1184 const DisplayDeviceState& state(curr[i]); 1185 1186 sp<FramebufferSurface> fbs; 1187 sp<SurfaceTextureClient> stc; 1188 if (!state.isVirtualDisplay()) { 1189 1190 ALOGE_IF(state.surface!=NULL, 1191 "adding a supported display, but rendering " 1192 "surface is provided (%p), ignoring it", 1193 state.surface.get()); 1194 1195 // for supported (by hwc) displays we provide our 1196 // own rendering surface 1197 fbs = new FramebufferSurface(*mHwc, state.type); 1198 stc = new SurfaceTextureClient( 1199 static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue())); 1200 } else { 1201 if (state.surface != NULL) { 1202 stc = new SurfaceTextureClient(state.surface); 1203 } 1204 } 1205 1206 const wp<IBinder>& display(curr.keyAt(i)); 1207 if (stc != NULL) { 1208 sp<DisplayDevice> hw = new DisplayDevice(this, 1209 state.type, display, stc, fbs, mEGLConfig); 1210 hw->setLayerStack(state.layerStack); 1211 hw->setProjection(state.orientation, 1212 state.viewport, state.frame); 1213 hw->setDisplayName(state.displayName); 1214 mDisplays.add(display, hw); 1215 if (hw->getDisplayType() < DisplayDevice::NUM_DISPLAY_TYPES) { 1216 // notify the system that this display is now up 1217 // (note onScreenAcquired() is safe to call from 1218 // here because we're in the main thread) 1219 onScreenAcquired(hw); 1220 } 1221 } 1222 } 1223 } 1224 } 1225 } 1226 1227 /* 1228 * Perform our own transaction if needed 1229 */ 1230 1231 const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 1232 if (currentLayers.size() > previousLayers.size()) { 1233 // layers have been added 1234 mVisibleRegionsDirty = true; 1235 } 1236 1237 // some layers might have been removed, so 1238 // we need to update the regions they're exposing. 1239 if (mLayersRemoved) { 1240 mLayersRemoved = false; 1241 mVisibleRegionsDirty = true; 1242 const size_t count = previousLayers.size(); 1243 for (size_t i=0 ; i<count ; i++) { 1244 const sp<LayerBase>& layer(previousLayers[i]); 1245 if (currentLayers.indexOf(layer) < 0) { 1246 // this layer is not visible anymore 1247 // TODO: we could traverse the tree from front to back and 1248 // compute the actual visible region 1249 // TODO: we could cache the transformed region 1250 const Layer::State& s(layer->drawingState()); 1251 Region visibleReg = s.transform.transform( 1252 Region(Rect(s.active.w, s.active.h))); 1253 invalidateLayerStack(s.layerStack, visibleReg); 1254 } 1255 } 1256 } 1257 1258 commitTransaction(); 1259} 1260 1261void SurfaceFlinger::commitTransaction() 1262{ 1263 if (!mLayersPendingRemoval.isEmpty()) { 1264 // Notify removed layers now that they can't be drawn from 1265 for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) { 1266 mLayersPendingRemoval[i]->onRemoved(); 1267 } 1268 mLayersPendingRemoval.clear(); 1269 } 1270 1271 mDrawingState = mCurrentState; 1272 mTransationPending = false; 1273 mTransactionCV.broadcast(); 1274} 1275 1276void SurfaceFlinger::computeVisibleRegions( 1277 const LayerVector& currentLayers, uint32_t layerStack, 1278 Region& outDirtyRegion, Region& outOpaqueRegion) 1279{ 1280 ATRACE_CALL(); 1281 1282 Region aboveOpaqueLayers; 1283 Region aboveCoveredLayers; 1284 Region dirty; 1285 1286 outDirtyRegion.clear(); 1287 1288 size_t i = currentLayers.size(); 1289 while (i--) { 1290 const sp<LayerBase>& layer = currentLayers[i]; 1291 1292 // start with the whole surface at its current location 1293 const Layer::State& s(layer->drawingState()); 1294 1295 // only consider the layers on the given later stack 1296 if (s.layerStack != layerStack) 1297 continue; 1298 1299 /* 1300 * opaqueRegion: area of a surface that is fully opaque. 1301 */ 1302 Region opaqueRegion; 1303 1304 /* 1305 * visibleRegion: area of a surface that is visible on screen 1306 * and not fully transparent. This is essentially the layer's 1307 * footprint minus the opaque regions above it. 1308 * Areas covered by a translucent surface are considered visible. 1309 */ 1310 Region visibleRegion; 1311 1312 /* 1313 * coveredRegion: area of a surface that is covered by all 1314 * visible regions above it (which includes the translucent areas). 1315 */ 1316 Region coveredRegion; 1317 1318 /* 1319 * transparentRegion: area of a surface that is hinted to be completely 1320 * transparent. This is only used to tell when the layer has no visible 1321 * non-transparent regions and can be removed from the layer list. It 1322 * does not affect the visibleRegion of this layer or any layers 1323 * beneath it. The hint may not be correct if apps don't respect the 1324 * SurfaceView restrictions (which, sadly, some don't). 1325 */ 1326 Region transparentRegion; 1327 1328 1329 // handle hidden surfaces by setting the visible region to empty 1330 if (CC_LIKELY(layer->isVisible())) { 1331 const bool translucent = !layer->isOpaque(); 1332 Rect bounds(layer->computeBounds()); 1333 visibleRegion.set(bounds); 1334 if (!visibleRegion.isEmpty()) { 1335 // Remove the transparent area from the visible region 1336 if (translucent) { 1337 const Transform tr(s.transform); 1338 if (tr.transformed()) { 1339 if (tr.preserveRects()) { 1340 // transform the transparent region 1341 transparentRegion = tr.transform(s.transparentRegion); 1342 } else { 1343 // transformation too complex, can't do the 1344 // transparent region optimization. 1345 transparentRegion.clear(); 1346 } 1347 } else { 1348 transparentRegion = s.transparentRegion; 1349 } 1350 } 1351 1352 // compute the opaque region 1353 const int32_t layerOrientation = s.transform.getOrientation(); 1354 if (s.alpha==255 && !translucent && 1355 ((layerOrientation & Transform::ROT_INVALID) == false)) { 1356 // the opaque region is the layer's footprint 1357 opaqueRegion = visibleRegion; 1358 } 1359 } 1360 } 1361 1362 // Clip the covered region to the visible region 1363 coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 1364 1365 // Update aboveCoveredLayers for next (lower) layer 1366 aboveCoveredLayers.orSelf(visibleRegion); 1367 1368 // subtract the opaque region covered by the layers above us 1369 visibleRegion.subtractSelf(aboveOpaqueLayers); 1370 1371 // compute this layer's dirty region 1372 if (layer->contentDirty) { 1373 // we need to invalidate the whole region 1374 dirty = visibleRegion; 1375 // as well, as the old visible region 1376 dirty.orSelf(layer->visibleRegion); 1377 layer->contentDirty = false; 1378 } else { 1379 /* compute the exposed region: 1380 * the exposed region consists of two components: 1381 * 1) what's VISIBLE now and was COVERED before 1382 * 2) what's EXPOSED now less what was EXPOSED before 1383 * 1384 * note that (1) is conservative, we start with the whole 1385 * visible region but only keep what used to be covered by 1386 * something -- which mean it may have been exposed. 1387 * 1388 * (2) handles areas that were not covered by anything but got 1389 * exposed because of a resize. 1390 */ 1391 const Region newExposed = visibleRegion - coveredRegion; 1392 const Region oldVisibleRegion = layer->visibleRegion; 1393 const Region oldCoveredRegion = layer->coveredRegion; 1394 const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 1395 dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 1396 } 1397 dirty.subtractSelf(aboveOpaqueLayers); 1398 1399 // accumulate to the screen dirty region 1400 outDirtyRegion.orSelf(dirty); 1401 1402 // Update aboveOpaqueLayers for next (lower) layer 1403 aboveOpaqueLayers.orSelf(opaqueRegion); 1404 1405 // Store the visible region in screen space 1406 layer->setVisibleRegion(visibleRegion); 1407 layer->setCoveredRegion(coveredRegion); 1408 layer->setVisibleNonTransparentRegion( 1409 visibleRegion.subtract(transparentRegion)); 1410 } 1411 1412 outOpaqueRegion = aboveOpaqueLayers; 1413} 1414 1415void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack, 1416 const Region& dirty) { 1417 for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 1418 const sp<DisplayDevice>& hw(mDisplays[dpy]); 1419 if (hw->getLayerStack() == layerStack) { 1420 hw->dirtyRegion.orSelf(dirty); 1421 } 1422 } 1423} 1424 1425void SurfaceFlinger::handlePageFlip() 1426{ 1427 Region dirtyRegion; 1428 1429 bool visibleRegions = false; 1430 const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 1431 const size_t count = currentLayers.size(); 1432 for (size_t i=0 ; i<count ; i++) { 1433 const sp<LayerBase>& layer(currentLayers[i]); 1434 const Region dirty(layer->latchBuffer(visibleRegions)); 1435 const Layer::State& s(layer->drawingState()); 1436 invalidateLayerStack(s.layerStack, dirty); 1437 } 1438 1439 mVisibleRegionsDirty |= visibleRegions; 1440} 1441 1442void SurfaceFlinger::invalidateHwcGeometry() 1443{ 1444 mHwWorkListDirty = true; 1445} 1446 1447 1448void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, 1449 const Region& inDirtyRegion) 1450{ 1451 Region dirtyRegion(inDirtyRegion); 1452 1453 // compute the invalid region 1454 hw->swapRegion.orSelf(dirtyRegion); 1455 1456 uint32_t flags = hw->getFlags(); 1457 if (flags & DisplayDevice::SWAP_RECTANGLE) { 1458 // we can redraw only what's dirty, but since SWAP_RECTANGLE only 1459 // takes a rectangle, we must make sure to update that whole 1460 // rectangle in that case 1461 dirtyRegion.set(hw->swapRegion.bounds()); 1462 } else { 1463 if (flags & DisplayDevice::PARTIAL_UPDATES) { 1464 // We need to redraw the rectangle that will be updated 1465 // (pushed to the framebuffer). 1466 // This is needed because PARTIAL_UPDATES only takes one 1467 // rectangle instead of a region (see DisplayDevice::flip()) 1468 dirtyRegion.set(hw->swapRegion.bounds()); 1469 } else { 1470 // we need to redraw everything (the whole screen) 1471 dirtyRegion.set(hw->bounds()); 1472 hw->swapRegion = dirtyRegion; 1473 } 1474 } 1475 1476 doComposeSurfaces(hw, dirtyRegion); 1477 1478 // update the swap region and clear the dirty region 1479 hw->swapRegion.orSelf(dirtyRegion); 1480 1481 // swap buffers (presentation) 1482 hw->swapBuffers(getHwComposer()); 1483} 1484 1485void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty) 1486{ 1487 const int32_t id = hw->getHwcDisplayId(); 1488 HWComposer& hwc(getHwComposer()); 1489 HWComposer::LayerListIterator cur = hwc.begin(id); 1490 const HWComposer::LayerListIterator end = hwc.end(id); 1491 1492 const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end); 1493 if (hasGlesComposition) { 1494 DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); 1495 1496 // set the frame buffer 1497 glMatrixMode(GL_MODELVIEW); 1498 glLoadIdentity(); 1499 1500 // Never touch the framebuffer if we don't have any framebuffer layers 1501 const bool hasHwcComposition = hwc.hasHwcComposition(id); 1502 if (hasHwcComposition) { 1503 // when using overlays, we assume a fully transparent framebuffer 1504 // NOTE: we could reduce how much we need to clear, for instance 1505 // remove where there are opaque FB layers. however, on some 1506 // GPUs doing a "clean slate" glClear might be more efficient. 1507 // We'll revisit later if needed. 1508 glClearColor(0, 0, 0, 0); 1509 glClear(GL_COLOR_BUFFER_BIT); 1510 } else { 1511 const Region region(hw->undefinedRegion.intersect(dirty)); 1512 // screen is already cleared here 1513 if (!region.isEmpty()) { 1514 // can happen with SurfaceView 1515 drawWormhole(hw, region); 1516 } 1517 } 1518 } 1519 1520 /* 1521 * and then, render the layers targeted at the framebuffer 1522 */ 1523 1524 const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 1525 const size_t count = layers.size(); 1526 const Transform& tr = hw->getTransform(); 1527 if (cur != end) { 1528 // we're using h/w composer 1529 for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { 1530 const sp<LayerBase>& layer(layers[i]); 1531 const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); 1532 if (!clip.isEmpty()) { 1533 switch (cur->getCompositionType()) { 1534 case HWC_OVERLAY: { 1535 if ((cur->getHints() & HWC_HINT_CLEAR_FB) 1536 && i 1537 && layer->isOpaque() 1538 && hasGlesComposition) { 1539 // never clear the very first layer since we're 1540 // guaranteed the FB is already cleared 1541 layer->clearWithOpenGL(hw, clip); 1542 } 1543 break; 1544 } 1545 case HWC_FRAMEBUFFER: { 1546 layer->draw(hw, clip); 1547 break; 1548 } 1549 case HWC_FRAMEBUFFER_TARGET: { 1550 // this should not happen as the iterator shouldn't 1551 // let us get there. 1552 ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i); 1553 break; 1554 } 1555 } 1556 } 1557 layer->setAcquireFence(hw, *cur); 1558 } 1559 } else { 1560 // we're not using h/w composer 1561 for (size_t i=0 ; i<count ; ++i) { 1562 const sp<LayerBase>& layer(layers[i]); 1563 const Region clip(dirty.intersect( 1564 tr.transform(layer->visibleRegion))); 1565 if (!clip.isEmpty()) { 1566 layer->draw(hw, clip); 1567 } 1568 } 1569 } 1570} 1571 1572void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, 1573 const Region& region) const 1574{ 1575 glDisable(GL_TEXTURE_EXTERNAL_OES); 1576 glDisable(GL_TEXTURE_2D); 1577 glDisable(GL_BLEND); 1578 glColor4f(0,0,0,0); 1579 1580 const int32_t height = hw->getHeight(); 1581 Region::const_iterator it = region.begin(); 1582 Region::const_iterator const end = region.end(); 1583 while (it != end) { 1584 const Rect& r = *it++; 1585 GLfloat vertices[][2] = { 1586 { r.left, height - r.top }, 1587 { r.left, height - r.bottom }, 1588 { r.right, height - r.bottom }, 1589 { r.right, height - r.top } 1590 }; 1591 glVertexPointer(2, GL_FLOAT, 0, vertices); 1592 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1593 } 1594} 1595 1596ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 1597 const sp<LayerBaseClient>& lbc) 1598{ 1599 // attach this layer to the client 1600 size_t name = client->attachLayer(lbc); 1601 1602 // add this layer to the current state list 1603 Mutex::Autolock _l(mStateLock); 1604 mCurrentState.layersSortedByZ.add(lbc); 1605 1606 return ssize_t(name); 1607} 1608 1609status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 1610{ 1611 Mutex::Autolock _l(mStateLock); 1612 status_t err = purgatorizeLayer_l(layer); 1613 if (err == NO_ERROR) 1614 setTransactionFlags(eTransactionNeeded); 1615 return err; 1616} 1617 1618status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1619{ 1620 ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1621 if (index >= 0) { 1622 mLayersRemoved = true; 1623 return NO_ERROR; 1624 } 1625 return status_t(index); 1626} 1627 1628status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 1629{ 1630 // First add the layer to the purgatory list, which makes sure it won't 1631 // go away, then remove it from the main list (through a transaction). 1632 ssize_t err = removeLayer_l(layerBase); 1633 if (err >= 0) { 1634 mLayerPurgatory.add(layerBase); 1635 } 1636 1637 mLayersPendingRemoval.push(layerBase); 1638 1639 // it's possible that we don't find a layer, because it might 1640 // have been destroyed already -- this is not technically an error 1641 // from the user because there is a race between Client::destroySurface(), 1642 // ~Client() and ~ISurface(). 1643 return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 1644} 1645 1646uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1647{ 1648 return android_atomic_release_load(&mTransactionFlags); 1649} 1650 1651uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1652{ 1653 return android_atomic_and(~flags, &mTransactionFlags) & flags; 1654} 1655 1656uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1657{ 1658 uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1659 if ((old & flags)==0) { // wake the server up 1660 signalTransaction(); 1661 } 1662 return old; 1663} 1664 1665void SurfaceFlinger::setTransactionState( 1666 const Vector<ComposerState>& state, 1667 const Vector<DisplayState>& displays, 1668 uint32_t flags) 1669{ 1670 Mutex::Autolock _l(mStateLock); 1671 uint32_t transactionFlags = 0; 1672 1673 size_t count = displays.size(); 1674 for (size_t i=0 ; i<count ; i++) { 1675 const DisplayState& s(displays[i]); 1676 transactionFlags |= setDisplayStateLocked(s); 1677 } 1678 1679 count = state.size(); 1680 for (size_t i=0 ; i<count ; i++) { 1681 const ComposerState& s(state[i]); 1682 sp<Client> client( static_cast<Client *>(s.client.get()) ); 1683 transactionFlags |= setClientStateLocked(client, s.state); 1684 } 1685 1686 if (transactionFlags) { 1687 // this triggers the transaction 1688 setTransactionFlags(transactionFlags); 1689 1690 // if this is a synchronous transaction, wait for it to take effect 1691 // before returning. 1692 if (flags & eSynchronous) { 1693 mTransationPending = true; 1694 } 1695 while (mTransationPending) { 1696 status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1697 if (CC_UNLIKELY(err != NO_ERROR)) { 1698 // just in case something goes wrong in SF, return to the 1699 // called after a few seconds. 1700 ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1701 mTransationPending = false; 1702 break; 1703 } 1704 } 1705 } 1706} 1707 1708uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) 1709{ 1710 ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); 1711 if (dpyIdx < 0) 1712 return 0; 1713 1714 uint32_t flags = 0; 1715 DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); 1716 if (disp.isValid()) { 1717 const uint32_t what = s.what; 1718 if (what & DisplayState::eSurfaceChanged) { 1719 if (disp.surface->asBinder() != s.surface->asBinder()) { 1720 disp.surface = s.surface; 1721 flags |= eDisplayTransactionNeeded; 1722 } 1723 } 1724 if (what & DisplayState::eLayerStackChanged) { 1725 if (disp.layerStack != s.layerStack) { 1726 disp.layerStack = s.layerStack; 1727 flags |= eDisplayTransactionNeeded; 1728 } 1729 } 1730 if (what & DisplayState::eDisplayProjectionChanged) { 1731 if (disp.orientation != s.orientation) { 1732 disp.orientation = s.orientation; 1733 flags |= eDisplayTransactionNeeded; 1734 } 1735 if (disp.frame != s.frame) { 1736 disp.frame = s.frame; 1737 flags |= eDisplayTransactionNeeded; 1738 } 1739 if (disp.viewport != s.viewport) { 1740 disp.viewport = s.viewport; 1741 flags |= eDisplayTransactionNeeded; 1742 } 1743 } 1744 } 1745 return flags; 1746} 1747 1748uint32_t SurfaceFlinger::setClientStateLocked( 1749 const sp<Client>& client, 1750 const layer_state_t& s) 1751{ 1752 uint32_t flags = 0; 1753 sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1754 if (layer != 0) { 1755 const uint32_t what = s.what; 1756 if (what & layer_state_t::ePositionChanged) { 1757 if (layer->setPosition(s.x, s.y)) 1758 flags |= eTraversalNeeded; 1759 } 1760 if (what & layer_state_t::eLayerChanged) { 1761 // NOTE: index needs to be calculated before we update the state 1762 ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1763 if (layer->setLayer(s.z)) { 1764 mCurrentState.layersSortedByZ.removeAt(idx); 1765 mCurrentState.layersSortedByZ.add(layer); 1766 // we need traversal (state changed) 1767 // AND transaction (list changed) 1768 flags |= eTransactionNeeded|eTraversalNeeded; 1769 } 1770 } 1771 if (what & layer_state_t::eSizeChanged) { 1772 if (layer->setSize(s.w, s.h)) { 1773 flags |= eTraversalNeeded; 1774 } 1775 } 1776 if (what & layer_state_t::eAlphaChanged) { 1777 if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1778 flags |= eTraversalNeeded; 1779 } 1780 if (what & layer_state_t::eMatrixChanged) { 1781 if (layer->setMatrix(s.matrix)) 1782 flags |= eTraversalNeeded; 1783 } 1784 if (what & layer_state_t::eTransparentRegionChanged) { 1785 if (layer->setTransparentRegionHint(s.transparentRegion)) 1786 flags |= eTraversalNeeded; 1787 } 1788 if (what & layer_state_t::eVisibilityChanged) { 1789 if (layer->setFlags(s.flags, s.mask)) 1790 flags |= eTraversalNeeded; 1791 } 1792 if (what & layer_state_t::eCropChanged) { 1793 if (layer->setCrop(s.crop)) 1794 flags |= eTraversalNeeded; 1795 } 1796 if (what & layer_state_t::eLayerStackChanged) { 1797 // NOTE: index needs to be calculated before we update the state 1798 ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1799 if (layer->setLayerStack(s.layerStack)) { 1800 mCurrentState.layersSortedByZ.removeAt(idx); 1801 mCurrentState.layersSortedByZ.add(layer); 1802 // we need traversal (state changed) 1803 // AND transaction (list changed) 1804 flags |= eTransactionNeeded|eTraversalNeeded; 1805 } 1806 } 1807 } 1808 return flags; 1809} 1810 1811sp<ISurface> SurfaceFlinger::createLayer( 1812 ISurfaceComposerClient::surface_data_t* params, 1813 const String8& name, 1814 const sp<Client>& client, 1815 uint32_t w, uint32_t h, PixelFormat format, 1816 uint32_t flags) 1817{ 1818 sp<LayerBaseClient> layer; 1819 sp<ISurface> surfaceHandle; 1820 1821 if (int32_t(w|h) < 0) { 1822 ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", 1823 int(w), int(h)); 1824 return surfaceHandle; 1825 } 1826 1827 //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); 1828 switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { 1829 case ISurfaceComposerClient::eFXSurfaceNormal: 1830 layer = createNormalLayer(client, w, h, flags, format); 1831 break; 1832 case ISurfaceComposerClient::eFXSurfaceBlur: 1833 case ISurfaceComposerClient::eFXSurfaceDim: 1834 layer = createDimLayer(client, w, h, flags); 1835 break; 1836 case ISurfaceComposerClient::eFXSurfaceScreenshot: 1837 layer = createScreenshotLayer(client, w, h, flags); 1838 break; 1839 } 1840 1841 if (layer != 0) { 1842 layer->initStates(w, h, flags); 1843 layer->setName(name); 1844 ssize_t token = addClientLayer(client, layer); 1845 surfaceHandle = layer->getSurface(); 1846 if (surfaceHandle != 0) { 1847 params->token = token; 1848 params->identity = layer->getIdentity(); 1849 } 1850 setTransactionFlags(eTransactionNeeded); 1851 } 1852 1853 return surfaceHandle; 1854} 1855 1856sp<Layer> SurfaceFlinger::createNormalLayer( 1857 const sp<Client>& client, 1858 uint32_t w, uint32_t h, uint32_t flags, 1859 PixelFormat& format) 1860{ 1861 // initialize the surfaces 1862 switch (format) { 1863 case PIXEL_FORMAT_TRANSPARENT: 1864 case PIXEL_FORMAT_TRANSLUCENT: 1865 format = PIXEL_FORMAT_RGBA_8888; 1866 break; 1867 case PIXEL_FORMAT_OPAQUE: 1868#ifdef NO_RGBX_8888 1869 format = PIXEL_FORMAT_RGB_565; 1870#else 1871 format = PIXEL_FORMAT_RGBX_8888; 1872#endif 1873 break; 1874 } 1875 1876#ifdef NO_RGBX_8888 1877 if (format == PIXEL_FORMAT_RGBX_8888) 1878 format = PIXEL_FORMAT_RGBA_8888; 1879#endif 1880 1881 sp<Layer> layer = new Layer(this, client); 1882 status_t err = layer->setBuffers(w, h, format, flags); 1883 if (CC_LIKELY(err != NO_ERROR)) { 1884 ALOGE("createNormalLayer() failed (%s)", strerror(-err)); 1885 layer.clear(); 1886 } 1887 return layer; 1888} 1889 1890sp<LayerDim> SurfaceFlinger::createDimLayer( 1891 const sp<Client>& client, 1892 uint32_t w, uint32_t h, uint32_t flags) 1893{ 1894 sp<LayerDim> layer = new LayerDim(this, client); 1895 return layer; 1896} 1897 1898sp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer( 1899 const sp<Client>& client, 1900 uint32_t w, uint32_t h, uint32_t flags) 1901{ 1902 sp<LayerScreenshot> layer = new LayerScreenshot(this, client); 1903 return layer; 1904} 1905 1906status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, SurfaceID sid) 1907{ 1908 /* 1909 * called by the window manager, when a surface should be marked for 1910 * destruction. 1911 * 1912 * The surface is removed from the current and drawing lists, but placed 1913 * in the purgatory queue, so it's not destroyed right-away (we need 1914 * to wait for all client's references to go away first). 1915 */ 1916 1917 status_t err = NAME_NOT_FOUND; 1918 Mutex::Autolock _l(mStateLock); 1919 sp<LayerBaseClient> layer = client->getLayerUser(sid); 1920 1921 if (layer != 0) { 1922 err = purgatorizeLayer_l(layer); 1923 if (err == NO_ERROR) { 1924 setTransactionFlags(eTransactionNeeded); 1925 } 1926 } 1927 return err; 1928} 1929 1930status_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer) 1931{ 1932 // called by ~ISurface() when all references are gone 1933 status_t err = NO_ERROR; 1934 sp<LayerBaseClient> l(layer.promote()); 1935 if (l != NULL) { 1936 Mutex::Autolock _l(mStateLock); 1937 err = removeLayer_l(l); 1938 if (err == NAME_NOT_FOUND) { 1939 // The surface wasn't in the current list, which means it was 1940 // removed already, which means it is in the purgatory, 1941 // and need to be removed from there. 1942 ssize_t idx = mLayerPurgatory.remove(l); 1943 ALOGE_IF(idx < 0, 1944 "layer=%p is not in the purgatory list", l.get()); 1945 } 1946 ALOGE_IF(err<0 && err != NAME_NOT_FOUND, 1947 "error removing layer=%p (%s)", l.get(), strerror(-err)); 1948 } 1949 return err; 1950} 1951 1952// --------------------------------------------------------------------------- 1953 1954void SurfaceFlinger::onInitializeDisplays() { 1955 // reset screen orientation 1956 Vector<ComposerState> state; 1957 Vector<DisplayState> displays; 1958 DisplayState d; 1959 d.what = DisplayState::eDisplayProjectionChanged; 1960 d.token = mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY]; 1961 d.orientation = DisplayState::eOrientationDefault; 1962 d.frame.makeInvalid(); 1963 d.viewport.makeInvalid(); 1964 displays.add(d); 1965 setTransactionState(state, displays, 0); 1966 onScreenAcquired(getDefaultDisplayDevice()); 1967} 1968 1969void SurfaceFlinger::initializeDisplays() { 1970 class MessageScreenInitialized : public MessageBase { 1971 SurfaceFlinger* flinger; 1972 public: 1973 MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } 1974 virtual bool handler() { 1975 flinger->onInitializeDisplays(); 1976 return true; 1977 } 1978 }; 1979 sp<MessageBase> msg = new MessageScreenInitialized(this); 1980 postMessageAsync(msg); // we may be called from main thread, use async message 1981} 1982 1983 1984void SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) { 1985 ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this); 1986 if (hw->isScreenAcquired()) { 1987 // this is expected, e.g. when power manager wakes up during boot 1988 ALOGD(" screen was previously acquired"); 1989 return; 1990 } 1991 1992 hw->acquireScreen(); 1993 int32_t type = hw->getDisplayType(); 1994 if (type < DisplayDevice::NUM_DISPLAY_TYPES) { 1995 // built-in display, tell the HWC 1996 getHwComposer().acquire(type); 1997 1998 if (type == DisplayDevice::DISPLAY_PRIMARY) { 1999 // FIXME: eventthread only knows about the main display right now 2000 mEventThread->onScreenAcquired(); 2001 } 2002 } 2003 mVisibleRegionsDirty = true; 2004 repaintEverything(); 2005} 2006 2007void SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) { 2008 ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this); 2009 if (!hw->isScreenAcquired()) { 2010 ALOGD(" screen was previously released"); 2011 return; 2012 } 2013 2014 hw->releaseScreen(); 2015 int32_t type = hw->getDisplayType(); 2016 if (type < DisplayDevice::NUM_DISPLAY_TYPES) { 2017 if (type == DisplayDevice::DISPLAY_PRIMARY) { 2018 // FIXME: eventthread only knows about the main display right now 2019 mEventThread->onScreenReleased(); 2020 } 2021 2022 // built-in display, tell the HWC 2023 getHwComposer().release(type); 2024 } 2025 mVisibleRegionsDirty = true; 2026 // from this point on, SF will stop drawing on this display 2027} 2028 2029void SurfaceFlinger::unblank(const sp<IBinder>& display) { 2030 class MessageScreenAcquired : public MessageBase { 2031 SurfaceFlinger* mFlinger; 2032 const sp<DisplayDevice>& mHw; 2033 public: 2034 MessageScreenAcquired(SurfaceFlinger* flinger, 2035 const sp<DisplayDevice>& hw) : mFlinger(flinger), mHw(hw) { } 2036 virtual bool handler() { 2037 mFlinger->onScreenAcquired(mHw); 2038 return true; 2039 } 2040 }; 2041 const sp<DisplayDevice>& hw = getDisplayDevice(display); 2042 if (hw == NULL) { 2043 ALOGE("Attempt to unblank null display %p", display.get()); 2044 } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) { 2045 ALOGW("Attempt to unblank virtual display"); 2046 } else { 2047 sp<MessageBase> msg = new MessageScreenAcquired(this, hw); 2048 postMessageSync(msg); 2049 } 2050} 2051 2052void SurfaceFlinger::blank(const sp<IBinder>& display) { 2053 class MessageScreenReleased : public MessageBase { 2054 SurfaceFlinger* mFlinger; 2055 const sp<DisplayDevice>& mHw; 2056 public: 2057 MessageScreenReleased(SurfaceFlinger* flinger, 2058 const sp<DisplayDevice>& hw) : mFlinger(flinger), mHw(hw) { } 2059 virtual bool handler() { 2060 mFlinger->onScreenReleased(mHw); 2061 return true; 2062 } 2063 }; 2064 const sp<DisplayDevice>& hw = getDisplayDevice(display); 2065 if (hw == NULL) { 2066 ALOGE("Attempt to blank null display %p", display.get()); 2067 } else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) { 2068 ALOGW("Attempt to blank virtual display"); 2069 } else { 2070 sp<MessageBase> msg = new MessageScreenReleased(this, hw); 2071 postMessageSync(msg); 2072 } 2073} 2074 2075// --------------------------------------------------------------------------- 2076 2077status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 2078{ 2079 const size_t SIZE = 4096; 2080 char buffer[SIZE]; 2081 String8 result; 2082 2083 if (!PermissionCache::checkCallingPermission(sDump)) { 2084 snprintf(buffer, SIZE, "Permission Denial: " 2085 "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 2086 IPCThreadState::self()->getCallingPid(), 2087 IPCThreadState::self()->getCallingUid()); 2088 result.append(buffer); 2089 } else { 2090 // Try to get the main lock, but don't insist if we can't 2091 // (this would indicate SF is stuck, but we want to be able to 2092 // print something in dumpsys). 2093 int retry = 3; 2094 while (mStateLock.tryLock()<0 && --retry>=0) { 2095 usleep(1000000); 2096 } 2097 const bool locked(retry >= 0); 2098 if (!locked) { 2099 snprintf(buffer, SIZE, 2100 "SurfaceFlinger appears to be unresponsive, " 2101 "dumping anyways (no locks held)\n"); 2102 result.append(buffer); 2103 } 2104 2105 bool dumpAll = true; 2106 size_t index = 0; 2107 size_t numArgs = args.size(); 2108 if (numArgs) { 2109 if ((index < numArgs) && 2110 (args[index] == String16("--list"))) { 2111 index++; 2112 listLayersLocked(args, index, result, buffer, SIZE); 2113 dumpAll = false; 2114 } 2115 2116 if ((index < numArgs) && 2117 (args[index] == String16("--latency"))) { 2118 index++; 2119 dumpStatsLocked(args, index, result, buffer, SIZE); 2120 dumpAll = false; 2121 } 2122 2123 if ((index < numArgs) && 2124 (args[index] == String16("--latency-clear"))) { 2125 index++; 2126 clearStatsLocked(args, index, result, buffer, SIZE); 2127 dumpAll = false; 2128 } 2129 } 2130 2131 if (dumpAll) { 2132 dumpAllLocked(result, buffer, SIZE); 2133 } 2134 2135 if (locked) { 2136 mStateLock.unlock(); 2137 } 2138 } 2139 write(fd, result.string(), result.size()); 2140 return NO_ERROR; 2141} 2142 2143void SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index, 2144 String8& result, char* buffer, size_t SIZE) const 2145{ 2146 const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 2147 const size_t count = currentLayers.size(); 2148 for (size_t i=0 ; i<count ; i++) { 2149 const sp<LayerBase>& layer(currentLayers[i]); 2150 snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 2151 result.append(buffer); 2152 } 2153} 2154 2155void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index, 2156 String8& result, char* buffer, size_t SIZE) const 2157{ 2158 String8 name; 2159 if (index < args.size()) { 2160 name = String8(args[index]); 2161 index++; 2162 } 2163 2164 const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 2165 const size_t count = currentLayers.size(); 2166 for (size_t i=0 ; i<count ; i++) { 2167 const sp<LayerBase>& layer(currentLayers[i]); 2168 if (name.isEmpty()) { 2169 snprintf(buffer, SIZE, "%s\n", layer->getName().string()); 2170 result.append(buffer); 2171 } 2172 if (name.isEmpty() || (name == layer->getName())) { 2173 layer->dumpStats(result, buffer, SIZE); 2174 } 2175 } 2176} 2177 2178void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, 2179 String8& result, char* buffer, size_t SIZE) const 2180{ 2181 String8 name; 2182 if (index < args.size()) { 2183 name = String8(args[index]); 2184 index++; 2185 } 2186 2187 const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 2188 const size_t count = currentLayers.size(); 2189 for (size_t i=0 ; i<count ; i++) { 2190 const sp<LayerBase>& layer(currentLayers[i]); 2191 if (name.isEmpty() || (name == layer->getName())) { 2192 layer->clearStats(); 2193 } 2194 } 2195} 2196 2197/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) 2198{ 2199 static const char* config = 2200 " [sf" 2201#ifdef NO_RGBX_8888 2202 " NO_RGBX_8888" 2203#endif 2204#ifdef HAS_CONTEXT_PRIORITY 2205 " HAS_CONTEXT_PRIORITY" 2206#endif 2207#ifdef NEVER_DEFAULT_TO_ASYNC_MODE 2208 " NEVER_DEFAULT_TO_ASYNC_MODE" 2209#endif 2210#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 2211 " TARGET_DISABLE_TRIPLE_BUFFERING" 2212#endif 2213 "]"; 2214 result.append(config); 2215} 2216 2217void SurfaceFlinger::dumpAllLocked( 2218 String8& result, char* buffer, size_t SIZE) const 2219{ 2220 // figure out if we're stuck somewhere 2221 const nsecs_t now = systemTime(); 2222 const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 2223 const nsecs_t inTransaction(mDebugInTransaction); 2224 nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 2225 nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 2226 2227 /* 2228 * Dump library configuration. 2229 */ 2230 result.append("Build configuration:"); 2231 appendSfConfigString(result); 2232 appendUiConfigString(result); 2233 appendGuiConfigString(result); 2234 result.append("\n"); 2235 2236 /* 2237 * Dump the visible layer list 2238 */ 2239 const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 2240 const size_t count = currentLayers.size(); 2241 snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 2242 result.append(buffer); 2243 for (size_t i=0 ; i<count ; i++) { 2244 const sp<LayerBase>& layer(currentLayers[i]); 2245 layer->dump(result, buffer, SIZE); 2246 } 2247 2248 /* 2249 * Dump the layers in the purgatory 2250 */ 2251 2252 const size_t purgatorySize = mLayerPurgatory.size(); 2253 snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 2254 result.append(buffer); 2255 for (size_t i=0 ; i<purgatorySize ; i++) { 2256 const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 2257 layer->shortDump(result, buffer, SIZE); 2258 } 2259 2260 /* 2261 * Dump Display state 2262 */ 2263 2264 snprintf(buffer, SIZE, "Displays (%d entries)\n", mDisplays.size()); 2265 result.append(buffer); 2266 for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { 2267 const sp<const DisplayDevice>& hw(mDisplays[dpy]); 2268 hw->dump(result, buffer, SIZE); 2269 } 2270 2271 /* 2272 * Dump SurfaceFlinger global state 2273 */ 2274 2275 snprintf(buffer, SIZE, "SurfaceFlinger global state:\n"); 2276 result.append(buffer); 2277 2278 HWComposer& hwc(getHwComposer()); 2279 sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 2280 const GLExtensions& extensions(GLExtensions::getInstance()); 2281 snprintf(buffer, SIZE, "GLES: %s, %s, %s\n", 2282 extensions.getVendor(), 2283 extensions.getRenderer(), 2284 extensions.getVersion()); 2285 result.append(buffer); 2286 2287 snprintf(buffer, SIZE, "EGL : %s\n", 2288 eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID)); 2289 result.append(buffer); 2290 2291 snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension()); 2292 result.append(buffer); 2293 2294 hw->undefinedRegion.dump(result, "undefinedRegion"); 2295 snprintf(buffer, SIZE, 2296 " orientation=%d, canDraw=%d\n", 2297 hw->getOrientation(), hw->canDraw()); 2298 result.append(buffer); 2299 snprintf(buffer, SIZE, 2300 " last eglSwapBuffers() time: %f us\n" 2301 " last transaction time : %f us\n" 2302 " transaction-flags : %08x\n" 2303 " refresh-rate : %f fps\n" 2304 " x-dpi : %f\n" 2305 " y-dpi : %f\n", 2306 mLastSwapBufferTime/1000.0, 2307 mLastTransactionTime/1000.0, 2308 mTransactionFlags, 2309 1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY), 2310 hwc.getDpiX(HWC_DISPLAY_PRIMARY), 2311 hwc.getDpiY(HWC_DISPLAY_PRIMARY)); 2312 result.append(buffer); 2313 2314 snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 2315 inSwapBuffersDuration/1000.0); 2316 result.append(buffer); 2317 2318 snprintf(buffer, SIZE, " transaction time: %f us\n", 2319 inTransactionDuration/1000.0); 2320 result.append(buffer); 2321 2322 /* 2323 * VSYNC state 2324 */ 2325 mEventThread->dump(result, buffer, SIZE); 2326 2327 /* 2328 * Dump HWComposer state 2329 */ 2330 snprintf(buffer, SIZE, "h/w composer state:\n"); 2331 result.append(buffer); 2332 snprintf(buffer, SIZE, " h/w composer %s and %s\n", 2333 hwc.initCheck()==NO_ERROR ? "present" : "not present", 2334 (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); 2335 result.append(buffer); 2336 hwc.dump(result, buffer, SIZE, hw->getVisibleLayersSortedByZ()); 2337 2338 /* 2339 * Dump gralloc state 2340 */ 2341 const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 2342 alloc.dump(result); 2343} 2344 2345bool SurfaceFlinger::startDdmConnection() 2346{ 2347 void* libddmconnection_dso = 2348 dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW); 2349 if (!libddmconnection_dso) { 2350 return false; 2351 } 2352 void (*DdmConnection_start)(const char* name); 2353 DdmConnection_start = 2354 (typeof DdmConnection_start)dlsym(libddmconnection_dso, "DdmConnection_start"); 2355 if (!DdmConnection_start) { 2356 dlclose(libddmconnection_dso); 2357 return false; 2358 } 2359 (*DdmConnection_start)(getServiceName()); 2360 return true; 2361} 2362 2363status_t SurfaceFlinger::onTransact( 2364 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2365{ 2366 switch (code) { 2367 case CREATE_CONNECTION: 2368 case SET_TRANSACTION_STATE: 2369 case BOOT_FINISHED: 2370 case BLANK: 2371 case UNBLANK: 2372 { 2373 // codes that require permission check 2374 IPCThreadState* ipc = IPCThreadState::self(); 2375 const int pid = ipc->getCallingPid(); 2376 const int uid = ipc->getCallingUid(); 2377 if ((uid != AID_GRAPHICS) && 2378 !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 2379 ALOGE("Permission Denial: " 2380 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2381 return PERMISSION_DENIED; 2382 } 2383 break; 2384 } 2385 case CAPTURE_SCREEN: 2386 { 2387 // codes that require permission check 2388 IPCThreadState* ipc = IPCThreadState::self(); 2389 const int pid = ipc->getCallingPid(); 2390 const int uid = ipc->getCallingUid(); 2391 if ((uid != AID_GRAPHICS) && 2392 !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 2393 ALOGE("Permission Denial: " 2394 "can't read framebuffer pid=%d, uid=%d", pid, uid); 2395 return PERMISSION_DENIED; 2396 } 2397 break; 2398 } 2399 } 2400 2401 status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 2402 if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 2403 CHECK_INTERFACE(ISurfaceComposer, data, reply); 2404 if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 2405 IPCThreadState* ipc = IPCThreadState::self(); 2406 const int pid = ipc->getCallingPid(); 2407 const int uid = ipc->getCallingUid(); 2408 ALOGE("Permission Denial: " 2409 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 2410 return PERMISSION_DENIED; 2411 } 2412 int n; 2413 switch (code) { 2414 case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 2415 case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 2416 return NO_ERROR; 2417 case 1002: // SHOW_UPDATES 2418 n = data.readInt32(); 2419 mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 2420 invalidateHwcGeometry(); 2421 repaintEverything(); 2422 return NO_ERROR; 2423 case 1004:{ // repaint everything 2424 repaintEverything(); 2425 return NO_ERROR; 2426 } 2427 case 1005:{ // force transaction 2428 setTransactionFlags( 2429 eTransactionNeeded| 2430 eDisplayTransactionNeeded| 2431 eTraversalNeeded); 2432 return NO_ERROR; 2433 } 2434 case 1006:{ // send empty update 2435 signalRefresh(); 2436 return NO_ERROR; 2437 } 2438 case 1008: // toggle use of hw composer 2439 n = data.readInt32(); 2440 mDebugDisableHWC = n ? 1 : 0; 2441 invalidateHwcGeometry(); 2442 repaintEverything(); 2443 return NO_ERROR; 2444 case 1009: // toggle use of transform hint 2445 n = data.readInt32(); 2446 mDebugDisableTransformHint = n ? 1 : 0; 2447 invalidateHwcGeometry(); 2448 repaintEverything(); 2449 return NO_ERROR; 2450 case 1010: // interrogate. 2451 reply->writeInt32(0); 2452 reply->writeInt32(0); 2453 reply->writeInt32(mDebugRegion); 2454 reply->writeInt32(0); 2455 reply->writeInt32(mDebugDisableHWC); 2456 return NO_ERROR; 2457 case 1013: { 2458 Mutex::Autolock _l(mStateLock); 2459 sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 2460 reply->writeInt32(hw->getPageFlipCount()); 2461 } 2462 return NO_ERROR; 2463 } 2464 } 2465 return err; 2466} 2467 2468void SurfaceFlinger::repaintEverything() { 2469 android_atomic_or(1, &mRepaintEverything); 2470 signalTransaction(); 2471} 2472 2473// --------------------------------------------------------------------------- 2474 2475status_t SurfaceFlinger::renderScreenToTexture(uint32_t layerStack, 2476 GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2477{ 2478 Mutex::Autolock _l(mStateLock); 2479 return renderScreenToTextureLocked(layerStack, textureName, uOut, vOut); 2480} 2481 2482status_t SurfaceFlinger::renderScreenToTextureLocked(uint32_t layerStack, 2483 GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 2484{ 2485 ATRACE_CALL(); 2486 2487 if (!GLExtensions::getInstance().haveFramebufferObject()) 2488 return INVALID_OPERATION; 2489 2490 // get screen geometry 2491 // FIXME: figure out what it means to have a screenshot texture w/ multi-display 2492 sp<const DisplayDevice> hw(getDefaultDisplayDevice()); 2493 const uint32_t hw_w = hw->getWidth(); 2494 const uint32_t hw_h = hw->getHeight(); 2495 GLfloat u = 1; 2496 GLfloat v = 1; 2497 2498 // make sure to clear all GL error flags 2499 while ( glGetError() != GL_NO_ERROR ) ; 2500 2501 // create a FBO 2502 GLuint name, tname; 2503 glGenTextures(1, &tname); 2504 glBindTexture(GL_TEXTURE_2D, tname); 2505 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2506 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 2507 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2508 hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 2509 if (glGetError() != GL_NO_ERROR) { 2510 while ( glGetError() != GL_NO_ERROR ) ; 2511 GLint tw = (2 << (31 - clz(hw_w))); 2512 GLint th = (2 << (31 - clz(hw_h))); 2513 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2514 tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 2515 u = GLfloat(hw_w) / tw; 2516 v = GLfloat(hw_h) / th; 2517 } 2518 glGenFramebuffersOES(1, &name); 2519 glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 2520 glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 2521 GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 2522 2523 DisplayDevice::setViewportAndProjection(hw); 2524 2525 // redraw the screen entirely... 2526 glDisable(GL_TEXTURE_EXTERNAL_OES); 2527 glDisable(GL_TEXTURE_2D); 2528 glClearColor(0,0,0,1); 2529 glClear(GL_COLOR_BUFFER_BIT); 2530 glMatrixMode(GL_MODELVIEW); 2531 glLoadIdentity(); 2532 const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 2533 const size_t count = layers.size(); 2534 for (size_t i=0 ; i<count ; ++i) { 2535 const sp<LayerBase>& layer(layers[i]); 2536 layer->draw(hw); 2537 } 2538 2539 hw->compositionComplete(); 2540 2541 // back to main framebuffer 2542 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 2543 glDeleteFramebuffersOES(1, &name); 2544 2545 *textureName = tname; 2546 *uOut = u; 2547 *vOut = v; 2548 return NO_ERROR; 2549} 2550 2551// --------------------------------------------------------------------------- 2552 2553status_t SurfaceFlinger::captureScreenImplLocked(const sp<IBinder>& display, 2554 sp<IMemoryHeap>* heap, 2555 uint32_t* w, uint32_t* h, PixelFormat* f, 2556 uint32_t sw, uint32_t sh, 2557 uint32_t minLayerZ, uint32_t maxLayerZ) 2558{ 2559 ATRACE_CALL(); 2560 2561 status_t result = PERMISSION_DENIED; 2562 2563 if (!GLExtensions::getInstance().haveFramebufferObject()) { 2564 return INVALID_OPERATION; 2565 } 2566 2567 // get screen geometry 2568 sp<const DisplayDevice> hw(getDisplayDevice(display)); 2569 const uint32_t hw_w = hw->getWidth(); 2570 const uint32_t hw_h = hw->getHeight(); 2571 2572 // if we have secure windows on this display, never allow the screen capture 2573 if (hw->getSecureLayerVisible()) { 2574 ALOGW("FB is protected: PERMISSION_DENIED"); 2575 return PERMISSION_DENIED; 2576 } 2577 2578 if ((sw > hw_w) || (sh > hw_h)) { 2579 ALOGE("size mismatch (%d, %d) > (%d, %d)", sw, sh, hw_w, hw_h); 2580 return BAD_VALUE; 2581 } 2582 2583 sw = (!sw) ? hw_w : sw; 2584 sh = (!sh) ? hw_h : sh; 2585 const size_t size = sw * sh * 4; 2586 const bool filtering = sw != hw_w || sh != hw_h; 2587 2588// ALOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 2589// sw, sh, minLayerZ, maxLayerZ); 2590 2591 // make sure to clear all GL error flags 2592 while ( glGetError() != GL_NO_ERROR ) ; 2593 2594 // create a FBO 2595 GLuint name, tname; 2596 glGenRenderbuffersOES(1, &tname); 2597 glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 2598 glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2599 2600 glGenFramebuffersOES(1, &name); 2601 glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 2602 glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 2603 GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 2604 2605 GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2606 2607 if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 2608 2609 // invert everything, b/c glReadPixel() below will invert the FB 2610 GLint viewport[4]; 2611 glGetIntegerv(GL_VIEWPORT, viewport); 2612 glViewport(0, 0, sw, sh); 2613 glMatrixMode(GL_PROJECTION); 2614 glPushMatrix(); 2615 glLoadIdentity(); 2616 glOrthof(0, hw_w, hw_h, 0, 0, 1); 2617 glMatrixMode(GL_MODELVIEW); 2618 2619 // redraw the screen entirely... 2620 glClearColor(0,0,0,1); 2621 glClear(GL_COLOR_BUFFER_BIT); 2622 2623 const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); 2624 const size_t count = layers.size(); 2625 for (size_t i=0 ; i<count ; ++i) { 2626 const sp<LayerBase>& layer(layers[i]); 2627 const uint32_t z = layer->drawingState().z; 2628 if (z >= minLayerZ && z <= maxLayerZ) { 2629 if (filtering) layer->setFiltering(true); 2630 layer->draw(hw); 2631 if (filtering) layer->setFiltering(false); 2632 } 2633 } 2634 2635 // check for errors and return screen capture 2636 if (glGetError() != GL_NO_ERROR) { 2637 // error while rendering 2638 result = INVALID_OPERATION; 2639 } else { 2640 // allocate shared memory large enough to hold the 2641 // screen capture 2642 sp<MemoryHeapBase> base( 2643 new MemoryHeapBase(size, 0, "screen-capture") ); 2644 void* const ptr = base->getBase(); 2645 if (ptr != MAP_FAILED) { 2646 // capture the screen with glReadPixels() 2647 ScopedTrace _t(ATRACE_TAG, "glReadPixels"); 2648 glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 2649 if (glGetError() == GL_NO_ERROR) { 2650 *heap = base; 2651 *w = sw; 2652 *h = sh; 2653 *f = PIXEL_FORMAT_RGBA_8888; 2654 result = NO_ERROR; 2655 } 2656 } else { 2657 result = NO_MEMORY; 2658 } 2659 } 2660 glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); 2661 glMatrixMode(GL_PROJECTION); 2662 glPopMatrix(); 2663 glMatrixMode(GL_MODELVIEW); 2664 } else { 2665 result = BAD_VALUE; 2666 } 2667 2668 // release FBO resources 2669 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 2670 glDeleteRenderbuffersOES(1, &tname); 2671 glDeleteFramebuffersOES(1, &name); 2672 2673 hw->compositionComplete(); 2674 2675// ALOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2676 2677 return result; 2678} 2679 2680 2681status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 2682 sp<IMemoryHeap>* heap, 2683 uint32_t* width, uint32_t* height, PixelFormat* format, 2684 uint32_t sw, uint32_t sh, 2685 uint32_t minLayerZ, uint32_t maxLayerZ) 2686{ 2687 if (CC_UNLIKELY(display == 0)) 2688 return BAD_VALUE; 2689 2690 if (!GLExtensions::getInstance().haveFramebufferObject()) 2691 return INVALID_OPERATION; 2692 2693 class MessageCaptureScreen : public MessageBase { 2694 SurfaceFlinger* flinger; 2695 sp<IBinder> display; 2696 sp<IMemoryHeap>* heap; 2697 uint32_t* w; 2698 uint32_t* h; 2699 PixelFormat* f; 2700 uint32_t sw; 2701 uint32_t sh; 2702 uint32_t minLayerZ; 2703 uint32_t maxLayerZ; 2704 status_t result; 2705 public: 2706 MessageCaptureScreen(SurfaceFlinger* flinger, const sp<IBinder>& display, 2707 sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2708 uint32_t sw, uint32_t sh, 2709 uint32_t minLayerZ, uint32_t maxLayerZ) 2710 : flinger(flinger), display(display), 2711 heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2712 minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2713 result(PERMISSION_DENIED) 2714 { 2715 } 2716 status_t getResult() const { 2717 return result; 2718 } 2719 virtual bool handler() { 2720 Mutex::Autolock _l(flinger->mStateLock); 2721 result = flinger->captureScreenImplLocked(display, 2722 heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 2723 return true; 2724 } 2725 }; 2726 2727 sp<MessageBase> msg = new MessageCaptureScreen(this, 2728 display, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 2729 status_t res = postMessageSync(msg); 2730 if (res == NO_ERROR) { 2731 res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 2732 } 2733 return res; 2734} 2735 2736// --------------------------------------------------------------------------- 2737 2738SurfaceFlinger::LayerVector::LayerVector() { 2739} 2740 2741SurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) 2742 : SortedVector<sp<LayerBase> >(rhs) { 2743} 2744 2745int SurfaceFlinger::LayerVector::do_compare(const void* lhs, 2746 const void* rhs) const 2747{ 2748 // sort layers per layer-stack, then by z-order and finally by sequence 2749 const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs)); 2750 const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs)); 2751 2752 uint32_t ls = l->currentState().layerStack; 2753 uint32_t rs = r->currentState().layerStack; 2754 if (ls != rs) 2755 return ls - rs; 2756 2757 uint32_t lz = l->currentState().z; 2758 uint32_t rz = r->currentState().z; 2759 if (lz != rz) 2760 return lz - rz; 2761 2762 return l->sequence - r->sequence; 2763} 2764 2765// --------------------------------------------------------------------------- 2766 2767SurfaceFlinger::DisplayDeviceState::DisplayDeviceState() 2768 : type(DisplayDevice::DISPLAY_ID_INVALID) { 2769} 2770 2771SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) 2772 : type(type), layerStack(0), orientation(0) { 2773 viewport.makeInvalid(); 2774 frame.makeInvalid(); 2775} 2776 2777// --------------------------------------------------------------------------- 2778 2779}; // namespace android 2780