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

Commit cb56533c authored by Vishnu Nair's avatar Vishnu Nair
Browse files

[layertracegenerator] stream layer trace to file

Write the generated layer trace entry by entry
so we don't hold the entire unserialized layer trace
in memory.

Fixes: 272158947
Test: presubmit
Test: open streamed trace in winscope
Test: cat /proc/`pidof layertracegenerator`/status
old
VmHWM:	  959496 kB
new
VmHWM:	   21416 kB

Change-Id: I4bf0cd8fe98d1e2a44fb6b7c85c4e06e586a52ed
parent 66eb2a68
Loading
Loading
Loading
Loading
+16 −5
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@
#define LOG_TAG "LayerTracing"
#define LOG_TAG "LayerTracing"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#define ATRACE_TAG ATRACE_TAG_GRAPHICS


#include <filesystem>

#include <SurfaceFlinger.h>
#include <SurfaceFlinger.h>
#include <android-base/stringprintf.h>
#include <android-base/stringprintf.h>
#include <log/log.h>
#include <log/log.h>
@@ -44,30 +46,39 @@ bool LayerTracing::enable() {
    return true;
    return true;
}
}


bool LayerTracing::disable(std::string filename) {
bool LayerTracing::disable(std::string filename, bool writeToFile) {
    std::scoped_lock lock(mTraceLock);
    std::scoped_lock lock(mTraceLock);
    if (!mEnabled) {
    if (!mEnabled) {
        return false;
        return false;
    }
    }
    mEnabled = false;
    mEnabled = false;
    if (writeToFile) {
        LayersTraceFileProto fileProto = createTraceFileProto();
        LayersTraceFileProto fileProto = createTraceFileProto();
        mBuffer->writeToFile(fileProto, filename);
        mBuffer->writeToFile(fileProto, filename);
    }
    mBuffer->reset();
    mBuffer->reset();
    return true;
    return true;
}
}


void LayerTracing::appendToStream(std::ofstream& out) {
    std::scoped_lock lock(mTraceLock);
    LayersTraceFileProto fileProto = createTraceFileProto();
    mBuffer->appendToStream(fileProto, out);
    mBuffer->reset();
}

bool LayerTracing::isEnabled() const {
bool LayerTracing::isEnabled() const {
    std::scoped_lock lock(mTraceLock);
    std::scoped_lock lock(mTraceLock);
    return mEnabled;
    return mEnabled;
}
}


status_t LayerTracing::writeToFile() {
status_t LayerTracing::writeToFile(std::string filename) {
    std::scoped_lock lock(mTraceLock);
    std::scoped_lock lock(mTraceLock);
    if (!mEnabled) {
    if (!mEnabled) {
        return STATUS_OK;
        return STATUS_OK;
    }
    }
    LayersTraceFileProto fileProto = createTraceFileProto();
    LayersTraceFileProto fileProto = createTraceFileProto();
    return mBuffer->writeToFile(fileProto, FILE_NAME);
    return mBuffer->writeToFile(fileProto, filename);
}
}


void LayerTracing::setTraceFlags(uint32_t flags) {
void LayerTracing::setTraceFlags(uint32_t flags) {
+3 −2
Original line number Original line Diff line number Diff line
@@ -43,9 +43,10 @@ public:
    LayerTracing();
    LayerTracing();
    ~LayerTracing();
    ~LayerTracing();
    bool enable();
    bool enable();
    bool disable(std::string filename = FILE_NAME);
    bool disable(std::string filename = FILE_NAME, bool writeToFile = true);
    void appendToStream(std::ofstream& out);
    bool isEnabled() const;
    bool isEnabled() const;
    status_t writeToFile();
    status_t writeToFile(std::string filename = FILE_NAME);
    static LayersTraceFileProto createTraceFileProto();
    static LayersTraceFileProto createTraceFileProto();
    void notify(bool visibleRegionDirty, int64_t time, int64_t vsyncId, LayersProto* layers,
    void notify(bool visibleRegionDirty, int64_t time, int64_t vsyncId, LayersProto* layers,
                std::string hwcDump, google::protobuf::RepeatedPtrField<DisplayProto>* displays);
                std::string hwcDump, google::protobuf::RepeatedPtrField<DisplayProto>* displays);
+14 −0
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
#include <utils/Timers.h>
#include <utils/Timers.h>
#include <utils/Trace.h>
#include <utils/Trace.h>
#include <chrono>
#include <chrono>
#include <fstream>
#include <queue>
#include <queue>


namespace android {
namespace android {
@@ -73,6 +74,19 @@ public:
        return NO_ERROR;
        return NO_ERROR;
    }
    }


    status_t appendToStream(FileProto& fileProto, std::ofstream& out) {
        ATRACE_CALL();
        writeToProto(fileProto);
        std::string output;
        if (!fileProto.SerializeToString(&output)) {
            ALOGE("Could not serialize proto.");
            return UNKNOWN_ERROR;
        }

        out << output;
        return NO_ERROR;
    }

    std::vector<std::string> emplace(std::string&& serializedProto) {
    std::vector<std::string> emplace(std::string&& serializedProto) {
        std::vector<std::string> replacedEntries;
        std::vector<std::string> replacedEntries;
        size_t protoSize = static_cast<size_t>(serializedProto.size());
        size_t protoSize = static_cast<size_t>(serializedProto.size());
+8 −2
Original line number Original line Diff line number Diff line
@@ -14,6 +14,7 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#include <ios>
#include <memory>
#include <memory>
#include <vector>
#include <vector>
#include "FrontEnd/LayerCreationArgs.h"
#include "FrontEnd/LayerCreationArgs.h"
@@ -62,8 +63,11 @@ bool LayerTraceGenerator::generate(const proto::TransactionTraceFile& traceFile,


    LayerTracing layerTracing;
    LayerTracing layerTracing;
    layerTracing.setTraceFlags(LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS);
    layerTracing.setTraceFlags(LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS);
    layerTracing.setBufferSize(512 * 1024 * 1024); // 512MB buffer size
    // 10MB buffer size (large enough to hold a single entry)
    layerTracing.setBufferSize(10 * 1024 * 1024);
    layerTracing.enable();
    layerTracing.enable();
    layerTracing.writeToFile(outputLayersTracePath);
    std::ofstream out(outputLayersTracePath, std::ios::binary | std::ios::app);


    ALOGD("Generating %d transactions...", traceFile.entry_size());
    ALOGD("Generating %d transactions...", traceFile.entry_size());
    for (int i = 0; i < traceFile.entry_size(); i++) {
    for (int i = 0; i < traceFile.entry_size(); i++) {
@@ -141,8 +145,10 @@ bool LayerTraceGenerator::generate(const proto::TransactionTraceFile& traceFile,
        auto displayProtos = LayerProtoHelper::writeDisplayInfoToProto(displayInfos);
        auto displayProtos = LayerProtoHelper::writeDisplayInfoToProto(displayInfos);
        layerTracing.notify(visibleRegionsDirty, entry.elapsed_realtime_nanos(), entry.vsync_id(),
        layerTracing.notify(visibleRegionsDirty, entry.elapsed_realtime_nanos(), entry.vsync_id(),
                            &layersProto, {}, &displayProtos);
                            &layersProto, {}, &displayProtos);
        layerTracing.appendToStream(out);
    }
    }
    layerTracing.disable(outputLayersTracePath);
    layerTracing.disable("", /*writeToFile=*/false);
    out.close();
    ALOGD("End of generating trace file. File written to %s", outputLayersTracePath);
    ALOGD("End of generating trace file. File written to %s", outputLayersTracePath);
    return true;
    return true;
}
}
+22 −0
Original line number Original line Diff line number Diff line
@@ -21,8 +21,10 @@
#include <cstdint>
#include <cstdint>
#include "Client.h"
#include "Client.h"


#include <layerproto/LayerProtoHeader.h>
#include "FrontEnd/LayerCreationArgs.h"
#include "FrontEnd/LayerCreationArgs.h"
#include "FrontEnd/Update.h"
#include "FrontEnd/Update.h"
#include "Tracing/LayerTracing.h"
#include "Tracing/RingBuffer.h"
#include "Tracing/RingBuffer.h"
#include "Tracing/TransactionTracing.h"
#include "Tracing/TransactionTracing.h"


@@ -305,4 +307,24 @@ TEST_F(TransactionTracingMirrorLayerTest, canAddMirrorLayers) {
    EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
    EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
    EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
    EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(1).z(), 43);
}
}

// Verify we can write the layers traces by entry to reduce mem pressure
// on the system when generating large traces.
TEST(LayerTraceTest, canStreamLayersTrace) {
    LayersTraceFileProto inProto = LayerTracing::createTraceFileProto();
    inProto.add_entry();
    inProto.add_entry();

    std::string output;
    inProto.SerializeToString(&output);
    LayersTraceFileProto inProto2 = LayerTracing::createTraceFileProto();
    inProto2.add_entry();
    std::string output2;
    inProto2.SerializeToString(&output2);

    LayersTraceFileProto outProto;
    outProto.ParseFromString(output + output2);
    // magic?
    EXPECT_EQ(outProto.entry().size(), 3);
}
} // namespace android
} // namespace android