Direct3D: Fix commandlist cleanup crash.

When checking for finished command lists and resetting them,
we call the finishedCallbacks. Some of those in turn can do a submit,
which will again call checkForFinishedCommandLists(). This could end up
trying to recycle the same command list twice as it iterates through
the deque. Clearing the entry from the deque and then recycling it
avoids this.

Change-Id: Iee01f1b80f99e1d6c00875b634c39789dc682d8e
Bug: skia:9935
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/299976
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2020-06-30 15:28:17 -04:00 committed by Skia Commit-Bot
parent 9eb0002b47
commit dd3b401e5b

View File

@ -161,15 +161,14 @@ void GrD3DGpu::checkForFinishedCommandLists() {
// value is less than the last signaled value. If so we pop it off and move onto the next.
// Repeat till we find a command list that has not finished yet (and all others afterwards are
// also guaranteed to not have finished).
SkDeque::F2BIter iter(fOutstandingCommandLists);
const OutstandingCommandList* curList = (const OutstandingCommandList*)iter.next();
while (curList && curList->fFenceValue <= currentFenceValue) {
curList = (const OutstandingCommandList*)iter.next();
OutstandingCommandList* front = (OutstandingCommandList*)fOutstandingCommandLists.front();
fResourceProvider.recycleDirectCommandList(std::move(front->fCommandList));
OutstandingCommandList* front = (OutstandingCommandList*)fOutstandingCommandLists.front();
while (front && front->fFenceValue <= currentFenceValue) {
std::unique_ptr<GrD3DDirectCommandList> currList(std::move(front->fCommandList));
// Since we used placement new we are responsible for calling the destructor manually.
front->~OutstandingCommandList();
fOutstandingCommandLists.pop_front();
fResourceProvider.recycleDirectCommandList(std::move(currList));
front = (OutstandingCommandList*)fOutstandingCommandLists.front();
}
}