1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
| //frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp
status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
nsecs_t expectedPresentTime) {
// This boolean is used to make sure that SurfaceFlinger's shadow copy
// of the buffer queue isn't modified when the buffer queue is returning
// BufferItem's that weren't actually queued. This can happen in shared
// buffer mode.
bool queuedBuffer = false;
const int32_t layerId = getSequence();
LayerRejecter r(mDrawingState, getDrawingState(), recomputeVisibleRegions,
getProducerStickyTransform() != 0, mName,
getTransformToDisplayInverse());
if (isRemovedFromCurrentState()) {
expectedPresentTime = 0;
}
// updateTexImage() below might drop the some buffers at the head of the queue if there is a
// buffer behind them which is timely to be presented. However this buffer may not be signaled
// yet. The code below makes sure that this wouldn't happen by setting maxFrameNumber to the
// last buffer that was signaled.
uint64_t lastSignaledFrameNumber = mLastFrameNumberReceived;
{
Mutex::Autolock lock(mQueueItemLock);
for (size_t i = 0; i < mQueueItems.size(); i++) {
bool fenceSignaled =
mQueueItems[i].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
if (!fenceSignaled) {
break;
}
lastSignaledFrameNumber = mQueueItems[i].item.mFrameNumber;
}
}
const uint64_t maxFrameNumberToAcquire =
std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber);
bool autoRefresh;
status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &autoRefresh,
&queuedBuffer, maxFrameNumberToAcquire);
mDrawingState.autoRefresh = autoRefresh;
if (updateResult == BufferQueue::PRESENT_LATER) {
// Producer doesn't want buffer to be displayed yet. Signal a
// layer update so we check again at the next opportunity.
// Producer 不希望显示缓冲区。 发出图层更新的信号,以便我们在下次有机会时再次检查。
mFlinger->onLayerUpdate(); // (692) SurfaceFlinger onLayerUpdate流程分析
return BAD_VALUE;
} else if (updateResult == BufferLayerConsumer::BUFFER_REJECTED) {
// If the buffer has been rejected, remove it from the shadow queue
// and return early
if (queuedBuffer) {
Mutex::Autolock lock(mQueueItemLock);
if (mQueuedFrames > 0) {
mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
if (mQueueItems[0].surfaceFrame) {
addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
}
mQueueItems.erase(mQueueItems.begin());
mQueuedFrames--;
}
}
return BAD_VALUE;
} else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
// This can occur if something goes wrong when trying to create the
// EGLImage for this buffer. If this happens, the buffer has already
// been released, so we need to clean up the queue and bug out
// early.
if (queuedBuffer) {
Mutex::Autolock lock(mQueueItemLock);
for (auto& [item, surfaceFrame] : mQueueItems) {
if (surfaceFrame) {
addSurfaceFrameDroppedForBuffer(surfaceFrame);
}
}
mQueueItems.clear();
mQueuedFrames = 0;
mFlinger->mTimeStats->onDestroy(layerId);
mFlinger->mFrameTracer->onDestroy(layerId);
}
// Once we have hit this state, the shadow queue may no longer
// correctly reflect the incoming BufferQueue's contents, so even if
// updateTexImage starts working, the only safe course of action is
// to continue to ignore updates.
mUpdateTexImageFailed = true;
return BAD_VALUE;
}
bool more_frames_pending = false;
if (queuedBuffer) {
// Autolock scope
auto currentFrameNumber = mConsumer->getFrameNumber();
Mutex::Autolock lock(mQueueItemLock);
// Remove any stale buffers that have been dropped during
// updateTexImage
while (mQueuedFrames > 0 && mQueueItems[0].item.mFrameNumber != currentFrameNumber) {
mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
if (mQueueItems[0].surfaceFrame) {
addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
}
mQueueItems.erase(mQueueItems.begin());
mQueuedFrames--;
}
uint64_t bufferID = mQueueItems[0].item.mGraphicBuffer->getId();
mFlinger->mTimeStats->setLatchTime(layerId, currentFrameNumber, latchTime);
mFlinger->mFrameTracer->traceTimestamp(layerId, bufferID, currentFrameNumber, latchTime,
FrameTracer::FrameEvent::LATCH);
if (mQueueItems[0].surfaceFrame) {
addSurfaceFramePresentedForBuffer(mQueueItems[0].surfaceFrame,
mQueueItems[0].item.mFenceTime->getSignalTime(),
latchTime);
}
mQueueItems.erase(mQueueItems.begin());
more_frames_pending = (mQueuedFrames.fetch_sub(1) > 1);
}
// Decrement the queued-frames count. Signal another event if we
// have more frames pending.
//减少排队的帧计数。 如果我们有更多待处理的帧,则发出另一个事件的信号。
if ((queuedBuffer && more_frames_pending) || mDrawingState.autoRefresh) {
mFlinger->onLayerUpdate(); // (692) SurfaceFlinger onLayerUpdate流程分析 | 知识管理 - PingCode
}
return NO_ERROR;
}
|