Android Graphics模块中的各种State和重要类普法
引言
尼玛,这Android Graphics图形栈蛋疼啊,更新太快了。机会是每年一个版本,前进的胶布不能停啊,继续干。这边博客,我们的核心是理一理Android Graphics中各种State状态类。
这里分析的Android版本是Android 13 aosp!
一. Layer中State
先不解释,先直接上代码,后分析:
//frameworks/native/services/surfaceflinger/Layer.h
//struct android::Layer::State
struct State {
Geometry active_legacy;
Geometry requested_legacy;
int32_t z;
ui::LayerStack layerStack;
uint32_t flags;
uint8_t reserved[2];
int32_t sequence; // changes when visible regions can change
bool modified;
// Crop is expressed in layer space coordinate.
Rect crop;
Rect requestedCrop;
// the transparentRegion hint is a bit special, it's latched only
// when we receive a buffer -- this is because it's "content"
// dependent.
Region activeTransparentRegion_legacy;
Region requestedTransparentRegion_legacy;
LayerMetadata metadata;
// If non-null, a Surface this Surface's Z-order is interpreted relative to.
wp<Layer> zOrderRelativeOf;
bool isRelativeOf{false};
// A list of surfaces whose Z-order is interpreted relative to ours.
SortedVector<wp<Layer>> zOrderRelatives;
half4 color;
float cornerRadius;
int backgroundBlurRadius;
gui::WindowInfo inputInfo;
wp<Layer> touchableRegionCrop;
// dataspace is only used by BufferStateLayer and EffectLayer
ui::Dataspace dataspace;
// The fields below this point are only used by BufferStateLayer
uint64_t frameNumber;
uint32_t width;
uint32_t height;
ui::Transform transform;
uint32_t bufferTransform;
bool transformToDisplayInverse;
Region transparentRegionHint;
std::shared_ptr<renderengine::ExternalTexture> buffer;
client_cache_t clientCacheId;
sp<Fence> acquireFence;
std::shared_ptr<FenceTime> acquireFenceTime;
HdrMetadata hdrMetadata;
Region surfaceDamageRegion;
int32_t api;
sp<NativeHandle> sidebandStream;
mat4 colorTransform;
bool hasColorTransform;
// pointer to background color layer that, if set, appears below the buffer state layer
// and the buffer state layer's children. Z order will be set to
// INT_MIN
sp<Layer> bgColorLayer;
// The deque of callback handles for this frame. The back of the deque contains the most
// recent callback handle.
std::deque<sp<CallbackHandle>> callbackHandles;
bool colorSpaceAgnostic;
nsecs_t desiredPresentTime = 0;
bool isAutoTimestamp = true;
// Length of the cast shadow. If the radius is > 0, a shadow of length shadowRadius will
// be rendered around the layer.
float shadowRadius;
// Layer regions that are made of custom materials, like frosted glass
std::vector<BlurRegion> blurRegions;
// Priority of the layer assigned by Window Manager.
int32_t frameRateSelectionPriority;
FrameRate frameRate;
// The combined frame rate of parents / children of this layer
FrameRate frameRateForLayerTree;
// Set by window manager indicating the layer and all its children are
// in a different orientation than the display. The hint suggests that
// the graphic producers should receive a transform hint as if the
// display was in this orientation. When the display changes to match
// the layer orientation, the graphic producer may not need to allocate
// a buffer of a different size. ui::Transform::ROT_INVALID means the
// a fixed transform hint is not set.
ui::Transform::RotationFlags fixedTransformHint;
// The vsync info that was used to start the transaction
FrameTimelineInfo frameTimelineInfo;
// When the transaction was posted
nsecs_t postTime;
sp<ITransactionCompletedListener> releaseBufferListener;
// SurfaceFrame that tracks the timeline of Transactions that contain a Buffer. Only one
// such SurfaceFrame exists because only one buffer can be presented on the layer per vsync.
// If multiple buffers are queued, the prior ones will be dropped, along with the
// SurfaceFrame that's tracking them.
std::shared_ptr<frametimeline::SurfaceFrame> bufferSurfaceFrameTX;
// A map of token(frametimelineVsyncId) to the SurfaceFrame that's tracking a transaction
// that contains the token. Only one SurfaceFrame exisits for transactions that share the
// same token, unless they are presented in different vsyncs.
std::unordered_map<int64_t, std::shared_ptr<frametimeline::SurfaceFrame>>
bufferlessSurfaceFramesTX;
// An arbitrary threshold for the number of BufferlessSurfaceFrames in the state. Used to
// trigger a warning if the number of SurfaceFrames crosses the threshold.
static constexpr uint32_t kStateSurfaceFramesThreshold = 25;
// Stretch effect to apply to this layer
StretchEffect stretchEffect;
// Whether or not this layer is a trusted overlay for input
bool isTrustedOverlay;
Rect bufferCrop;
Rect destinationFrame;
sp<IBinder> releaseBufferEndpoint;
gui::DropInputMode dropInputMode;
bool autoRefresh = false;
bool dimmingEnabled = true;
};
// These are only accessed by the main thread or the tracing thread.
State mDrawingState;
这里的Layer.State主要存储了该Layer相关的数据,例如长宽,各种矩阵,阴影等。
这里有点疑问,没有看到mCurrentState这个!
二. BufferLayer中对应的BufferInfo
这个BufferInfo比较重要,主要用于将Layer的信息传递给后续的OutputLayer。
//frameworks/native/services/surfaceflinger/BufferLayer.h
class BufferLayer : public Layer {
...
protected:
struct BufferInfo {
nsecs_t mDesiredPresentTime;
std::shared_ptr<FenceTime> mFenceTime;
sp<Fence> mFence;
uint32_t mTransform{0};
ui::Dataspace mDataspace{ui::Dataspace::UNKNOWN};
Rect mCrop;
uint32_t mScaleMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
Region mSurfaceDamage;
HdrMetadata mHdrMetadata;
int mApi;
PixelFormat mPixelFormat{PIXEL_FORMAT_NONE};
bool mTransformToDisplayInverse{false};
std::shared_ptr<renderengine::ExternalTexture> mBuffer;
uint64_t mFrameNumber;
int mBufferSlot{BufferQueue::INVALID_BUFFER_SLOT};
bool mFrameLatencyNeeded{false};
};
BufferInfo mBufferInfo;
...
}
三. OutputLayer对应的CompositionState
这里需要注意CompositionState对应的域空间,不要和Layer里面的搞混淆了!
//frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
class OutputLayer {
using CompositionState = compositionengine::impl::OutputLayerCompositionState;
}
///frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
namespace compositionengine::impl {//namespace android::compositionengine::impl
// Note that fields that affect HW composer state may need to be mirrored into
// android::compositionengine::impl::planner::LayerState
struct OutputLayerCompositionState {
// The portion of the layer that is not obscured by opaque layers on top
Region visibleRegion;
// The portion of the layer that is not obscured and is also opaque
Region visibleNonTransparentRegion;
// The portion of the layer that is obscured by opaque layers on top
Region coveredRegion;
// The visibleRegion transformed to output space
Region outputSpaceVisibleRegion;
// Region cast by the layer's shadow
Region shadowRegion;
// If true, client composition will be used on this output
bool forceClientComposition{false};
// If true, when doing client composition, the target may need to be cleared
bool clearClientTarget{false};
// The display frame for this layer on this output
Rect displayFrame;
// The source crop for this layer on this output
FloatRect sourceCrop;
// The buffer transform to use for this layer o on this output.
Hwc2::Transform bufferTransform{static_cast<Hwc2::Transform>(0)};
// The dataspace for this layer
ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};
// A hint to the HWC that this region is transparent and may be skipped in
// order to save power.
Region outputSpaceBlockingRegionHint;
// Overrides the buffer, acquire fence, and display frame stored in LayerFECompositionState
struct {
std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
sp<Fence> acquireFence = nullptr;
Rect displayFrame = {};
ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};
ProjectionSpace displaySpace;
Region damageRegion = Region::INVALID_REGION;
Region visibleRegion;
// The OutputLayer pointed to by this field will be rearranged to draw
// behind the OutputLayer represented by this CompositionState and will
// be visible through it. Unowned - the OutputLayer's lifetime will
// outlast this.)
compositionengine::OutputLayer* peekThroughLayer = nullptr;
// True when this layer's blur has been cached with a previous layer, so that this layer
// does not need to request blurring.
// TODO(b/188816867): support blur regions too, which are less likely to be common if a
// device supports cross-window blurs. Blur region support should be doable, but we would
// need to make sure that layer caching works well with the blur region transform passed
// into RenderEngine
bool disableBackgroundBlur = false;
} overrideInfo;
/*
* HWC state
*/
struct Hwc {
explicit Hwc(std::shared_ptr<HWC2::Layer> hwcLayer) : hwcLayer(hwcLayer) {}
// The HWC Layer backing this layer
std::shared_ptr<HWC2::Layer> hwcLayer;
// The most recently set HWC composition type for this layer
aidl::android::hardware::graphics::composer3::Composition hwcCompositionType{
aidl::android::hardware::graphics::composer3::Composition::INVALID};
// The buffer cache for this layer. This is used to lower the
// cost of sending reused buffers to the HWC.
HwcBufferCache hwcBufferCache;
// Set to true when overridden info has been sent to HW composer
bool stateOverridden = false;
// True when this layer was skipped as part of SF-side layer caching.
bool layerSkipped = false;
};
// The HWC state is optional, and is only set up if there is any potential
// HWC acceleration possible.
std::optional<Hwc> hwc;
// Debugging
void dump(std::string& result) const;
// Timestamp for when the layer is queued for client composition
nsecs_t clientCompositionTimestamp{0};
static constexpr float kDefaultWhitePointNits = 200.f;
float whitePointNits = kDefaultWhitePointNits;
// Dimming ratio of the layer from [0, 1]
static constexpr float kDefaultDimmingRatio = 1.f;
float dimmingRatio = kDefaultDimmingRatio;
};
} // namespace compositionengine::impl
四 Output和Display
这里要怎么理解Output和Display呢,可以简单概括就是:
- Output: 封装所有与合成输出层相关的状态
//frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
namespace android {
namespace compositionengine {
class Output {
public:
using OutputCompositionState = compositionengine::impl::OutputCompositionState;
// Gets the raw composition state data for the output
// TODO(lpique): Make this protected once it is only internally called.
virtual const OutputCompositionState& getState() const = 0;
// Allows mutable access to the raw composition state data for the output.
// This is meant to be used by the various functions that are part of the
// composition process.
// TODO(lpique): Make this protected once it is only internally called.
virtual OutputCompositionState& editState() = 0;
auto getOutputLayersOrderedByZ() const { return OutputLayersEnumerator(*this); }
// Prepare the output, updating the OutputLayers used in the output
virtual void prepare(const CompositionRefreshArgs&, LayerFESet&) = 0;
// Presents the output, finalizing all composition details
virtual void present(const CompositionRefreshArgs&) = 0;
// Latches the front-end layer state for each output layer
virtual void updateLayerStateFromFE(const CompositionRefreshArgs&) const = 0;
}
}// namespace compositionengine
}// namespace android
Output还有一个对应域空间android::compositionengine::impl的,它们之间的关联,暂时还没有搞清楚!
- Display: 表示所有输出层最终对应的显示设备,可以有硬件合成器支持的显示设备,也可以对应虚拟显示设备
namespace android::compositionengine {
class Display : public virtual Output {
}
} // namespace android::compositionengine
五. LayerFE
按照谷歌注释的翻译意思是,定义合成引擎用于向前端层发出请求的接口!这个我的理解它主要是Layer的一个前端,主要用来处理Layer合成相关的,!表示一个"前端"Layer,跟Layer相对应,用于处理Layer在合成阶段的工作
namespace android {
namespace compositionengine {
// Defines the interface used by the CompositionEngine to make requests
// of the front-end layer
class LayerFE : public virtual RefBase {
// Gets the raw front-end composition state data for the layer
virtual const LayerFECompositionState* getCompositionState() const = 0;
}
} // namespace compositionengine
} // namespace android
六 LayerFECompositionState
表示Layer的frontEnd(LayerFECompositionState)
//frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
/*
* Used by LayerFE::getCompositionState
* Note that fields that affect HW composer state may need to be mirrored into
* android::compositionengine::impl::planner::LayerState
*/
struct LayerFECompositionState {
// If set to true, forces client composition on all output layers until
// the next geometry change.
bool forceClientComposition{false};
// TODO(b/121291683): Reorganize and rename the contents of this structure
/*
* Visibility state
*/
// The filter that determines which outputs include this layer
ui::LayerFilter outputFilter;
// If false, this layer should not be considered visible
bool isVisible{true};
// True if the layer is completely opaque
bool isOpaque{true};
// If true, invalidates the entire visible region
bool contentDirty{false};
// The alpha value for this layer
float alpha{1.f};
// Background blur in pixels
int backgroundBlurRadius{0};
// The transform from layer local coordinates to composition coordinates
ui::Transform geomLayerTransform;
// The inverse of the layer transform
ui::Transform geomInverseLayerTransform;
// The hint from the layer producer as to what portion of the layer is
// transparent.
Region transparentRegionHint;
// The blend mode for this layer
hal::BlendMode blendMode{hal::BlendMode::INVALID};
// The bounds of the layer in layer local coordinates
FloatRect geomLayerBounds;
// length of the shadow in screen space
float shadowRadius{0.f};
// List of regions that require blur
std::vector<BlurRegion> blurRegions;
StretchEffect stretchEffect;
/*
* Geometry state
*/
bool isSecure{false};
bool geomUsesSourceCrop{false};
bool geomBufferUsesDisplayInverseTransform{false};
uint32_t geomBufferTransform{0};
Rect geomBufferSize;
Rect geomContentCrop;
Rect geomCrop;
GenericLayerMetadataMap metadata;
/*
* Per-frame content
*/
// The type of composition for this layer
aidl::android::hardware::graphics::composer3::Composition compositionType{
aidl::android::hardware::graphics::composer3::Composition::INVALID};
// The buffer and related state
sp<GraphicBuffer> buffer;
int bufferSlot{BufferQueue::INVALID_BUFFER_SLOT};
sp<Fence> acquireFence = Fence::NO_FENCE;
Region surfaceDamage;
uint64_t frameNumber = 0;
// The handle to use for a sideband stream for this layer
sp<NativeHandle> sidebandStream;
// If true, this sideband layer has a frame update
bool sidebandStreamHasFrame{false};
// The color for this layer
half4 color;
/*
* Per-frame presentation state
*/
// If true, this layer will use the dataspace chosen for the output and
// ignore the dataspace value just below
bool isColorspaceAgnostic{false};
// The dataspace for this layer
ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};
// The metadata for this layer
HdrMetadata hdrMetadata;
// The color transform
mat4 colorTransform;
bool colorTransformIsIdentity{true};
// True if the layer has protected content
bool hasProtectedContent{false};
/*
* Cursor state
*/
// The output-independent frame for the cursor
Rect cursorFrame;
// framerate of the layer as measured by LayerHistory
float fps;
// The dimming flag
bool dimmingEnabled{true};
virtual ~LayerFECompositionState();
// Debugging
virtual void dump(std::string& out) const;
};
参考里面对核心类的解释!