void GPUProcessHost::Shutdown() { MOZ_ASSERT(!mShutdownRequested); mListener = nullptr; if (mGPUChild) { // OnChannelClosed uses this to check if the shutdown was expected or // unexpected. mShutdownRequested = true; #ifdef NS_FREE_PERMANENT_DATA // The channel might already be closed if we got here unexpectedly. if (!mChannelClosed) { mGPUChild->Close(); } #else // No need to communicate shutdown, the GPU process doesn't need to // communicate anything back. KillHard("NormalShutdown"); #endif // If we're shutting down unexpectedly, we're in the middle of handling an // ActorDestroy for PGPUChild, which is still on the stack. We'll return // back to OnChannelClosed. // // Otherwise, we'll wait for OnChannelClose to be called whenever PGPUChild // acknowledges shutdown. return; } DestroyProcess(); }
void GPUProcessManager::OnProcessDeviceReset(GPUProcessHost* aHost) { // Detect whether the device is resetting too quickly or too much // indicating that we should give up and use software mDeviceResetCount++; auto newTime = TimeStamp::Now(); auto delta = (int32_t)(newTime - mDeviceResetLastTime).ToMilliseconds(); mDeviceResetLastTime = newTime; if (ShouldLimitDeviceResets(mDeviceResetCount, delta)) { DestroyProcess(); DisableGPUProcess("GPU processed experienced too many device resets"); HandleProcessLost(); return; } RebuildRemoteSessions(); for (const auto& listener : mListeners) { listener->OnCompositorDeviceReset(); } }
void GPUProcessHost::OnChannelClosed() { if (!mShutdownRequested) { // This is an unclean shutdown. Notify our listener that we're going away. mChannelClosed = true; if (mListener) { mListener->OnProcessUnexpectedShutdown(this); } } // Release the actor. GPUChild::Destroy(Move(mGPUChild)); MOZ_ASSERT(!mGPUChild); // If the owner of GPUProcessHost already requested shutdown, we can now // schedule destruction. Otherwise we must wait for someone to call // Shutdown. Note that GPUProcessManager calls Shutdown within // OnProcessUnexpectedShutdown. if (mShutdownRequested) { DestroyProcess(); } }
void GPUProcessManager::OnProcessUnexpectedShutdown(GPUProcessHost* aHost) { MOZ_ASSERT(mProcess && mProcess == aHost); DestroyProcess(); if (mNumProcessAttempts > uint32_t(gfxPrefs::GPUProcessMaxRestarts())) { char disableMessage[64]; SprintfLiteral(disableMessage, "GPU process disabled after %d attempts", mNumProcessAttempts); DisableGPUProcess(disableMessage); } else if (mNumProcessAttempts > uint32_t(gfxPrefs::GPUProcessMaxRestartsWithDecoder()) && mDecodeVideoOnGpuProcess) { mDecodeVideoOnGpuProcess = false; Telemetry::Accumulate(Telemetry::GPU_PROCESS_CRASH_FALLBACKS, uint32_t(FallbackType::DECODINGDISABLED)); } else { Telemetry::Accumulate(Telemetry::GPU_PROCESS_CRASH_FALLBACKS, uint32_t(FallbackType::NONE)); } HandleProcessLost(); }
void GPUProcessManager::CleanShutdown() { DestroyProcess(); mVsyncIOThread = nullptr; }