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

Commit fe1fdc94 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8211163 from fe5dd039 to tm-d1-release

Change-Id: I4d8f3fb612c37cadf4a574a3668a2c1ef8ab47ad
parents d43b3f52 fe5dd039
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include "AidlComposerHal.h"

#include <android-base/file.h>
#include <android/binder_ibinder_platform.h>
#include <android/binder_manager.h>
#include <log/log.h>
@@ -115,7 +116,7 @@ template <>
AidlPerFrameMetadataBlob translate(IComposerClient::PerFrameMetadataBlob x) {
    AidlPerFrameMetadataBlob blob;
    blob.key = translate<AidlPerFrameMetadataKey>(x.key),
    std::copy(blob.blob.begin(), blob.blob.end(), x.blob.begin());
    std::copy(x.blob.begin(), x.blob.end(), std::inserter(blob.blob, blob.blob.end()));
    return blob;
}

@@ -262,13 +263,27 @@ std::vector<Capability> AidlComposer::getCapabilities() {
}

std::string AidlComposer::dumpDebugInfo() {
    std::string info;
    const auto status = mAidlComposer->dumpDebugInfo(&info);
    if (!status.isOk()) {
        ALOGE("dumpDebugInfo failed %s", status.getDescription().c_str());
    int pipefds[2];
    int result = pipe(pipefds);
    if (result < 0) {
        ALOGE("dumpDebugInfo: pipe failed: %s", strerror(errno));
        return {};
    }
    return info;

    std::string str;
    const auto status = mAidlComposer->dump(pipefds[1], /*args*/ nullptr, /*numArgs*/ 0);
    // Close the write-end of the pipe to make sure that when reading from the
    // read-end we will get eof instead of blocking forever
    close(pipefds[1]);

    if (status == STATUS_OK) {
        base::ReadFdToString(pipefds[0], &str);
    } else {
        ALOGE("dumpDebugInfo: dump failed: %d", status);
    }

    close(pipefds[0]);
    return str;
}

void AidlComposer::registerCallback(HWC2::ComposerCallback& callback) {
+0 −1
Original line number Diff line number Diff line
@@ -101,7 +101,6 @@ bool FlagManager::use_adpf_cpu_hint() const {
}

bool FlagManager::use_skia_tracing() const {
    ALOGD("use_skia_tracing ?");
    std::optional<bool> sysPropVal =
            doParse<bool>(base::GetProperty(PROPERTY_SKIA_ATRACE_ENABLED, "").c_str());
    return getValue("SkiaTracingFeature__use_skia_tracing", sysPropVal, false);
+1 −1
Original line number Diff line number Diff line
@@ -5341,7 +5341,7 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co
    colorizer.reset(result);
    const bool hwcDisabled = mDebugDisableHWC || mDebugFlashDelay;
    StringAppendF(&result, "  h/w composer %s\n", hwcDisabled ? "disabled" : "enabled");
    getHwComposer().dump(result);
    dumpHwc(result);

    /*
     * Dump gralloc state
+46 −0
Original line number Diff line number Diff line
// Copyright (C) 2022 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.

cc_binary {
    name: "layertracegenerator",
    defaults: [
        "libsurfaceflinger_mocks_defaults",
        "surfaceflinger_defaults",
        "skia_renderengine_deps",
    ],
    srcs: [
        ":libsurfaceflinger_sources",
        ":libsurfaceflinger_mock_sources",
        ":layertracegenerator_sources",
        "main.cpp",
    ],
    static_libs: [
        "libgtest",
    ],
    header_libs: [
        "libsurfaceflinger_mocks_headers",
    ],
}

filegroup {
    name: "layertracegenerator_sources",
    srcs: [
        "LayerTraceGenerator.cpp",
    ],
}

cc_library_headers {
    name: "layertracegenerator_headers",
    export_include_dirs: ["."],
}
+284 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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 "LayerTraceGenerator"

#include <TestableSurfaceFlinger.h>
#include <Tracing/TransactionProtoParser.h>
#include <binder/IPCThreadState.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <gui/LayerState.h>
#include <log/log.h>
#include <mock/MockEventThread.h>
#include <renderengine/ExternalTexture.h>
#include <renderengine/mock/FakeExternalTexture.h>
#include <renderengine/mock/RenderEngine.h>
#include <utils/String16.h>
#include <string>

#include "LayerTraceGenerator.h"

namespace android {

class Factory final : public surfaceflinger::Factory {
public:
    ~Factory() = default;

    std::unique_ptr<HWComposer> createHWComposer(const std::string&) override { return nullptr; }

    std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration(
            Fps /*currentRefreshRate*/) override {
        return std::make_unique<scheduler::FakePhaseOffsets>();
    }

    sp<SurfaceInterceptor> createSurfaceInterceptor() override {
        return new android::impl::SurfaceInterceptor();
    }

    sp<StartPropertySetThread> createStartPropertySetThread(
            bool /* timestampPropertyValue */) override {
        return nullptr;
    }

    sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs& /* creationArgs */) override {
        return nullptr;
    }

    sp<GraphicBuffer> createGraphicBuffer(uint32_t /* width */, uint32_t /* height */,
                                          PixelFormat /* format */, uint32_t /* layerCount */,
                                          uint64_t /* usage */,
                                          std::string /* requestorName */) override {
        return nullptr;
    }

    void createBufferQueue(sp<IGraphicBufferProducer>* /* outProducer */,
                           sp<IGraphicBufferConsumer>* /* outConsumer */,
                           bool /* consumerIsSurfaceFlinger */) override {}

    sp<IGraphicBufferProducer> createMonitoredProducer(
            const sp<IGraphicBufferProducer>& /* producer */,
            const sp<SurfaceFlinger>& /* flinger */, const wp<Layer>& /* layer */) override {
        return nullptr;
    }

    sp<BufferLayerConsumer> createBufferLayerConsumer(
            const sp<IGraphicBufferConsumer>& /* consumer */,
            renderengine::RenderEngine& /* renderEngine */, uint32_t /* textureName */,
            Layer* /* layer */) override {
        return nullptr;
    }

    std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
            const sp<IGraphicBufferProducer>& /* producer */) override {
        return nullptr;
    }

    std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override {
        return compositionengine::impl::createCompositionEngine();
    }

    sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) {
        return sp<ContainerLayer>::make(args);
    }

    sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) {
        return new BufferStateLayer(args);
    }

    sp<EffectLayer> createEffectLayer(const LayerCreationArgs& args) {
        return new EffectLayer(args);
    }

    sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs&) override {
        return nullptr;
    }

    std::unique_ptr<FrameTracer> createFrameTracer() override {
        return std::make_unique<testing::NiceMock<mock::FrameTracer>>();
    }

    std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline(
            std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid = 0) override {
        return std::make_unique<testing::NiceMock<mock::FrameTimeline>>(timeStats,
                                                                        surfaceFlingerPid);
    }
};

class MockSurfaceFlinger : public SurfaceFlinger {
public:
    MockSurfaceFlinger(Factory& factory)
          : SurfaceFlinger(factory, SurfaceFlinger::SkipInitialization) {}
    std::shared_ptr<renderengine::ExternalTexture> getExternalTextureFromBufferData(
            const BufferData& bufferData, const char* /* layerName */) const override {
        return std::make_shared<renderengine::mock::FakeExternalTexture>(bufferData.getWidth(),
                                                                         bufferData.getHeight(),
                                                                         bufferData.getId(),
                                                                         bufferData
                                                                                 .getPixelFormat(),
                                                                         bufferData.getUsage());
    };

    // b/220017192 migrate from transact codes to ISurfaceComposer apis
    void setLayerTracingFlags(int32_t flags) {
        Parcel data;
        Parcel reply;
        data.writeInterfaceToken(String16("android.ui.ISurfaceComposer"));
        data.writeInt32(flags);
        transact(1033, data, &reply, 0 /* flags */);
    }

    void startLayerTracing(int64_t traceStartTime) {
        Parcel data;
        Parcel reply;
        data.writeInterfaceToken(String16("android.ui.ISurfaceComposer"));
        data.writeInt32(1);
        data.writeInt64(traceStartTime);
        transact(1025, data, &reply, 0 /* flags */);
    }

    void stopLayerTracing(const char* tracePath) {
        Parcel data;
        Parcel reply;
        data.writeInterfaceToken(String16("android.ui.ISurfaceComposer"));
        data.writeInt32(2);
        data.writeCString(tracePath);
        transact(1025, data, &reply, 0 /* flags */);
    }
};

class TraceGenFlingerDataMapper : public TransactionProtoParser::FlingerDataMapper {
public:
    std::unordered_map<int32_t /*layerId*/, sp<IBinder> /* handle */> mLayerHandles;
    sp<IBinder> getLayerHandle(int32_t layerId) const override {
        if (layerId == -1) {
            ALOGE("Error: Called with layer=%d", layerId);
            return nullptr;
        }
        auto it = mLayerHandles.find(layerId);
        if (it == mLayerHandles.end()) {
            ALOGE("Error: Could not find handle for layer=%d", layerId);
            return nullptr;
        }
        return it->second;
    }
};

bool LayerTraceGenerator::generate(const proto::TransactionTraceFile& traceFile,
                                   const char* outputLayersTracePath) {
    if (traceFile.entry_size() == 0) {
        return false;
    }

    Factory mFactory;
    sp<MockSurfaceFlinger> flinger = new MockSurfaceFlinger(mFactory);
    TestableSurfaceFlinger mFlinger(flinger);
    mFlinger.setupRenderEngine(
            std::make_unique<testing::NiceMock<renderengine::mock::RenderEngine>>());
    mock::VsyncController* mVsyncController = new testing::NiceMock<mock::VsyncController>();
    mock::VSyncTracker* mVSyncTracker = new testing::NiceMock<mock::VSyncTracker>();
    mock::EventThread* mEventThread = new testing::NiceMock<mock::EventThread>();
    mock::EventThread* mSFEventThread = new testing::NiceMock<mock::EventThread>();
    mFlinger.setupScheduler(std::unique_ptr<scheduler::VsyncController>(mVsyncController),
                            std::unique_ptr<scheduler::VSyncTracker>(mVSyncTracker),
                            std::unique_ptr<EventThread>(mEventThread),
                            std::unique_ptr<EventThread>(mSFEventThread),
                            TestableSurfaceFlinger::SchedulerCallbackImpl::kNoOp,
                            TestableSurfaceFlinger::kOneDisplayMode, true /* useNiceMock */);

    Hwc2::mock::Composer* mComposer = new testing::NiceMock<Hwc2::mock::Composer>();
    mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
    mFlinger.mutableMaxRenderTargetSize() = 16384;

    flinger->setLayerTracingFlags(LayerTracing::TRACE_BUFFERS | LayerTracing::TRACE_INPUT |
                                  LayerTracing::TRACE_BUFFERS);
    flinger->startLayerTracing(traceFile.entry(0).elapsed_realtime_nanos());
    std::unique_ptr<TraceGenFlingerDataMapper> mapper =
            std::make_unique<TraceGenFlingerDataMapper>();
    TraceGenFlingerDataMapper* dataMapper = mapper.get();
    TransactionProtoParser parser(std::move(mapper));

    nsecs_t frameTime;
    int64_t vsyncId;
    ALOGD("Generating %d transactions...", traceFile.entry_size());
    for (int i = 0; i < traceFile.entry_size(); i++) {
        proto::TransactionTraceEntry entry = traceFile.entry(i);
        ALOGV("    Entry %04d/%04d for time=%" PRId64 " vsyncid=%" PRId64
              " layers +%d -%d transactions=%d",
              i, traceFile.entry_size(), entry.elapsed_realtime_nanos(), entry.vsync_id(),
              entry.added_layers_size(), entry.removed_layers_size(), entry.transactions_size());

        for (int j = 0; j < entry.added_layers_size(); j++) {
            // create layers
            TracingLayerCreationArgs tracingArgs;
            parser.fromProto(entry.added_layers(j), tracingArgs);

            sp<IBinder> outHandle;
            int32_t outLayerId;
            LayerCreationArgs args(mFlinger.flinger(), nullptr /* client */, tracingArgs.name,
                                   tracingArgs.flags, LayerMetadata());
            args.sequence = std::make_optional<int32_t>(tracingArgs.layerId);

            if (tracingArgs.mirrorFromId == -1) {
                sp<IBinder> parentHandle = nullptr;
                if ((tracingArgs.parentId != -1) &&
                    (dataMapper->mLayerHandles.find(tracingArgs.parentId) ==
                     dataMapper->mLayerHandles.end())) {
                    args.addToRoot = false;
                } else {
                    parentHandle = dataMapper->getLayerHandle(tracingArgs.parentId);
                }
                mFlinger.createLayer(args, &outHandle, parentHandle, &outLayerId,
                                     nullptr /* parentLayer */, nullptr /* outTransformHint */);
            } else {
                sp<IBinder> mirrorFromHandle = dataMapper->getLayerHandle(tracingArgs.mirrorFromId);
                mFlinger.mirrorLayer(args, mirrorFromHandle, &outHandle, &outLayerId);
            }
            LOG_ALWAYS_FATAL_IF(outLayerId != tracingArgs.layerId,
                                "Could not create layer expected:%d actual:%d", tracingArgs.layerId,
                                outLayerId);
            dataMapper->mLayerHandles[tracingArgs.layerId] = outHandle;
        }

        for (int j = 0; j < entry.transactions_size(); j++) {
            // apply transactions
            TransactionState transaction = parser.fromProto(entry.transactions(j));
            mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
                                         transaction.displays, transaction.flags,
                                         transaction.applyToken, transaction.inputWindowCommands,
                                         transaction.desiredPresentTime,
                                         transaction.isAutoTimestamp, {},
                                         transaction.hasListenerCallbacks,
                                         transaction.listenerCallbacks, transaction.id);
        }

        for (int j = 0; j < entry.removed_layer_handles_size(); j++) {
            dataMapper->mLayerHandles.erase(entry.removed_layer_handles(j));
        }

        frameTime = entry.elapsed_realtime_nanos();
        vsyncId = entry.vsync_id();
        mFlinger.commit(frameTime, vsyncId);
    }

    flinger->stopLayerTracing(outputLayersTracePath);
    ALOGD("End of generating trace file. File written to %s", outputLayersTracePath);
    dataMapper->mLayerHandles.clear();
    return true;
}

} // namespace android
 No newline at end of file
Loading