ExSurfaceFlinger.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /* Copyright (c) 2015, The Linux Foundation. All rights reserved.
  2. *
  3. * Redistribution and use in source and binary forms, with or without
  4. * modification, are permitted provided that the following conditions are
  5. * met:
  6. * * Redistributions of source code must retain the above copyright
  7. * notice, this list of conditions and the following disclaimer.
  8. * * Redistributions in binary form must reproduce the above
  9. * copyright notice, this list of conditions and the following
  10. * disclaimer in the documentation and/or other materials provided
  11. * with the distribution.
  12. * * Neither the name of The Linux Foundation nor the names of its
  13. * contributors may be used to endorse or promote products derived
  14. * from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  17. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  20. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  23. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  24. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  25. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  26. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #include "ExSurfaceFlinger.h"
  29. #include "ExLayer.h"
  30. #include <fstream>
  31. #include <cutils/properties.h>
  32. #ifdef QTI_BSP
  33. #include <hardware/display_defs.h>
  34. #endif
  35. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  36. namespace android {
  37. bool ExSurfaceFlinger::sExtendedMode = false;
  38. ExSurfaceFlinger::ExSurfaceFlinger() {
  39. char property[PROPERTY_VALUE_MAX] = {0};
  40. mDebugLogs = false;
  41. if((property_get("persist.debug.qdframework.logs", property, NULL) > 0) &&
  42. (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
  43. (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
  44. mDebugLogs = true;
  45. }
  46. ALOGD_IF(isDebug(),"Creating custom SurfaceFlinger %s",__FUNCTION__);
  47. mDisableExtAnimation = false;
  48. if((property_get("sys.disable_ext_animation", property, "0") > 0) &&
  49. (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
  50. (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
  51. mDisableExtAnimation = true;
  52. }
  53. ALOGD_IF(isDebug(),"Animation on external is %s in %s",
  54. mDisableExtAnimation ? "disabled" : "not disabled", __FUNCTION__);
  55. }
  56. ExSurfaceFlinger::~ExSurfaceFlinger() { }
  57. void ExSurfaceFlinger::updateExtendedMode() {
  58. char prop[PROPERTY_VALUE_MAX];
  59. property_get("sys.extended_mode", prop, "0");
  60. sExtendedMode = atoi(prop) ? true : false;
  61. }
  62. void ExSurfaceFlinger::getIndexLOI(size_t dpy,
  63. const LayerVector& currentLayers,
  64. bool& bIgnoreLayers,
  65. int& indexLOI ) {
  66. size_t i = currentLayers.size();
  67. while(i--) {
  68. const sp<Layer>& layer = currentLayers[i];
  69. /* iterate through the layer list to find ext_only layers and store
  70. * the index
  71. */
  72. if (layer->isSecureDisplay()) {
  73. bIgnoreLayers = true;
  74. indexLOI = -1;
  75. if(!dpy)
  76. indexLOI = i;
  77. break;
  78. }
  79. /* iterate through the layer list to find ext_only layers or yuv
  80. * layer(extended_mode) and store the index
  81. */
  82. if ((dpy && (layer->isExtOnly() ||
  83. (isExtendedMode() && layer->isYuvLayer())))) {
  84. bIgnoreLayers= true;
  85. indexLOI = i;
  86. }
  87. }
  88. return;
  89. }
  90. bool ExSurfaceFlinger::updateLayerVisibleNonTransparentRegion(
  91. const int& dpy, const sp<Layer>& layer,
  92. bool& bIgnoreLayers, int& indexLOI,
  93. uint32_t layerStack, const int& i) {
  94. const Layer::State& s(layer->getDrawingState());
  95. /* Only add the layer marked as "external_only" or yuvLayer
  96. * (extended_mode) to external list and
  97. * only remove the layer marked as "external_only" or yuvLayer in
  98. * extended_mode from primary list
  99. * and do not add the layer marked as "internal_only" to external list
  100. * Add secure UI layers to primary and remove other layers from internal
  101. * and external list
  102. */
  103. if(((bIgnoreLayers && indexLOI != (int)i) ||
  104. (!dpy && layer->isExtOnly()) ||
  105. (!dpy && isExtendedMode() && layer->isYuvLayer()))||
  106. (dpy && layer->isIntOnly())) {
  107. /* Ignore all other layers except the layers marked as ext_only
  108. * by setting visible non transparent region empty
  109. */
  110. Region visibleNonTransRegion;
  111. visibleNonTransRegion.set(Rect(0,0));
  112. layer->setVisibleNonTransparentRegion(visibleNonTransRegion);
  113. return true;
  114. }
  115. /* only consider the layers on the given later stack
  116. * Override layers created using presentation class by the layers having
  117. * ext_only flag enabled
  118. */
  119. if(s.layerStack != layerStack && !bIgnoreLayers) {
  120. /* set the visible region as empty since we have removed the
  121. * layerstack check in rebuildLayerStack() function
  122. */
  123. Region visibleNonTransRegion;
  124. visibleNonTransRegion.set(Rect(0,0));
  125. layer->setVisibleNonTransparentRegion(visibleNonTransRegion);
  126. return true;
  127. }
  128. if (mDisableExtAnimation) {
  129. /* Remove screenShotSurface from secondary displays when ext animation disabled */
  130. const int screenShotLen = strlen("ScreenshotSurface");
  131. if (dpy && !strncmp(layer->getName(), "ScreenshotSurface", screenShotLen) ) {
  132. Region visibleNonTransRegion;
  133. visibleNonTransRegion.set(Rect(0, 0));
  134. layer->setVisibleNonTransparentRegion(visibleNonTransRegion);
  135. return true;
  136. }
  137. }
  138. return false;
  139. }
  140. void ExSurfaceFlinger::delayDPTransactionIfNeeded(
  141. const Vector<DisplayState>& displays) {
  142. /* Delay the display projection transaction by 50ms only when the disable
  143. * external rotation animation feature is enabled
  144. */
  145. if(mDisableExtAnimation) {
  146. size_t count = displays.size();
  147. for (size_t i=0 ; i<count ; i++) {
  148. const DisplayState& s(displays[i]);
  149. if((mDisplays.indexOfKey(s.token) >= 0) && (s.token !=
  150. mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY])) {
  151. const uint32_t what = s.what;
  152. /* Invalidate and Delay the binder thread by 50 ms on
  153. * eDisplayProjectionChanged to trigger a draw cycle so that
  154. * it can fix one incorrect frame on the External, when we
  155. * disable external animation
  156. */
  157. if (what & DisplayState::eDisplayProjectionChanged) {
  158. invalidateHwcGeometry();
  159. repaintEverything();
  160. usleep(50000);
  161. }
  162. }
  163. }
  164. }
  165. }
  166. bool ExSurfaceFlinger::canDrawLayerinScreenShot(
  167. const sp<const DisplayDevice>& hw,
  168. const sp<Layer>& layer) {
  169. int dispType = hw->getDisplayType();
  170. /* a) Don't draw SecureDisplayLayer or ProtectedLayer.
  171. * b) Don't let ext_only and extended_mode to be captured
  172. * If not, we would see incorrect image during rotation
  173. * on primary.
  174. */
  175. if(!layer->isSecureDisplay()
  176. && !layer->isProtected()
  177. && !(!dispType && (layer->isExtOnly() ||
  178. (isExtendedMode() && layer->isYuvLayer())))
  179. && !(layer->isIntOnly() && dispType)
  180. && layer->isVisible()){
  181. return true;
  182. }
  183. return false;
  184. }
  185. void ExSurfaceFlinger::isfreezeSurfacePresent(bool& freezeSurfacePresent,
  186. const sp<const DisplayDevice>& hw,
  187. const int32_t& id) {
  188. freezeSurfacePresent = false;
  189. /* Get the layers in the current drawing state */
  190. const LayerVector& layers(mDrawingState.layersSortedByZ);
  191. const size_t layerCount = layers.size();
  192. /* Look for ScreenShotSurface in external layer list, only when
  193. * disable external rotation animation feature is enabled
  194. */
  195. if(mDisableExtAnimation && (id != HWC_DISPLAY_PRIMARY)) {
  196. for (size_t i = 0 ; i < layerCount ; ++i) {
  197. static int screenShotLen = strlen("ScreenshotSurface");
  198. const sp<Layer>& layer(layers[i]);
  199. const Layer::State& s(layer->getDrawingState());
  200. /* check the layers associated with external display */
  201. if(s.layerStack == hw->getLayerStack()) {
  202. if(!strncmp(layer->getName(), "ScreenshotSurface",
  203. screenShotLen)) {
  204. /* Screenshot layer is present, and animation in
  205. * progress
  206. */
  207. freezeSurfacePresent = true;
  208. break;
  209. }
  210. }
  211. }
  212. }
  213. }
  214. void ExSurfaceFlinger::setOrientationEventControl(bool& freezeSurfacePresent,
  215. const int32_t& id) {
  216. HWComposer& hwc(getHwComposer());
  217. HWComposer::LayerListIterator cur = hwc.begin(id);
  218. if(freezeSurfacePresent) {
  219. /* If freezeSurfacePresent, set ANIMATING flag
  220. * which is used to support disable animation on external
  221. */
  222. cur->setAnimating(true);
  223. }
  224. }
  225. void ExSurfaceFlinger::updateVisibleRegionsDirty() {
  226. /* If extended_mode is set, and set mVisibleRegionsDirty
  227. * as we need to rebuildLayerStack
  228. */
  229. if(isExtendedMode()) {
  230. mVisibleRegionsDirty = true;
  231. }
  232. }
  233. void ExSurfaceFlinger::drawWormHoleIfRequired(HWComposer::LayerListIterator& cur,
  234. const HWComposer::LayerListIterator& end,
  235. const sp<const DisplayDevice>& hw,
  236. const Region& region) {
  237. if (cur != end) {
  238. #ifdef QTI_BSP
  239. if (cur->getCompositionType() != HWC_BLIT)
  240. drawWormhole(hw, region);
  241. #endif
  242. } else {
  243. drawWormhole(hw, region);
  244. }
  245. }
  246. #ifdef DEBUG_CONT_DUMPSYS
  247. status_t ExSurfaceFlinger::dump(int fd, const Vector<String16>& args) {
  248. // Format: adb shell dumpsys SurfaceFlinger --file --no-limit
  249. size_t numArgs = args.size();
  250. status_t err = NO_ERROR;
  251. if (!numArgs || (args[0] != String16("--file"))) {
  252. return SurfaceFlinger::dump(fd, args);
  253. }
  254. Mutex::Autolock _l(mFileDump.lock);
  255. // Same command is used to start and end dump.
  256. mFileDump.running = !mFileDump.running;
  257. if (mFileDump.running) {
  258. // Create an empty file or erase existing file.
  259. std::fstream fs;
  260. fs.open(mFileDump.name, std::ios::out);
  261. if (!fs) {
  262. mFileDump.running = false;
  263. err = UNKNOWN_ERROR;
  264. } else {
  265. mFileDump.position = 0;
  266. if (numArgs >= 2 && (args[1] == String16("--nolimit"))) {
  267. mFileDump.noLimit = true;
  268. } else {
  269. mFileDump.noLimit = false;
  270. }
  271. }
  272. }
  273. String8 result;
  274. result += mFileDump.running ? "Start" : "End";
  275. result += mFileDump.noLimit ? " unlimited" : " fixed limit";
  276. result += " dumpsys to file : ";
  277. result += mFileDump.name;
  278. result += "\n";
  279. write(fd, result.string(), result.size());
  280. return NO_ERROR;
  281. }
  282. void ExSurfaceFlinger::dumpDrawCycle(bool prePrepare) {
  283. Mutex::Autolock _l(mFileDump.lock);
  284. // User might stop dump collection in middle of prepare & commit.
  285. // Collect dumpsys again after commit and replace.
  286. if (!mFileDump.running && !mFileDump.replaceAfterCommit) {
  287. return;
  288. }
  289. Vector<String16> args;
  290. size_t index = 0;
  291. String8 dumpsys;
  292. dumpAllLocked(args, index, dumpsys);
  293. char timeStamp[32];
  294. char dataSize[32];
  295. char hms[32];
  296. long millis;
  297. struct timeval tv;
  298. struct tm *ptm;
  299. gettimeofday(&tv, NULL);
  300. ptm = localtime(&tv.tv_sec);
  301. if (ptm == NULL) {
  302. return;
  303. }
  304. strftime (hms, sizeof (hms), "%H:%M:%S", ptm);
  305. millis = tv.tv_usec / 1000;
  306. snprintf(timeStamp, sizeof(timeStamp), "Timestamp: %s.%03ld", hms, millis);
  307. snprintf(dataSize, sizeof(dataSize), "Size: %8zu", dumpsys.size());
  308. std::fstream fs;
  309. fs.open(mFileDump.name, std::ios::in | std::ios::out);
  310. if (!fs) {
  311. ALOGE("Failed to open %s file for dumpsys", mFileDump.name);
  312. return;
  313. }
  314. // Format:
  315. // | start code | after commit? | time stamp | dump size | dump data |
  316. fs.seekp(mFileDump.position, std::ios::beg);
  317. fs << "#@#@-- DUMPSYS START --@#@#" << std::endl;
  318. fs << "PostCommit: " << ( prePrepare ? "false" : "true" ) << std::endl;
  319. fs << timeStamp << std::endl;
  320. fs << dataSize << std::endl;
  321. fs << dumpsys << std::endl;
  322. if (prePrepare) {
  323. mFileDump.replaceAfterCommit = true;
  324. } else {
  325. mFileDump.replaceAfterCommit = false;
  326. // Reposition only after commit.
  327. // Keem file size to appx 20 MB limit by default, wrap around if exceeds.
  328. mFileDump.position = fs.tellp();
  329. if (!mFileDump.noLimit && (mFileDump.position > (20 * 1024 * 1024))) {
  330. mFileDump.position = 0;
  331. }
  332. }
  333. fs.close();
  334. }
  335. #endif
  336. }; // namespace android