Loading services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp +21 −6 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; } Loading Loading @@ -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) { Loading services/surfaceflinger/FlagManager.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -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); Loading services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading services/surfaceflinger/Tracing/tools/Android.bp 0 → 100644 +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: ["."], } services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp 0 → 100644 +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
services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp +21 −6 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; } Loading Loading @@ -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) { Loading
services/surfaceflinger/FlagManager.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
services/surfaceflinger/Tracing/tools/Android.bp 0 → 100644 +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: ["."], }
services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp 0 → 100644 +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