Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release
[gecko.git] / gfx / webrender_bindings / RenderCompositor.cpp
blob1712eca855f957d974b0ca873cd9c8388574f9ac
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "RenderCompositor.h"
9 #include "gfxConfig.h"
10 #include "gfxPlatform.h"
11 #include "GLContext.h"
12 #include "mozilla/StaticPrefs_gfx.h"
13 #include "mozilla/gfx/Logging.h"
14 #include "mozilla/gfx/gfxVars.h"
15 #include "mozilla/layers/SyncObject.h"
16 #include "mozilla/webrender/RenderCompositorLayersSWGL.h"
17 #include "mozilla/webrender/RenderCompositorOGL.h"
18 #include "mozilla/webrender/RenderCompositorSWGL.h"
19 #include "mozilla/widget/CompositorWidget.h"
21 #ifdef XP_WIN
22 # include "mozilla/webrender/RenderCompositorANGLE.h"
23 # include "mozilla/widget/WinCompositorWidget.h"
24 #endif
26 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
27 # include "mozilla/webrender/RenderCompositorEGL.h"
28 #endif
30 #ifdef MOZ_WAYLAND
31 # include "mozilla/webrender/RenderCompositorNative.h"
32 #endif
34 #ifdef XP_DARWIN
35 # include "mozilla/webrender/RenderCompositorNative.h"
36 #endif
38 namespace mozilla::wr {
40 void wr_compositor_add_surface(void* aCompositor, wr::NativeSurfaceId aId,
41 const wr::CompositorSurfaceTransform* aTransform,
42 wr::DeviceIntRect aClipRect,
43 wr::ImageRendering aImageRendering) {
44 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
45 compositor->AddSurface(aId, *aTransform, aClipRect, aImageRendering);
48 void wr_compositor_begin_frame(void* aCompositor) {
49 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
50 compositor->CompositorBeginFrame();
53 void wr_compositor_bind(void* aCompositor, wr::NativeTileId aId,
54 wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
55 wr::DeviceIntRect aDirtyRect,
56 wr::DeviceIntRect aValidRect) {
57 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
58 compositor->Bind(aId, aOffset, aFboId, aDirtyRect, aValidRect);
61 void wr_compositor_create_surface(void* aCompositor, wr::NativeSurfaceId aId,
62 wr::DeviceIntPoint aVirtualOffset,
63 wr::DeviceIntSize aTileSize, bool aIsOpaque) {
64 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
65 compositor->CreateSurface(aId, aVirtualOffset, aTileSize, aIsOpaque);
68 void wr_compositor_create_external_surface(void* aCompositor,
69 wr::NativeSurfaceId aId,
70 bool aIsOpaque) {
71 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
72 compositor->CreateExternalSurface(aId, aIsOpaque);
75 void wr_compositor_create_backdrop_surface(void* aCompositor,
76 wr::NativeSurfaceId aId,
77 wr::ColorF aColor) {
78 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
79 compositor->CreateBackdropSurface(aId, aColor);
82 void wr_compositor_create_tile(void* aCompositor, wr::NativeSurfaceId aId,
83 int32_t aX, int32_t aY) {
84 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
85 compositor->CreateTile(aId, aX, aY);
88 void wr_compositor_destroy_tile(void* aCompositor, wr::NativeSurfaceId aId,
89 int32_t aX, int32_t aY) {
90 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
91 compositor->DestroyTile(aId, aX, aY);
94 void wr_compositor_destroy_surface(void* aCompositor, NativeSurfaceId aId) {
95 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
96 compositor->DestroySurface(aId);
99 void wr_compositor_attach_external_image(void* aCompositor,
100 wr::NativeSurfaceId aId,
101 wr::ExternalImageId aExternalImage) {
102 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
103 compositor->AttachExternalImage(aId, aExternalImage);
106 void wr_compositor_start_compositing(void* aCompositor, wr::ColorF aClearColor,
107 const wr::DeviceIntRect* aDirtyRects,
108 size_t aNumDirtyRects,
109 const wr::DeviceIntRect* aOpaqueRects,
110 size_t aNumOpaqueRects) {
111 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
112 compositor->StartCompositing(aClearColor, aDirtyRects, aNumDirtyRects,
113 aOpaqueRects, aNumOpaqueRects);
116 void wr_compositor_end_frame(void* aCompositor) {
117 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
118 compositor->CompositorEndFrame();
121 void wr_compositor_enable_native_compositor(void* aCompositor, bool aEnable) {
122 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
123 compositor->EnableNativeCompositor(aEnable);
126 void wr_compositor_get_capabilities(void* aCompositor,
127 CompositorCapabilities* aCaps) {
128 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
129 compositor->GetCompositorCapabilities(aCaps);
132 void wr_compositor_get_window_visibility(void* aCompositor,
133 WindowVisibility* aVisibility) {
134 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
135 compositor->GetWindowVisibility(aVisibility);
138 void wr_compositor_unbind(void* aCompositor) {
139 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
140 compositor->Unbind();
143 void wr_compositor_deinit(void* aCompositor) {
144 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
145 compositor->DeInit();
148 void wr_compositor_map_tile(void* aCompositor, wr::NativeTileId aId,
149 wr::DeviceIntRect aDirtyRect,
150 wr::DeviceIntRect aValidRect, void** aData,
151 int32_t* aStride) {
152 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
153 compositor->MapTile(aId, aDirtyRect, aValidRect, aData, aStride);
156 void wr_compositor_unmap_tile(void* aCompositor) {
157 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
158 compositor->UnmapTile();
161 void wr_partial_present_compositor_set_buffer_damage_region(
162 void* aCompositor, const wr::DeviceIntRect* aRects, size_t aNRects) {
163 RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
164 compositor->SetBufferDamageRegion(aRects, aNRects);
167 /* static */
168 UniquePtr<RenderCompositor> RenderCompositor::Create(
169 const RefPtr<widget::CompositorWidget>& aWidget, nsACString& aError) {
170 if (aWidget->GetCompositorOptions().UseSoftwareWebRender()) {
171 #ifdef XP_DARWIN
172 // Mac uses NativeLayerCA
173 if (!gfxPlatform::IsHeadless()) {
174 return RenderCompositorNativeSWGL::Create(aWidget, aError);
176 #elif defined(MOZ_WAYLAND)
177 if (gfx::gfxVars::UseWebRenderCompositor()) {
178 return RenderCompositorNativeSWGL::Create(aWidget, aError);
180 #endif
181 UniquePtr<RenderCompositor> comp =
182 RenderCompositorLayersSWGL::Create(aWidget, aError);
183 if (comp) {
184 return comp;
186 #if defined(MOZ_WIDGET_ANDROID)
187 // On Android, we do not want to fallback from RenderCompositorOGLSWGL to
188 // RenderCompositorSWGL.
189 if (aWidget->GetCompositorOptions().AllowSoftwareWebRenderOGL()) {
190 return nullptr;
192 #endif
193 return RenderCompositorSWGL::Create(aWidget, aError);
196 #ifdef XP_WIN
197 if (gfx::gfxVars::UseWebRenderANGLE()) {
198 return RenderCompositorANGLE::Create(aWidget, aError);
200 #endif
202 #if defined(MOZ_WAYLAND)
203 if (gfx::gfxVars::UseWebRenderCompositor()) {
204 return RenderCompositorNativeOGL::Create(aWidget, aError);
206 #endif
208 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
209 UniquePtr<RenderCompositor> eglCompositor =
210 RenderCompositorEGL::Create(aWidget, aError);
211 if (eglCompositor) {
212 return eglCompositor;
214 #endif
216 #if defined(MOZ_WIDGET_ANDROID)
217 // RenderCompositorOGL is not used on android
218 return nullptr;
219 #elif defined(XP_DARWIN)
220 // Mac uses NativeLayerCA
221 return RenderCompositorNativeOGL::Create(aWidget, aError);
222 #else
223 return RenderCompositorOGL::Create(aWidget, aError);
224 #endif
227 RenderCompositor::RenderCompositor(
228 const RefPtr<widget::CompositorWidget>& aWidget)
229 : mWidget(aWidget) {}
231 RenderCompositor::~RenderCompositor() = default;
233 bool RenderCompositor::MakeCurrent() { return gl()->MakeCurrent(); }
235 void RenderCompositor::GetCompositorCapabilities(
236 CompositorCapabilities* aCaps) {
237 if (StaticPrefs::gfx_webrender_compositor_max_update_rects_AtStartup() > 0) {
238 aCaps->max_update_rects = 1;
239 } else {
240 aCaps->max_update_rects = 0;
244 void RenderCompositor::GetWindowVisibility(WindowVisibility* aVisibility) {
245 #ifdef XP_WIN
246 auto* widget = mWidget->AsWindows();
247 if (!widget) {
248 return;
250 aVisibility->size_mode = ToWrWindowSizeMode(widget->GetWindowSizeMode());
251 aVisibility->is_fully_occluded = widget->GetWindowIsFullyOccluded();
252 #endif
255 GLenum RenderCompositor::IsContextLost(bool aForce) {
256 auto* glc = gl();
257 // GetGraphicsResetStatus may trigger an implicit MakeCurrent if robustness
258 // is not supported, so unless we are forcing, pass on the check.
259 if (!glc || (!aForce && !glc->IsSupported(gl::GLFeature::robustness))) {
260 return LOCAL_GL_NO_ERROR;
262 auto resetStatus = glc->fGetGraphicsResetStatus();
263 switch (resetStatus) {
264 case LOCAL_GL_NO_ERROR:
265 break;
266 case LOCAL_GL_INNOCENT_CONTEXT_RESET_ARB:
267 NS_WARNING("Device reset due to system / different context");
268 break;
269 case LOCAL_GL_PURGED_CONTEXT_RESET_NV:
270 NS_WARNING("Device reset due to NV video memory purged");
271 break;
272 case LOCAL_GL_GUILTY_CONTEXT_RESET_ARB:
273 gfxCriticalError() << "Device reset due to WR context";
274 break;
275 case LOCAL_GL_UNKNOWN_CONTEXT_RESET_ARB:
276 gfxCriticalNote << "Device reset may be due to WR context";
277 break;
278 default:
279 gfxCriticalError() << "Device reset with WR context unexpected status: "
280 << gfx::hexa(resetStatus);
281 break;
283 return resetStatus;
286 } // namespace mozilla::wr