| /* |
| * Copyright 2016 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. |
| */ |
| |
| #ifndef ANDROID_SURFACEINTERCEPTOR_H |
| #define ANDROID_SURFACEINTERCEPTOR_H |
| |
| #include <frameworks/native/cmds/surfacereplayer/proto/src/trace.pb.h> |
| |
| #include <mutex> |
| |
| #include <binder/IBinder.h> |
| |
| #include <gui/LayerState.h> |
| |
| #include <utils/KeyedVector.h> |
| #include <utils/SortedVector.h> |
| #include <utils/StrongPointer.h> |
| #include <utils/Vector.h> |
| |
| #include "DisplayDevice.h" |
| |
| namespace android { |
| |
| class BufferItem; |
| class Layer; |
| class SurfaceFlinger; |
| struct ComposerState; |
| struct DisplayDeviceState; |
| struct DisplayState; |
| struct layer_state_t; |
| using Transaction = surfaceflinger::Transaction; |
| using Trace = surfaceflinger::Trace; |
| using Rectangle = surfaceflinger::Rectangle; |
| using SurfaceChange = surfaceflinger::SurfaceChange; |
| using Increment = surfaceflinger::Increment; |
| using DisplayChange = surfaceflinger::DisplayChange; |
| |
| constexpr auto DEFAULT_FILENAME = "/data/misc/wmtrace/transaction_trace.winscope"; |
| |
| class SurfaceInterceptor : public IBinder::DeathRecipient { |
| public: |
| virtual ~SurfaceInterceptor(); |
| |
| // Both vectors are used to capture the current state of SF as the initial snapshot in the trace |
| virtual void enable(const SortedVector<sp<Layer>>& layers, |
| const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays) = 0; |
| virtual void disable() = 0; |
| virtual bool isEnabled() = 0; |
| |
| virtual void addTransactionTraceListener( |
| const sp<gui::ITransactionTraceListener>& listener) = 0; |
| virtual void binderDied(const wp<IBinder>& who) = 0; |
| |
| // Intercept display and surface transactions |
| virtual void saveTransaction( |
| const Vector<ComposerState>& stateUpdates, |
| const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays, |
| const Vector<DisplayState>& changedDisplays, uint32_t flags, int originPid, |
| int originUid, uint64_t transactionId) = 0; |
| |
| // Intercept surface data |
| virtual void saveSurfaceCreation(const sp<const Layer>& layer) = 0; |
| virtual void saveSurfaceDeletion(const sp<const Layer>& layer) = 0; |
| virtual void saveBufferUpdate(int32_t layerId, uint32_t width, uint32_t height, |
| uint64_t frameNumber) = 0; |
| |
| // Intercept display data |
| virtual void saveDisplayCreation(const DisplayDeviceState& info) = 0; |
| virtual void saveDisplayDeletion(int32_t sequenceId) = 0; |
| virtual void savePowerModeUpdate(int32_t sequenceId, int32_t mode) = 0; |
| virtual void saveVSyncEvent(nsecs_t timestamp) = 0; |
| }; |
| |
| namespace impl { |
| |
| /* |
| * SurfaceInterceptor intercepts and stores incoming streams of window |
| * properties on SurfaceFlinger. |
| */ |
| class SurfaceInterceptor final : public android::SurfaceInterceptor { |
| public: |
| SurfaceInterceptor() = default; |
| ~SurfaceInterceptor() override = default; |
| |
| // Both vectors are used to capture the current state of SF as the initial snapshot in the trace |
| void enable(const SortedVector<sp<Layer>>& layers, |
| const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays) override; |
| void disable() override; |
| bool isEnabled() override; |
| |
| void addTransactionTraceListener(const sp<gui::ITransactionTraceListener>& listener) override; |
| void binderDied(const wp<IBinder>& who) override; |
| |
| // Intercept display and surface transactions |
| void saveTransaction(const Vector<ComposerState>& stateUpdates, |
| const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays, |
| const Vector<DisplayState>& changedDisplays, uint32_t flags, int originPid, |
| int originUid, uint64_t transactionId) override; |
| |
| // Intercept surface data |
| void saveSurfaceCreation(const sp<const Layer>& layer) override; |
| void saveSurfaceDeletion(const sp<const Layer>& layer) override; |
| void saveBufferUpdate(int32_t layerId, uint32_t width, uint32_t height, |
| uint64_t frameNumber) override; |
| |
| // Intercept display data |
| void saveDisplayCreation(const DisplayDeviceState& info) override; |
| void saveDisplayDeletion(int32_t sequenceId) override; |
| void savePowerModeUpdate(int32_t sequenceId, int32_t mode) override; |
| void saveVSyncEvent(nsecs_t timestamp) override; |
| |
| private: |
| // The creation increments of Surfaces and Displays do not contain enough information to capture |
| // the initial state of each object, so a transaction with all of the missing properties is |
| // performed at the initial snapshot for each display and surface. |
| void saveExistingDisplaysLocked( |
| const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays); |
| void saveExistingSurfacesLocked(const SortedVector<sp<Layer>>& layers); |
| void addInitialSurfaceStateLocked(Increment* increment, const sp<const Layer>& layer); |
| void addInitialDisplayStateLocked(Increment* increment, const DisplayDeviceState& display); |
| |
| status_t writeProtoFileLocked(); |
| const sp<const Layer> getLayer(const wp<IBinder>& weakHandle) const; |
| int32_t getLayerId(const sp<const Layer>& layer) const; |
| int32_t getLayerIdFromWeakRef(const wp<const Layer>& layer) const; |
| int32_t getLayerIdFromHandle(const sp<IBinder>& weakHandle) const; |
| |
| Increment* createTraceIncrementLocked(); |
| void addSurfaceCreationLocked(Increment* increment, const sp<const Layer>& layer); |
| void addSurfaceDeletionLocked(Increment* increment, const sp<const Layer>& layer); |
| void addBufferUpdateLocked(Increment* increment, int32_t layerId, uint32_t width, |
| uint32_t height, uint64_t frameNumber); |
| void addVSyncUpdateLocked(Increment* increment, nsecs_t timestamp); |
| void addDisplayCreationLocked(Increment* increment, const DisplayDeviceState& info); |
| void addDisplayDeletionLocked(Increment* increment, int32_t sequenceId); |
| void addPowerModeUpdateLocked(Increment* increment, int32_t sequenceId, int32_t mode); |
| |
| // Add surface transactions to the trace |
| SurfaceChange* createSurfaceChangeLocked(Transaction* transaction, int32_t layerId); |
| void setProtoRectLocked(Rectangle* protoRect, const Rect& rect); |
| void addPositionLocked(Transaction* transaction, int32_t layerId, float x, float y); |
| void addDepthLocked(Transaction* transaction, int32_t layerId, uint32_t z); |
| void addSizeLocked(Transaction* transaction, int32_t layerId, uint32_t w, uint32_t h); |
| void addAlphaLocked(Transaction* transaction, int32_t layerId, float alpha); |
| void addMatrixLocked(Transaction* transaction, int32_t layerId, |
| const layer_state_t::matrix22_t& matrix); |
| void addTransparentRegionLocked(Transaction* transaction, int32_t layerId, |
| const Region& transRegion); |
| void addFlagsLocked(Transaction* transaction, int32_t layerId, uint8_t flags, uint8_t mask); |
| void addLayerStackLocked(Transaction* transaction, int32_t layerId, uint32_t layerStack); |
| void addCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect); |
| void addCornerRadiusLocked(Transaction* transaction, int32_t layerId, float cornerRadius); |
| void addBackgroundBlurRadiusLocked(Transaction* transaction, int32_t layerId, |
| int32_t backgroundBlurRadius); |
| void addBlurRegionsLocked(Transaction* transaction, int32_t layerId, |
| const std::vector<BlurRegion>& effectRegions); |
| void addSurfaceChangesLocked(Transaction* transaction, const layer_state_t& state); |
| void addTransactionLocked(Increment* increment, const Vector<ComposerState>& stateUpdates, |
| const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays, |
| const Vector<DisplayState>& changedDisplays, |
| uint32_t transactionFlags, int originPid, int originUid, |
| uint64_t transactionId); |
| void addReparentLocked(Transaction* transaction, int32_t layerId, int32_t parentId); |
| void addRelativeParentLocked(Transaction* transaction, int32_t layerId, int32_t parentId, |
| int z); |
| void addShadowRadiusLocked(Transaction* transaction, int32_t layerId, float shadowRadius); |
| void addTrustedOverlayLocked(Transaction* transaction, int32_t layerId, bool isTrustedOverlay); |
| |
| // Add display transactions to the trace |
| DisplayChange* createDisplayChangeLocked(Transaction* transaction, int32_t sequenceId); |
| void addDisplaySurfaceLocked(Transaction* transaction, int32_t sequenceId, |
| const sp<const IGraphicBufferProducer>& surface); |
| void addDisplayLayerStackLocked(Transaction* transaction, int32_t sequenceId, |
| uint32_t layerStack); |
| void addDisplayFlagsLocked(Transaction* transaction, int32_t sequenceId, uint32_t flags); |
| void addDisplaySizeLocked(Transaction* transaction, int32_t sequenceId, uint32_t w, |
| uint32_t h); |
| void addDisplayProjectionLocked(Transaction* transaction, int32_t sequenceId, |
| int32_t orientation, const Rect& viewport, const Rect& frame); |
| void addDisplayChangesLocked(Transaction* transaction, |
| const DisplayState& state, int32_t sequenceId); |
| |
| // Add transaction origin to trace |
| void setTransactionOriginLocked(Transaction* transaction, int32_t pid, int32_t uid); |
| |
| bool mEnabled {false}; |
| std::string mOutputFileName {DEFAULT_FILENAME}; |
| std::mutex mTraceMutex {}; |
| Trace mTrace {}; |
| std::mutex mListenersMutex; |
| std::map<wp<IBinder>, sp<gui::ITransactionTraceListener>> mTraceToggledListeners |
| GUARDED_BY(mListenersMutex); |
| }; |
| |
| } // namespace impl |
| |
| } // namespace android |
| |
| #endif // ANDROID_SURFACEINTERCEPTOR_H |