123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- /* Copyright (c) 2015, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "ExSurfaceFlinger.h"
- #include "ExLayer.h"
- #include <fstream>
- #include <cutils/properties.h>
- #ifdef QTI_BSP
- #include <hardware/display_defs.h>
- #endif
- #define ATRACE_TAG ATRACE_TAG_GRAPHICS
- namespace android {
- bool ExSurfaceFlinger::sExtendedMode = false;
- ExSurfaceFlinger::ExSurfaceFlinger() {
- char property[PROPERTY_VALUE_MAX] = {0};
- mDebugLogs = false;
- if((property_get("persist.debug.qdframework.logs", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- mDebugLogs = true;
- }
- ALOGD_IF(isDebug(),"Creating custom SurfaceFlinger %s",__FUNCTION__);
- mDisableExtAnimation = false;
- if((property_get("sys.disable_ext_animation", property, "0") > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- mDisableExtAnimation = true;
- }
- ALOGD_IF(isDebug(),"Animation on external is %s in %s",
- mDisableExtAnimation ? "disabled" : "not disabled", __FUNCTION__);
- }
- ExSurfaceFlinger::~ExSurfaceFlinger() { }
- void ExSurfaceFlinger::updateExtendedMode() {
- char prop[PROPERTY_VALUE_MAX];
- property_get("sys.extended_mode", prop, "0");
- sExtendedMode = atoi(prop) ? true : false;
- }
- void ExSurfaceFlinger::getIndexLOI(size_t dpy,
- const LayerVector& currentLayers,
- bool& bIgnoreLayers,
- int& indexLOI ) {
- size_t i = currentLayers.size();
- while(i--) {
- const sp<Layer>& layer = currentLayers[i];
- /* iterate through the layer list to find ext_only layers and store
- * the index
- */
- if (layer->isSecureDisplay()) {
- bIgnoreLayers = true;
- indexLOI = -1;
- if(!dpy)
- indexLOI = i;
- break;
- }
- /* iterate through the layer list to find ext_only layers or yuv
- * layer(extended_mode) and store the index
- */
- if ((dpy && (layer->isExtOnly() ||
- (isExtendedMode() && layer->isYuvLayer())))) {
- bIgnoreLayers= true;
- indexLOI = i;
- }
- }
- return;
- }
- bool ExSurfaceFlinger::updateLayerVisibleNonTransparentRegion(
- const int& dpy, const sp<Layer>& layer,
- bool& bIgnoreLayers, int& indexLOI,
- uint32_t layerStack, const int& i) {
- const Layer::State& s(layer->getDrawingState());
- /* Only add the layer marked as "external_only" or yuvLayer
- * (extended_mode) to external list and
- * only remove the layer marked as "external_only" or yuvLayer in
- * extended_mode from primary list
- * and do not add the layer marked as "internal_only" to external list
- * Add secure UI layers to primary and remove other layers from internal
- * and external list
- */
- if(((bIgnoreLayers && indexLOI != (int)i) ||
- (!dpy && layer->isExtOnly()) ||
- (!dpy && isExtendedMode() && layer->isYuvLayer()))||
- (dpy && layer->isIntOnly())) {
- /* Ignore all other layers except the layers marked as ext_only
- * by setting visible non transparent region empty
- */
- Region visibleNonTransRegion;
- visibleNonTransRegion.set(Rect(0,0));
- layer->setVisibleNonTransparentRegion(visibleNonTransRegion);
- return true;
- }
- /* only consider the layers on the given later stack
- * Override layers created using presentation class by the layers having
- * ext_only flag enabled
- */
- if(s.layerStack != layerStack && !bIgnoreLayers) {
- /* set the visible region as empty since we have removed the
- * layerstack check in rebuildLayerStack() function
- */
- Region visibleNonTransRegion;
- visibleNonTransRegion.set(Rect(0,0));
- layer->setVisibleNonTransparentRegion(visibleNonTransRegion);
- return true;
- }
- if (mDisableExtAnimation) {
- /* Remove screenShotSurface from secondary displays when ext animation disabled */
- const int screenShotLen = strlen("ScreenshotSurface");
- if (dpy && !strncmp(layer->getName(), "ScreenshotSurface", screenShotLen) ) {
- Region visibleNonTransRegion;
- visibleNonTransRegion.set(Rect(0, 0));
- layer->setVisibleNonTransparentRegion(visibleNonTransRegion);
- return true;
- }
- }
- return false;
- }
- void ExSurfaceFlinger::delayDPTransactionIfNeeded(
- const Vector<DisplayState>& displays) {
- /* Delay the display projection transaction by 50ms only when the disable
- * external rotation animation feature is enabled
- */
- if(mDisableExtAnimation) {
- size_t count = displays.size();
- for (size_t i=0 ; i<count ; i++) {
- const DisplayState& s(displays[i]);
- if((mDisplays.indexOfKey(s.token) >= 0) && (s.token !=
- mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY])) {
- const uint32_t what = s.what;
- /* Invalidate and Delay the binder thread by 50 ms on
- * eDisplayProjectionChanged to trigger a draw cycle so that
- * it can fix one incorrect frame on the External, when we
- * disable external animation
- */
- if (what & DisplayState::eDisplayProjectionChanged) {
- invalidateHwcGeometry();
- repaintEverything();
- usleep(50000);
- }
- }
- }
- }
- }
- bool ExSurfaceFlinger::canDrawLayerinScreenShot(
- const sp<const DisplayDevice>& hw,
- const sp<Layer>& layer) {
- int dispType = hw->getDisplayType();
- /* a) Don't draw SecureDisplayLayer or ProtectedLayer.
- * b) Don't let ext_only and extended_mode to be captured
- * If not, we would see incorrect image during rotation
- * on primary.
- */
- if(!layer->isSecureDisplay()
- && !layer->isProtected()
- && !(!dispType && (layer->isExtOnly() ||
- (isExtendedMode() && layer->isYuvLayer())))
- && !(layer->isIntOnly() && dispType)
- && layer->isVisible()){
- return true;
- }
- return false;
- }
- void ExSurfaceFlinger::isfreezeSurfacePresent(bool& freezeSurfacePresent,
- const sp<const DisplayDevice>& hw,
- const int32_t& id) {
- freezeSurfacePresent = false;
- /* Get the layers in the current drawing state */
- const LayerVector& layers(mDrawingState.layersSortedByZ);
- const size_t layerCount = layers.size();
- /* Look for ScreenShotSurface in external layer list, only when
- * disable external rotation animation feature is enabled
- */
- if(mDisableExtAnimation && (id != HWC_DISPLAY_PRIMARY)) {
- for (size_t i = 0 ; i < layerCount ; ++i) {
- static int screenShotLen = strlen("ScreenshotSurface");
- const sp<Layer>& layer(layers[i]);
- const Layer::State& s(layer->getDrawingState());
- /* check the layers associated with external display */
- if(s.layerStack == hw->getLayerStack()) {
- if(!strncmp(layer->getName(), "ScreenshotSurface",
- screenShotLen)) {
- /* Screenshot layer is present, and animation in
- * progress
- */
- freezeSurfacePresent = true;
- break;
- }
- }
- }
- }
- }
- void ExSurfaceFlinger::setOrientationEventControl(bool& freezeSurfacePresent,
- const int32_t& id) {
- HWComposer& hwc(getHwComposer());
- HWComposer::LayerListIterator cur = hwc.begin(id);
- if(freezeSurfacePresent) {
- /* If freezeSurfacePresent, set ANIMATING flag
- * which is used to support disable animation on external
- */
- cur->setAnimating(true);
- }
- }
- void ExSurfaceFlinger::updateVisibleRegionsDirty() {
- /* If extended_mode is set, and set mVisibleRegionsDirty
- * as we need to rebuildLayerStack
- */
- if(isExtendedMode()) {
- mVisibleRegionsDirty = true;
- }
- }
- void ExSurfaceFlinger::drawWormHoleIfRequired(HWComposer::LayerListIterator& cur,
- const HWComposer::LayerListIterator& end,
- const sp<const DisplayDevice>& hw,
- const Region& region) {
- if (cur != end) {
- #ifdef QTI_BSP
- if (cur->getCompositionType() != HWC_BLIT)
- drawWormhole(hw, region);
- #endif
- } else {
- drawWormhole(hw, region);
- }
- }
- #ifdef DEBUG_CONT_DUMPSYS
- status_t ExSurfaceFlinger::dump(int fd, const Vector<String16>& args) {
- // Format: adb shell dumpsys SurfaceFlinger --file --no-limit
- size_t numArgs = args.size();
- status_t err = NO_ERROR;
- if (!numArgs || (args[0] != String16("--file"))) {
- return SurfaceFlinger::dump(fd, args);
- }
- Mutex::Autolock _l(mFileDump.lock);
- // Same command is used to start and end dump.
- mFileDump.running = !mFileDump.running;
- if (mFileDump.running) {
- // Create an empty file or erase existing file.
- std::fstream fs;
- fs.open(mFileDump.name, std::ios::out);
- if (!fs) {
- mFileDump.running = false;
- err = UNKNOWN_ERROR;
- } else {
- mFileDump.position = 0;
- if (numArgs >= 2 && (args[1] == String16("--nolimit"))) {
- mFileDump.noLimit = true;
- } else {
- mFileDump.noLimit = false;
- }
- }
- }
- String8 result;
- result += mFileDump.running ? "Start" : "End";
- result += mFileDump.noLimit ? " unlimited" : " fixed limit";
- result += " dumpsys to file : ";
- result += mFileDump.name;
- result += "\n";
- write(fd, result.string(), result.size());
- return NO_ERROR;
- }
- void ExSurfaceFlinger::dumpDrawCycle(bool prePrepare) {
- Mutex::Autolock _l(mFileDump.lock);
- // User might stop dump collection in middle of prepare & commit.
- // Collect dumpsys again after commit and replace.
- if (!mFileDump.running && !mFileDump.replaceAfterCommit) {
- return;
- }
- Vector<String16> args;
- size_t index = 0;
- String8 dumpsys;
- dumpAllLocked(args, index, dumpsys);
- char timeStamp[32];
- char dataSize[32];
- char hms[32];
- long millis;
- struct timeval tv;
- struct tm *ptm;
- gettimeofday(&tv, NULL);
- ptm = localtime(&tv.tv_sec);
- if (ptm == NULL) {
- return;
- }
- strftime (hms, sizeof (hms), "%H:%M:%S", ptm);
- millis = tv.tv_usec / 1000;
- snprintf(timeStamp, sizeof(timeStamp), "Timestamp: %s.%03ld", hms, millis);
- snprintf(dataSize, sizeof(dataSize), "Size: %8zu", dumpsys.size());
- std::fstream fs;
- fs.open(mFileDump.name, std::ios::in | std::ios::out);
- if (!fs) {
- ALOGE("Failed to open %s file for dumpsys", mFileDump.name);
- return;
- }
- // Format:
- // | start code | after commit? | time stamp | dump size | dump data |
- fs.seekp(mFileDump.position, std::ios::beg);
- fs << "#@#@-- DUMPSYS START --@#@#" << std::endl;
- fs << "PostCommit: " << ( prePrepare ? "false" : "true" ) << std::endl;
- fs << timeStamp << std::endl;
- fs << dataSize << std::endl;
- fs << dumpsys << std::endl;
- if (prePrepare) {
- mFileDump.replaceAfterCommit = true;
- } else {
- mFileDump.replaceAfterCommit = false;
- // Reposition only after commit.
- // Keem file size to appx 20 MB limit by default, wrap around if exceeds.
- mFileDump.position = fs.tellp();
- if (!mFileDump.noLimit && (mFileDump.position > (20 * 1024 * 1024))) {
- mFileDump.position = 0;
- }
- }
- fs.close();
- }
- #endif
- }; // namespace android
|