diff --git a/src/gpu/ganesh/SurfaceContext.cpp b/src/gpu/ganesh/SurfaceContext.cpp index c6fa47fbca3..02c51c97404 100644 --- a/src/gpu/ganesh/SurfaceContext.cpp +++ b/src/gpu/ganesh/SurfaceContext.cpp @@ -58,6 +58,7 @@ #include #include +#include #include #include @@ -1386,6 +1387,20 @@ SurfaceContext::PixelTransferResult SurfaceContext::transferPixels(GrColorType d if (!buffer) { return {}; } + // GrTransferFromRenderTask::onExecute() can fail silently (its bool return + // is discarded by GrDrawingManager) and the entire executeRenderTasks() + // pass is skipped if GrResourceAllocator::assign() fails for *any* proxy in + // the flush. In both cases the finished-proc still fires and this buffer is + // mapped and handed to the client. fBuffersAreInitiallyZero is false on + // Vk/GL and clearToZero() refuses kXferGpuToCpu buffers, so map+memset here + // to prevent stale GPU-process bytes (e.g. another origin's prior readback + // in a shared VMA sub-allocation) from being disclosed when that happens. + if (!this->caps()->buffersAreInitiallyZero()) { + if (void* p = buffer->map()) { + std::memset(p, 0, size); + buffer->unmap(); + } + } auto srcRect = rect; bool flip = this->origin() == kBottomLeft_GrSurfaceOrigin; if (flip) {