Remove FrameBuffer teardownVkColorBuffer() calls
... as these are no longer needed after aosp/2452176 which ties
the VK backing directly to the lifetime of ColorBuffer.
Bug: b/233939967
Bug: b/271904841
Test: android build
Test: cmake build
Test: cvd start --gpu_mode=gfxstream
Test: cvd start --gpu_mode=gfxstream --enable_gpu_angle=true
Test: gfxstream unit tests
Change-Id: I3828071491ea0eeadd612838402d6b7a75d826e1
diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp
index 7103903..d209e29 100644
--- a/stream-servers/FrameBuffer.cpp
+++ b/stream-servers/FrameBuffer.cpp
@@ -1264,49 +1264,49 @@
if (m_shuttingDown) {
return;
}
- AutoLock mutex(m_lock);
- auto colorBuffersToCleanup = destroyEmulatedEglWindowSurfaceLocked(p_surface);
- mutex.unlock();
+ std::vector<ColorBufferPtr> colorBuffersToCleanup;
- for (auto handle : colorBuffersToCleanup) {
- goldfish_vk::teardownVkColorBuffer(handle);
+ {
+ AutoLock mutex(m_lock);
+ destroyEmulatedEglWindowSurfaceLocked(p_surface, &colorBuffersToCleanup);
}
+
+ // Avoid holding the global lock during potentially slow ColorBuffer
+ // destruction (during `colorBuffersToCleanup` destruction).
}
-std::vector<HandleType> FrameBuffer::destroyEmulatedEglWindowSurfaceLocked(HandleType p_surface) {
- std::vector<HandleType> colorBuffersToCleanUp;
- const auto w = m_windows.find(p_surface);
- if (w != m_windows.end()) {
- RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
- if (!m_guestManagedColorBufferLifetime) {
- if (m_refCountPipeEnabled) {
- if (decColorBufferRefCountLocked(w->second.second)) {
- colorBuffersToCleanUp.push_back(w->second.second);
- }
- } else {
- if (closeColorBufferLocked(w->second.second)) {
- colorBuffersToCleanUp.push_back(w->second.second);
- }
- }
- }
- m_windows.erase(w);
- RenderThreadInfo* tinfo = RenderThreadInfo::get();
- uint64_t puid = tinfo->m_puid;
- if (puid) {
- auto ite = m_procOwnedEmulatedEglWindowSurfaces.find(puid);
- if (ite != m_procOwnedEmulatedEglWindowSurfaces.end()) {
- ite->second.erase(p_surface);
- }
+void FrameBuffer::destroyEmulatedEglWindowSurfaceLocked(
+ HandleType p_surface, std::vector<ColorBufferPtr>* colorBuffersToCleanup) {
+ auto it = m_windows.find(p_surface);
+ if (it == m_windows.end()) {
+ return;
+ }
+ auto& surfaceAndBackingColorBuffer = it->second;
+
+ RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
+ if (!m_guestManagedColorBufferLifetime) {
+ if (m_refCountPipeEnabled) {
+ decColorBufferRefCountLocked(surfaceAndBackingColorBuffer.second,
+ colorBuffersToCleanup);
} else {
- if (!tinfo->m_glInfo) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "Render thread GL not available.";
- }
- tinfo->m_glInfo->m_windowSet.erase(p_surface);
+ closeColorBufferLocked(surfaceAndBackingColorBuffer.second, colorBuffersToCleanup);
}
}
- return colorBuffersToCleanUp;
+ m_windows.erase(it);
+ RenderThreadInfo* tinfo = RenderThreadInfo::get();
+ uint64_t puid = tinfo->m_puid;
+ if (puid) {
+ auto ite = m_procOwnedEmulatedEglWindowSurfaces.find(puid);
+ if (ite != m_procOwnedEmulatedEglWindowSurfaces.end()) {
+ ite->second.erase(p_surface);
+ }
+ } else {
+ if (!tinfo->m_glInfo) {
+ GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Render thread GL not available.";
+ }
+ tinfo->m_glInfo->m_windowSet.erase(p_surface);
+ }
}
void FrameBuffer::createEmulatedEglFenceSync(EGLenum type,
@@ -1406,36 +1406,32 @@
return;
}
- std::vector<HandleType> colorBuffersToCleanup;
+ std::vector<ColorBufferPtr> colorBuffersToCleanup;
- AutoLock mutex(m_lock);
- RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
- for (const HandleType winHandle : tinfo->m_windowSet) {
- const auto winIt = m_windows.find(winHandle);
- if (winIt != m_windows.end()) {
- if (const HandleType oldColorBufferHandle = winIt->second.second) {
- if (!m_guestManagedColorBufferLifetime) {
- if (m_refCountPipeEnabled) {
- if (decColorBufferRefCountLocked(oldColorBufferHandle)) {
- colorBuffersToCleanup.push_back(oldColorBufferHandle);
- }
- } else {
- if (closeColorBufferLocked(oldColorBufferHandle)) {
- colorBuffersToCleanup.push_back(oldColorBufferHandle);
+ {
+ AutoLock mutex(m_lock);
+ RecursiveScopedContextBind bind(getPbufferSurfaceContextHelper());
+ for (const HandleType winHandle : tinfo->m_windowSet) {
+ const auto winIt = m_windows.find(winHandle);
+ if (winIt != m_windows.end()) {
+ if (const HandleType oldColorBufferHandle = winIt->second.second) {
+ if (!m_guestManagedColorBufferLifetime) {
+ if (m_refCountPipeEnabled) {
+ decColorBufferRefCountLocked(oldColorBufferHandle,
+ &colorBuffersToCleanup);
+ } else {
+ closeColorBufferLocked(oldColorBufferHandle, &colorBuffersToCleanup);
}
}
+ m_windows.erase(winIt);
}
- m_windows.erase(winIt);
}
}
+ tinfo->m_windowSet.clear();
}
- tinfo->m_windowSet.clear();
- m_lock.unlock();
-
- for (auto handle: colorBuffersToCleanup) {
- goldfish_vk::teardownVkColorBuffer(handle);
- }
+ // Avoid holding the global lock during potentially slow ColorBuffer
+ // destruction (during `colorBuffersToCleanup` destruction).
}
int FrameBuffer::openColorBuffer(HandleType p_colorbuffer) {
@@ -1468,7 +1464,7 @@
return 0;
}
-void FrameBuffer::closeColorBuffer(HandleType p_colorbuffer) {
+void FrameBuffer::closeColorBuffer(HandleType colorBufferHandle) {
// When guest feature flag RefCountPipe is on, no reference counting is
// needed.
if (m_refCountPipeEnabled) {
@@ -1477,32 +1473,30 @@
RenderThreadInfo* tInfo = RenderThreadInfo::get();
- std::vector<HandleType> toCleanup;
+ std::vector<ColorBufferPtr> colorBuffersToCleanup;
- AutoLock mutex(m_lock);
- uint64_t puid = tInfo ? tInfo->m_puid : 0;
- if (puid) {
- auto ite = m_procOwnedColorBuffers.find(puid);
- if (ite != m_procOwnedColorBuffers.end()) {
- const auto& cb = ite->second.find(p_colorbuffer);
- if (cb != ite->second.end()) {
- ite->second.erase(cb);
- if (closeColorBufferLocked(p_colorbuffer)) {
- toCleanup.push_back(p_colorbuffer);
- }
+ {
+ AutoLock mutex(m_lock);
+ uint64_t puid = tInfo ? tInfo->m_puid : 0;
+ if (puid) {
+ auto processOwnedColorBuffersIt = m_procOwnedColorBuffers.find(puid);
+ if (processOwnedColorBuffersIt == m_procOwnedColorBuffers.end()) {
+ return;
}
- }
- } else {
- if (closeColorBufferLocked(p_colorbuffer)) {
- toCleanup.push_back(p_colorbuffer);
+ auto& processOwnedColorBuffers = processOwnedColorBuffersIt->second;
+
+ auto colorBufferIt = processOwnedColorBuffers.find(colorBufferHandle);
+ if (colorBufferIt != processOwnedColorBuffers.end()) {
+ processOwnedColorBuffers.erase(colorBufferIt);
+ closeColorBufferLocked(colorBufferHandle, &colorBuffersToCleanup);
+ }
+ } else {
+ closeColorBufferLocked(colorBufferHandle, &colorBuffersToCleanup);
}
}
- mutex.unlock();
-
- for (auto handle : toCleanup) {
- goldfish_vk::teardownVkColorBuffer(handle);
- }
+ // Avoid holding the global lock during potentially slow ColorBuffer
+ // destruction (during `colorBuffersToCleanup` destruction).
}
void FrameBuffer::closeBuffer(HandleType p_buffer) {
@@ -1517,7 +1511,8 @@
m_buffers.erase(it);
}
-bool FrameBuffer::closeColorBufferLocked(HandleType p_colorbuffer,
+bool FrameBuffer::closeColorBufferLocked(HandleType colorBufferHandle,
+ std::vector<ColorBufferPtr>* colorBuffersToCleanup,
bool forced) {
// When guest feature flag RefCountPipe is on, no reference counting is
// needed.
@@ -1530,14 +1525,15 @@
if (m_noDelayCloseColorBufferEnabled) forced = true;
- ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer));
- if (c == m_colorbuffers.end()) {
+ auto it = m_colorbuffers.find(colorBufferHandle);
+ if (it == m_colorbuffers.end()) {
// This is harmless: it is normal for guest system to issue
// closeColorBuffer command when the color buffer is already
// garbage collected on the host. (we don't have a mechanism
// to give guest a notice yet)
return false;
}
+ ColorBufferRef& colorBufferRef = it->second;
// The guest can and will gralloc_alloc/gralloc_free and then
// gralloc_register a buffer, due to API level (O+) or
@@ -1545,19 +1541,20 @@
// So, we don't actually close the color buffer when refcount
// reached zero, unless it has been opened at least once already.
// Instead, put it on a 'delayed close' list to return to it later.
- if (--c->second.refcount == 0) {
+ if (--colorBufferRef.refcount == 0) {
if (forced) {
- eraseDelayedCloseColorBufferLocked(c->first, c->second.closedTs);
- m_colorbuffers.erase(c);
+ eraseDelayedCloseColorBufferLocked(colorBufferHandle, colorBufferRef.closedTs);
+ m_colorbuffers.erase(it);
deleted = true;
} else {
- c->second.closedTs = android::base::getUnixTimeUs();
- m_colorBufferDelayedCloseList.push_back({c->second.closedTs, p_colorbuffer});
+ colorBufferRef.closedTs = android::base::getUnixTimeUs();
+ m_colorBufferDelayedCloseList.push_back(
+ {colorBufferRef.closedTs, colorBufferHandle});
}
}
}
- performDelayedColorBufferCloseLocked(false);
+ performDelayedColorBufferCloseLocked(colorBuffersToCleanup, false);
return deleted;
}
@@ -1576,7 +1573,8 @@
}
}
-void FrameBuffer::performDelayedColorBufferCloseLocked(bool forced) {
+void FrameBuffer::performDelayedColorBufferCloseLocked(
+ std::vector<ColorBufferPtr>* colorBuffersToCleanup, bool forced) {
// Let's wait just long enough to make sure it's not because of instant
// timestamp change (end of previous second -> beginning of a next one),
// but not for long - this is a workaround for race conditions, and they
@@ -1590,9 +1588,11 @@
it->ts + kColorBufferClosingDelaySec <= now)) {
if (it->cbHandle != 0) {
AutoLock colorBufferMapLock(m_colorBufferMapLock);
- const auto& cb = m_colorbuffers.find(it->cbHandle);
- if (cb != m_colorbuffers.end()) {
- m_colorbuffers.erase(cb);
+ auto colorBufferIt = m_colorbuffers.find(it->cbHandle);
+ if (colorBufferIt != m_colorbuffers.end()) {
+ ColorBufferRef& colorBufferRef = colorBufferIt->second;
+ colorBuffersToCleanup->push_back(std::move(colorBufferRef.cb));
+ m_colorbuffers.erase(colorBufferIt);
}
}
++it;
@@ -1658,41 +1658,41 @@
android::base::sleepUs(10000);
} while (renderThreadWithThisPuidExists);
-
- AutoLock mutex(m_lock);
- if (!hasEmulationGl() || !getDisplay()) {
- return;
- }
-
- auto colorBuffersToCleanup = cleanupProcGLObjects_locked(puid);
-
- // Run other cleanup callbacks
- // Avoid deadlock by first storing a separate list of callbacks
+ std::vector<ColorBufferPtr> colorBuffersToCleanup;
std::vector<std::function<void()>> callbacks;
{
- auto procIte = m_procOwnedCleanupCallbacks.find(puid);
- if (procIte != m_procOwnedCleanupCallbacks.end()) {
- for (auto it : procIte->second) {
- callbacks.push_back(it.second);
+ AutoLock mutex(m_lock);
+ if (!hasEmulationGl() || !getDisplay()) {
+ return;
+ }
+
+ cleanupProcGLObjects_locked(puid, &colorBuffersToCleanup);
+
+ // Gather other cleanup callbacks.
+ {
+ auto procIte = m_procOwnedCleanupCallbacks.find(puid);
+ if (procIte != m_procOwnedCleanupCallbacks.end()) {
+ for (auto it : procIte->second) {
+ callbacks.push_back(it.second);
+ }
+ m_procOwnedCleanupCallbacks.erase(procIte);
}
- m_procOwnedCleanupCallbacks.erase(procIte);
}
}
- mutex.unlock();
+ // Avoid holding the global lock during potentially slow ColorBuffer destruction
+ colorBuffersToCleanup.clear();
- for (auto handle : colorBuffersToCleanup) {
- goldfish_vk::teardownVkColorBuffer(handle);
- }
-
+ // Avoid deadlock
for (auto cb : callbacks) {
cb();
}
}
-std::vector<HandleType> FrameBuffer::cleanupProcGLObjects_locked(uint64_t puid, bool forced) {
- std::vector<HandleType> colorBuffersToCleanup;
+void FrameBuffer::cleanupProcGLObjects_locked(uint64_t puid,
+ std::vector<ColorBufferPtr>* colorBuffersToCleanup,
+ bool forced) {
{
std::unique_ptr<RecursiveScopedContextBind> bind = nullptr;
if (m_emulationGl) {
@@ -1710,13 +1710,9 @@
}
if (!m_guestManagedColorBufferLifetime) {
if (m_refCountPipeEnabled) {
- if (decColorBufferRefCountLocked(w->second.second)) {
- colorBuffersToCleanup.push_back(w->second.second);
- }
+ decColorBufferRefCountLocked(w->second.second, colorBuffersToCleanup);
} else {
- if (closeColorBufferLocked(w->second.second, forced)) {
- colorBuffersToCleanup.push_back(w->second.second);
- }
+ closeColorBufferLocked(w->second.second, colorBuffersToCleanup, forced);
}
}
m_windows.erase(w);
@@ -1733,9 +1729,7 @@
auto procIte = m_procOwnedColorBuffers.find(puid);
if (procIte != m_procOwnedColorBuffers.end()) {
for (auto cb : procIte->second) {
- if (closeColorBufferLocked(cb, forced)) {
- colorBuffersToCleanup.push_back(cb);
- }
+ closeColorBufferLocked(cb, colorBuffersToCleanup, forced);
}
m_procOwnedColorBuffers.erase(procIte);
}
@@ -1764,8 +1758,6 @@
m_procOwnedEmulatedEglContexts.erase(procIte);
}
}
-
- return colorBuffersToCleanup;
}
void FrameBuffer::markOpened(ColorBufferRef* cbRef) {
@@ -1804,44 +1796,55 @@
bool FrameBuffer::setEmulatedEglWindowSurfaceColorBuffer(HandleType p_surface,
HandleType p_colorbuffer) {
+ std::vector<ColorBufferPtr> colorBuffersToCleanup;
+
AutoLock mutex(m_lock);
- EmulatedEglWindowSurfaceMap::iterator w(m_windows.find(p_surface));
- if (w == m_windows.end()) {
- // bad surface handle
- ERR("bad window surface handle %#x", p_surface);
+ auto surfaceIt = m_windows.find(p_surface);
+ if (surfaceIt == m_windows.end()) {
+ ERR("Failed to find window surface %#x", p_surface);
return false;
}
+ auto& surfaceAndBackingColorBuffer = surfaceIt->second;
{
AutoLock colorBufferMapLock(m_colorBufferMapLock);
- ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer));
- if (c == m_colorbuffers.end()) {
- ERR("bad color buffer handle %#x", p_colorbuffer);
- // bad colorbuffer handle
+
+ auto colorBufferIt = m_colorbuffers.find(p_colorbuffer);
+ if (colorBufferIt == m_colorbuffers.end()) {
+ ERR("Failed to find ColorBuffer:%#x", p_colorbuffer);
return false;
}
+ auto& colorBufferRef = colorBufferIt->second;
- (*w).second.first->setColorBuffer((*c).second.cb);
- markOpened(&c->second);
+ auto& surface = surfaceAndBackingColorBuffer.first;
+ surface->setColorBuffer(colorBufferRef.cb);
+
+ markOpened(&colorBufferRef);
+
if (!m_guestManagedColorBufferLifetime) {
- c->second.refcount++;
+ colorBufferRef.refcount++;
}
}
- if (w->second.second) {
+
+ auto previousBackingColorBuffer = surfaceAndBackingColorBuffer.second;
+ if (previousBackingColorBuffer) {
if (!m_guestManagedColorBufferLifetime) {
if (m_refCountPipeEnabled) {
- decColorBufferRefCountLocked(w->second.second);
+ decColorBufferRefCountLocked(previousBackingColorBuffer, &colorBuffersToCleanup);
} else {
- closeColorBufferLocked(w->second.second);
+ closeColorBufferLocked(previousBackingColorBuffer, &colorBuffersToCleanup);
}
}
}
- (*w).second.second = p_colorbuffer;
-
+ surfaceAndBackingColorBuffer.second = p_colorbuffer;
m_EmulatedEglWindowSurfaceToColorBuffer[p_surface] = p_colorbuffer;
+ // Avoid holding the global lock during potentially slow ColorBuffer
+ // destruction (during `colorBuffersToCleanup` destruction).
+ m_lock.unlock();
+
return true;
}
@@ -2488,7 +2491,8 @@
}
}
if (!m_subWin) { // m_subWin is supposed to be false
- decColorBufferRefCountLocked(p_colorbuffer);
+ std::vector<ColorBufferPtr> colorBuffersToCleanup;
+ decColorBufferRefCountLocked(p_colorbuffer, &colorBuffersToCleanup);
}
EXIT:
@@ -2747,17 +2751,22 @@
}
}
-bool FrameBuffer::decColorBufferRefCountLocked(HandleType p_colorbuffer) {
+void FrameBuffer::decColorBufferRefCountLocked(HandleType p_colorbuffer,
+ std::vector<ColorBufferPtr>* toDestroy) {
AutoLock colorBufferMapLock(m_colorBufferMapLock);
- const auto& it = m_colorbuffers.find(p_colorbuffer);
- if (it != m_colorbuffers.end()) {
- it->second.refcount -= 1;
- if (it->second.refcount == 0) {
- m_colorbuffers.erase(p_colorbuffer);
- return true;
- }
+
+ auto it = m_colorbuffers.find(p_colorbuffer);
+ if (it == m_colorbuffers.end()) {
+ return;
}
- return false;
+
+ ColorBufferRef& ref = it->second;
+
+ ref.refcount -= 1;
+ if (ref.refcount == 0) {
+ toDestroy->push_back(std::move(ref.cb));
+ m_colorbuffers.erase(it);
+ }
}
bool FrameBuffer::compose(uint32_t bufferSize, void* buffer, bool needPost) {
@@ -2995,31 +3004,23 @@
}
}
if (!cleanupComplete) {
- std::vector<HandleType> colorBuffersToCleanup;
+ std::vector<ColorBufferPtr> colorBuffersToCleanup;
while (m_procOwnedEmulatedEglWindowSurfaces.size()) {
- auto cleanupHandles = cleanupProcGLObjects_locked(
- m_procOwnedEmulatedEglWindowSurfaces.begin()->first, true);
- colorBuffersToCleanup.insert(colorBuffersToCleanup.end(),
- cleanupHandles.begin(), cleanupHandles.end());
+ cleanupProcGLObjects_locked(m_procOwnedEmulatedEglWindowSurfaces.begin()->first,
+ &colorBuffersToCleanup, true);
}
while (m_procOwnedColorBuffers.size()) {
- auto cleanupHandles = cleanupProcGLObjects_locked(
- m_procOwnedColorBuffers.begin()->first, true);
- colorBuffersToCleanup.insert(colorBuffersToCleanup.end(),
- cleanupHandles.begin(), cleanupHandles.end());
+ cleanupProcGLObjects_locked(m_procOwnedColorBuffers.begin()->first,
+ &colorBuffersToCleanup, true);
}
while (m_procOwnedEmulatedEglImages.size()) {
- auto cleanupHandles = cleanupProcGLObjects_locked(
- m_procOwnedEmulatedEglImages.begin()->first, true);
- colorBuffersToCleanup.insert(colorBuffersToCleanup.end(),
- cleanupHandles.begin(), cleanupHandles.end());
+ cleanupProcGLObjects_locked(m_procOwnedEmulatedEglImages.begin()->first,
+ &colorBuffersToCleanup, true);
}
while (m_procOwnedEmulatedEglContexts.size()) {
- auto cleanupHandles = cleanupProcGLObjects_locked(
- m_procOwnedEmulatedEglContexts.begin()->first, true);
- colorBuffersToCleanup.insert(colorBuffersToCleanup.end(),
- cleanupHandles.begin(), cleanupHandles.end());
+ cleanupProcGLObjects_locked(m_procOwnedEmulatedEglContexts.begin()->first,
+ &colorBuffersToCleanup, true);
}
std::vector<std::function<void()>> cleanupCallbacks;
@@ -3036,13 +3037,12 @@
m_procOwnedResources.clear();
- performDelayedColorBufferCloseLocked(true);
+ performDelayedColorBufferCloseLocked(&colorBuffersToCleanup, true);
lock.unlock();
- for (auto colorBufferHandle : colorBuffersToCleanup) {
- goldfish_vk::teardownVkColorBuffer(colorBufferHandle);
- }
+ // Avoid holding the global lock during potentially slow ColorBuffer destruction.
+ colorBuffersToCleanup.clear();
for (auto cb : cleanupCallbacks) {
cb();
@@ -3320,15 +3320,17 @@
}
void FrameBuffer::sweepColorBuffersLocked() {
+ std::vector<ColorBufferPtr> colorBuffersToDestroy;
+
HandleType handleToDestroy;
while (mOutstandingColorBufferDestroys.tryReceive(&handleToDestroy)) {
- bool needCleanup = decColorBufferRefCountLocked(handleToDestroy);
- if (needCleanup) {
- m_lock.unlock();
- goldfish_vk::teardownVkColorBuffer(handleToDestroy);
- m_lock.lock();
- }
+ decColorBufferRefCountLocked(handleToDestroy, &colorBuffersToDestroy);
}
+
+ // Avoid holding the global lock during potentially slow destruction.
+ m_lock.unlock();
+ colorBuffersToDestroy.clear();
+ m_lock.lock();
}
std::future<void> FrameBuffer::blockPostWorker(std::future<void> continueSignal) {
diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h
index 563a6c3..9952621 100644
--- a/stream-servers/FrameBuffer.h
+++ b/stream-servers/FrameBuffer.h
@@ -218,8 +218,10 @@
// handle value as returned by createEmulatedEglWindowSurface().
void destroyEmulatedEglWindowSurface(HandleType p_surface);
- // Returns the set of ColorBuffers destroyed (for further cleanup)
- std::vector<HandleType> destroyEmulatedEglWindowSurfaceLocked(HandleType p_surface);
+ // Destroy a given EmulatedEglWindowSurface instance and moves any references to
+ // backing ColorBuffers to the `toDestroy`.
+ void destroyEmulatedEglWindowSurfaceLocked(HandleType p_surface,
+ std::vector<ColorBufferPtr>* toDestroy);
void createEmulatedEglFenceSync(EGLenum type,
int destroyWhenSignaled,
@@ -294,6 +296,8 @@
std::unique_ptr<ProcessResources> removeGraphicsProcessResources(uint64_t puid);
// TODO(kaiyili): retire cleanupProcGLObjects in favor of removeGraphicsProcessResources.
void cleanupProcGLObjects(uint64_t puid);
+ void cleanupProcGLObjects_locked(uint64_t puid, std::vector<ColorBufferPtr>* toDestroy,
+ bool forced = false);
// Equivalent for eglMakeCurrent() for the current display.
// |p_context|, |p_drawSurface| and |p_readSurface| are the handle values
@@ -671,21 +675,22 @@
HandleType genHandle_locked();
bool removeSubWindow_locked();
- // Returns the set of ColorBuffers destroyed (for further cleanup)
- std::vector<HandleType> cleanupProcGLObjects_locked(uint64_t puid,
- bool forced = false);
void markOpened(ColorBufferRef* cbRef);
// Returns true if the color buffer was erased.
- bool closeColorBufferLocked(HandleType p_colorbuffer, bool forced = false);
- // Returns true if this was the last ref and we need to destroy stuff.
- bool decColorBufferRefCountLocked(HandleType p_colorbuffer);
+ bool closeColorBufferLocked(HandleType p_colorbuffer, std::vector<ColorBufferPtr>* toDestroy,
+ bool forced = false);
+ // Decrements the color buffer's reference count and adds the color buffer to the given
+ // `toDestroy` list if this was the last reference to the color buffer.
+ void decColorBufferRefCountLocked(HandleType p_colorbuffer,
+ std::vector<ColorBufferPtr>* toDestroy);
// Decrease refcount but not destroy the object.
// Mainly used in post thread, when we need to destroy the object but cannot in post thread.
void decColorBufferRefCountNoDestroy(HandleType p_colorbuffer);
// Close all expired color buffers for real.
// Treat all delayed color buffers as expired if forced=true
- void performDelayedColorBufferCloseLocked(bool forced = false);
+ void performDelayedColorBufferCloseLocked(std::vector<ColorBufferPtr>* toDestroy,
+ bool forced = false);
void eraseDelayedCloseColorBufferLocked(HandleType cb, uint64_t ts);
AsyncResult postImpl(HandleType p_colorbuffer, Post::CompletionCallback callback,