1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #include "InProcessCompositorWidget.h"
6 
7 #include "mozilla/VsyncDispatcher.h"
8 #include "nsBaseWidget.h"
9 
10 #if defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
11 #  include "mozilla/widget/AndroidCompositorWidget.h"
12 #endif
13 
14 namespace mozilla {
15 namespace widget {
16 
17 // Platforms with no OOP compositor process support use
18 // InProcessCompositorWidget by default.
19 #if !defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
20 /* static */
CreateLocal(const CompositorWidgetInitData & aInitData,const layers::CompositorOptions & aOptions,nsIWidget * aWidget)21 RefPtr<CompositorWidget> CompositorWidget::CreateLocal(
22     const CompositorWidgetInitData& aInitData,
23     const layers::CompositorOptions& aOptions, nsIWidget* aWidget) {
24   // We're getting crashes from storing a NULL mWidget, and this is the
25   // only remaining explanation that doesn't involve memory corruption,
26   // so placing a release assert here. For even more sanity-checking, we
27   // do it after the static_cast.
28   nsBaseWidget* widget = static_cast<nsBaseWidget*>(aWidget);
29   MOZ_RELEASE_ASSERT(widget);
30 #  ifdef MOZ_WIDGET_ANDROID
31   return new AndroidCompositorWidget(aOptions, widget);
32 #  else
33   return new InProcessCompositorWidget(aOptions, widget);
34 #  endif
35 }
36 #endif
37 
InProcessCompositorWidget(const layers::CompositorOptions & aOptions,nsBaseWidget * aWidget)38 InProcessCompositorWidget::InProcessCompositorWidget(
39     const layers::CompositorOptions& aOptions, nsBaseWidget* aWidget)
40     : CompositorWidget(aOptions),
41       mWidget(aWidget),
42       mCanary(CANARY_VALUE),
43       mWidgetSanity(aWidget) {
44   // The only method of construction that is used outside of unit tests is
45   // ::CreateLocal, above. That method of construction asserts that mWidget
46   // is not assigned a NULL value. And yet mWidget is NULL in some crash
47   // reports that involve other class methods. Adding a release assert here
48   // will give us the earliest possible notification that we're headed for
49   // a crash.
50   MOZ_RELEASE_ASSERT(mWidget);
51 }
52 
PreRender(WidgetRenderingContext * aContext)53 bool InProcessCompositorWidget::PreRender(WidgetRenderingContext* aContext) {
54   CheckWidgetSanity();
55   return mWidget->PreRender(aContext);
56 }
57 
PostRender(WidgetRenderingContext * aContext)58 void InProcessCompositorWidget::PostRender(WidgetRenderingContext* aContext) {
59   CheckWidgetSanity();
60   mWidget->PostRender(aContext);
61 }
62 
63 RefPtr<layers::NativeLayerRoot>
GetNativeLayerRoot()64 InProcessCompositorWidget::GetNativeLayerRoot() {
65   CheckWidgetSanity();
66   return mWidget->GetNativeLayerRoot();
67 }
68 
69 already_AddRefed<gfx::DrawTarget>
StartRemoteDrawing()70 InProcessCompositorWidget::StartRemoteDrawing() {
71   CheckWidgetSanity();
72   return mWidget->StartRemoteDrawing();
73 }
74 
75 already_AddRefed<gfx::DrawTarget>
StartRemoteDrawingInRegion(const LayoutDeviceIntRegion & aInvalidRegion,layers::BufferMode * aBufferMode)76 InProcessCompositorWidget::StartRemoteDrawingInRegion(
77     const LayoutDeviceIntRegion& aInvalidRegion,
78     layers::BufferMode* aBufferMode) {
79   CheckWidgetSanity();
80   return mWidget->StartRemoteDrawingInRegion(aInvalidRegion, aBufferMode);
81 }
82 
EndRemoteDrawing()83 void InProcessCompositorWidget::EndRemoteDrawing() {
84   CheckWidgetSanity();
85   mWidget->EndRemoteDrawing();
86 }
87 
EndRemoteDrawingInRegion(gfx::DrawTarget * aDrawTarget,const LayoutDeviceIntRegion & aInvalidRegion)88 void InProcessCompositorWidget::EndRemoteDrawingInRegion(
89     gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
90   CheckWidgetSanity();
91   mWidget->EndRemoteDrawingInRegion(aDrawTarget, aInvalidRegion);
92 }
93 
CleanupRemoteDrawing()94 void InProcessCompositorWidget::CleanupRemoteDrawing() {
95   CheckWidgetSanity();
96   mWidget->CleanupRemoteDrawing();
97 }
98 
CleanupWindowEffects()99 void InProcessCompositorWidget::CleanupWindowEffects() {
100   CheckWidgetSanity();
101   mWidget->CleanupWindowEffects();
102 }
103 
InitCompositor(layers::Compositor * aCompositor)104 bool InProcessCompositorWidget::InitCompositor(
105     layers::Compositor* aCompositor) {
106   CheckWidgetSanity();
107   return mWidget->InitCompositor(aCompositor);
108 }
109 
GetClientSize()110 LayoutDeviceIntSize InProcessCompositorWidget::GetClientSize() {
111   CheckWidgetSanity();
112   return mWidget->GetClientSize();
113 }
114 
GetGLFrameBufferFormat()115 uint32_t InProcessCompositorWidget::GetGLFrameBufferFormat() {
116   CheckWidgetSanity();
117   return mWidget->GetGLFrameBufferFormat();
118 }
119 
GetWidgetKey()120 uintptr_t InProcessCompositorWidget::GetWidgetKey() {
121   CheckWidgetSanity();
122   return reinterpret_cast<uintptr_t>(mWidget);
123 }
124 
RealWidget()125 nsIWidget* InProcessCompositorWidget::RealWidget() { return mWidget; }
126 
ObserveVsync(VsyncObserver * aObserver)127 void InProcessCompositorWidget::ObserveVsync(VsyncObserver* aObserver) {
128   CheckWidgetSanity();
129   if (RefPtr<CompositorVsyncDispatcher> cvd =
130           mWidget->GetCompositorVsyncDispatcher()) {
131     cvd->SetCompositorVsyncObserver(aObserver);
132   }
133 }
134 
135 const char* InProcessCompositorWidget::CANARY_VALUE =
136     reinterpret_cast<char*>(0x1a1a1a1a);
137 
CheckWidgetSanity()138 void InProcessCompositorWidget::CheckWidgetSanity() {
139   MOZ_RELEASE_ASSERT(mWidgetSanity == mWidget);
140   MOZ_RELEASE_ASSERT(mCanary == CANARY_VALUE);
141 }
142 
143 }  // namespace widget
144 }  // namespace mozilla
145