Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e1a1282 authored by Adrian Roos's avatar Adrian Roos
Browse files

Add SurfaceFlinger tracing

Bug: 64831661
Test: adb shell service call SurfaceFlinger 1025 i32 1 && adb shell service call SurfaceFlinger 1025 i32 0
Change-Id: Idf272715b52aee5d2d366fbd4a96b0afaaf2d0c7
parent 026bb7e0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ LOCAL_SRC_FILES := \
    MonitoredProducer.cpp \
    SurfaceFlingerConsumer.cpp \
    SurfaceInterceptor.cpp \
    SurfaceTracing.cpp \
    Transform.cpp \
    DisplayHardware/ComposerHal.cpp \
    DisplayHardware/FramebufferSurface.cpp \
+23 −0
Original line number Diff line number Diff line
@@ -1520,6 +1520,7 @@ void SurfaceFlinger::handleMessageRefresh() {
    rebuildLayerStacks();
    setUpHWComposer();
    doDebugFlashRegions();
    doTracing("handleRefresh");
    doComposition();
    postComposition(refreshStartTime);

@@ -1579,6 +1580,14 @@ void SurfaceFlinger::doDebugFlashRegions()
    }
}

void SurfaceFlinger::doTracing(const char* where) {
    ATRACE_CALL();
    ATRACE_NAME(where);
    if (CC_UNLIKELY(mTracing.isEnabled())) {
        mTracing.traceLayers(where, dumpProtoInfo());
    }
}

void SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
{
    ATRACE_CALL();
@@ -4230,6 +4239,20 @@ status_t SurfaceFlinger::onTransact(
                reply->writeBool(hasWideColorDisplay);
                return NO_ERROR;
            }
            case 1025: { // tracing
                n = data.readInt32();
                if (n) {
                    ALOGV("LayerTracing enabled");
                    mTracing.enable();
                    doTracing("tracing.enable");
                    reply->writeInt32(NO_ERROR);
                } else {
                    ALOGV("LayerTracing disabled");
                    status_t err = mTracing.disable();
                    reply->writeInt32(err);
                }
                return NO_ERROR;
            }
        }
    }
    return err;
+3 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@
#include "LayerVector.h"
#include "MessageQueue.h"
#include "SurfaceInterceptor.h"
#include "SurfaceTracing.h"
#include "StartPropertySetThread.h"

#ifdef USE_HWC2
@@ -575,6 +576,7 @@ private:
    void setUpHWComposer();
    void doComposition();
    void doDebugFlashRegions();
    void doTracing(const char* where);
    void doDisplayComposition(const sp<const DisplayDevice>& displayDevice, const Region& dirtyRegion);

    // compose surfaces for display hw. this fails if using GL and the surface
@@ -746,6 +748,7 @@ private:
    bool mPropagateBackpressure = true;
#endif
    SurfaceInterceptor mInterceptor;
    SurfaceTracing mTracing;
    bool mUseHwcVirtualDisplays = false;

    // Restrict layers to use two buffers in their bufferqueues.
+85 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#undef LOG_TAG
#define LOG_TAG "SurfaceTracing"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include "SurfaceTracing.h"

#include <android-base/file.h>
#include <log/log.h>
#include <utils/SystemClock.h>
#include <utils/Trace.h>

namespace android {

void SurfaceTracing::enable() {
    if (mEnabled) {
        return;
    }
    ATRACE_CALL();
    mEnabled = true;
    std::lock_guard<std::mutex> protoGuard(mTraceMutex);

    mTrace.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
                            LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
}

status_t SurfaceTracing::disable() {
    if (!mEnabled) {
        return NO_ERROR;
    }
    ATRACE_CALL();
    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
    mEnabled = false;
    status_t err(writeProtoFileLocked());
    ALOGE_IF(err == PERMISSION_DENIED, "Could not save the proto file! Permission denied");
    ALOGE_IF(err == NOT_ENOUGH_DATA, "Could not save the proto file! There are missing fields");
    mTrace.Clear();
    return err;
}

bool SurfaceTracing::isEnabled() {
    return mEnabled;
}

void SurfaceTracing::traceLayers(const char* where, LayersProto layers) {
    std::lock_guard<std::mutex> protoGuard(mTraceMutex);

    LayersTraceProto* entry = mTrace.add_entry();
    entry->set_elapsed_realtime_nanos(elapsedRealtimeNano());
    entry->set_where(where);
    entry->mutable_layers()->Swap(&layers);
}

status_t SurfaceTracing::writeProtoFileLocked() {
    ATRACE_CALL();

    if (!mTrace.IsInitialized()) {
        return NOT_ENOUGH_DATA;
    }
    std::string output;
    if (!mTrace.SerializeToString(&output)) {
        return PERMISSION_DENIED;
    }
    if (!android::base::WriteStringToFile(output, mOutputFileName, true)) {
        return PERMISSION_DENIED;
    }

    return NO_ERROR;
}

} // namespace android
+50 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <layerproto/LayerProtoHeader.h>
#include <utils/Errors.h>

#include <mutex>

using namespace android::surfaceflinger;

namespace android {

/*
 * SurfaceTracing records layer states during surface flinging.
 */
class SurfaceTracing {
public:
    void enable();
    status_t disable();
    bool isEnabled();

    void traceLayers(const char* where, LayersProto);

private:
    static constexpr auto DEFAULT_FILENAME = "/data/misc/trace/layerstrace.pb";

    status_t writeProtoFileLocked();

    bool mEnabled = false;
    std::string mOutputFileName = DEFAULT_FILENAME;
    std::mutex mTraceMutex;
    LayersTraceFileProto mTrace;
};

} // namespace android
Loading