forked from mirrors/gecko-dev
		
	 2cf59fe695
			
		
	
	
		2cf59fe695
		
	
	
	
	
		
			
			In bug 1762424 we introduced a rendering path on Android using the SurfaceControl API, in order to work around a bug preventing recovery from a GPU process crash. However, the initial implementation caused this bug: repeatedly sending the same SurfaceControl objects over AIDL to the GPU process resulted in them being leaked, eventually causing severe display issues. Not only were we duplicating the SurfaceControl for each widget, but each time a widget was resized too. This patch reworks our usage of the SurfaceControl API to avoid ever having to send them cross-process. Instead, we create a single child SurfaceControl object for each SurfaceControl that is attached to a widget. (Typically there will be a single one shared between all widgets, changing only when the app is paused and resumed, which is much fewer than one per widget per resize.) In the parent process we obtain the Surfaces that will be rendered in to from the child SurfaceControls, and only send those Surfaces to the GPU process. Thankfully unlike SurfaceControls, sending Surfaces cross-process does not cause leaks. When the GPU process dies we simply destroy all of the child SurfaceControls, and recreate them again on-demand. Differential Revision: https://phabricator.services.mozilla.com/D147437
		
			
				
	
	
		
			57 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			57 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "HeadlessCompositorWidget.h"
 | |
| #include "HeadlessWidget.h"
 | |
| #include "mozilla/widget/PlatformWidgetTypes.h"
 | |
| 
 | |
| #include "InProcessAndroidCompositorWidget.h"
 | |
| #include "nsWindow.h"
 | |
| 
 | |
| namespace mozilla {
 | |
| namespace widget {
 | |
| 
 | |
| /* static */
 | |
| RefPtr<CompositorWidget> CompositorWidget::CreateLocal(
 | |
|     const CompositorWidgetInitData& aInitData,
 | |
|     const layers::CompositorOptions& aOptions, nsIWidget* aWidget) {
 | |
|   if (aInitData.type() ==
 | |
|       CompositorWidgetInitData::THeadlessCompositorWidgetInitData) {
 | |
|     return new HeadlessCompositorWidget(
 | |
|         aInitData.get_HeadlessCompositorWidgetInitData(), aOptions,
 | |
|         static_cast<HeadlessWidget*>(aWidget));
 | |
|   } else {
 | |
|     return new InProcessAndroidCompositorWidget(
 | |
|         aInitData.get_AndroidCompositorWidgetInitData(), aOptions,
 | |
|         static_cast<nsWindow*>(aWidget));
 | |
|   }
 | |
| }
 | |
| 
 | |
| InProcessAndroidCompositorWidget::InProcessAndroidCompositorWidget(
 | |
|     const AndroidCompositorWidgetInitData& aInitData,
 | |
|     const layers::CompositorOptions& aOptions, nsWindow* aWindow)
 | |
|     : AndroidCompositorWidget(aInitData, aOptions), mWindow(aWindow) {}
 | |
| 
 | |
| void InProcessAndroidCompositorWidget::ObserveVsync(VsyncObserver* aObserver) {
 | |
|   if (RefPtr<CompositorVsyncDispatcher> cvd =
 | |
|           mWindow->GetCompositorVsyncDispatcher()) {
 | |
|     cvd->SetCompositorVsyncObserver(aObserver);
 | |
|   }
 | |
| }
 | |
| 
 | |
| nsIWidget* InProcessAndroidCompositorWidget::RealWidget() { return mWindow; }
 | |
| 
 | |
| void InProcessAndroidCompositorWidget::OnCompositorSurfaceChanged() {
 | |
|   mSurface = java::sdk::Surface::Ref::From(
 | |
|       static_cast<jobject>(mWindow->GetNativeData(NS_JAVA_SURFACE)));
 | |
| }
 | |
| 
 | |
| void InProcessAndroidCompositorWidget::NotifyClientSizeChanged(
 | |
|     const LayoutDeviceIntSize& aClientSize) {
 | |
|   AndroidCompositorWidget::NotifyClientSizeChanged(aClientSize);
 | |
| }
 | |
| 
 | |
| }  // namespace widget
 | |
| }  // namespace mozilla
 |