Bug 1591752 - FFI for WebRender OS compositor integration: Create WrCompositor struct which implements the webrender::Compositor trait and calls through to virtual methods on RenderCompositor. r=sotaro

This patch was largely written by Sotaro.

This patch also adds an off-by-default pref gfx.webrender.compositor that currently does nothing.

Differential Revision: https://phabricator.services.mozilla.com/D50721

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Markus Stange 2019-10-27 01:18:27 +00:00
Родитель 7a894386f2
Коммит 8785168981
7 изменённых файлов: 208 добавлений и 19 удалений

Просмотреть файл

@ -23,6 +23,45 @@
namespace mozilla {
namespace wr {
void wr_compositor_add_surface(void* aCompositor, wr::NativeSurfaceId aId,
wr::DeviceIntPoint aPosition,
wr::DeviceIntRect aClipRect) {
RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
compositor->AddSurface(aId, aPosition, aClipRect);
}
void wr_compositor_begin_frame(void* aCompositor) {
RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
compositor->CompositorBeginFrame();
}
void wr_compositor_bind(void* aCompositor, wr::NativeSurfaceId aId,
wr::DeviceIntPoint* aOffset) {
RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
compositor->Bind(aId, aOffset);
}
void wr_compositor_create_surface(void* aCompositor, wr::NativeSurfaceId aId,
wr::DeviceIntSize aSize) {
RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
compositor->CreateSurface(aId, aSize);
}
void wr_compositor_destroy_surface(void* aCompositor, NativeSurfaceId aId) {
RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
compositor->DestroySurface(aId);
}
void wr_compositor_end_frame(void* aCompositor) {
RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
compositor->CompositorEndFrame();
}
void wr_compositor_unbind(void* aCompositor) {
RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
compositor->Unbind();
}
/* static */
UniquePtr<RenderCompositor> RenderCompositor::Create(
RefPtr<widget::CompositorWidget>&& aWidget) {

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "Units.h"
namespace mozilla {
@ -62,6 +63,21 @@ class RenderCompositor {
virtual bool IsContextLost();
virtual bool ShouldUseNativeCompositor() { return false; }
// Interface for wr::Compositor
virtual void CompositorBeginFrame() {}
virtual void CompositorEndFrame() {}
virtual void Bind(wr::NativeSurfaceId aId, wr::DeviceIntPoint* aOffset) {}
virtual void Unbind() {}
virtual void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntSize aSize) {
}
virtual void DestroySurface(NativeSurfaceId aId) {}
virtual void AddSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aPosition,
wr::DeviceIntRect aClipRect) {}
void wr_compositor_unbind(void* aCompositor) {}
protected:
RefPtr<widget::CompositorWidget> mWidget;
RefPtr<layers::SyncObjectHost> mSyncObject;

Просмотреть файл

@ -75,26 +75,28 @@ class NewRenderer : public RendererEvent {
bool supportLowPriorityTransactions = isMainWindow;
bool supportPictureCaching = isMainWindow;
wr::Renderer* wrRenderer = nullptr;
if (!wr_window_new(aWindowId, mSize.width, mSize.height,
supportLowPriorityTransactions, allow_texture_swizzling,
StaticPrefs::gfx_webrender_picture_caching() &&
supportPictureCaching,
if (!wr_window_new(
aWindowId, mSize.width, mSize.height,
supportLowPriorityTransactions, allow_texture_swizzling,
StaticPrefs::gfx_webrender_picture_caching() &&
supportPictureCaching,
#ifdef NIGHTLY_BUILD
StaticPrefs::gfx_webrender_start_debug_server(),
StaticPrefs::gfx_webrender_start_debug_server(),
#else
false,
false,
#endif
compositor->gl(),
aRenderThread.GetProgramCache()
? aRenderThread.GetProgramCache()->Raw()
: nullptr,
aRenderThread.GetShaders()
? aRenderThread.GetShaders()->RawShaders()
: nullptr,
aRenderThread.ThreadPool().Raw(), &WebRenderMallocSizeOf,
&WebRenderMallocEnclosingSizeOf,
(uint32_t)wr::RenderRoot::Default, mDocHandle,
&wrRenderer, mMaxTextureSize)) {
compositor->gl(),
aRenderThread.GetProgramCache()
? aRenderThread.GetProgramCache()->Raw()
: nullptr,
aRenderThread.GetShaders()
? aRenderThread.GetShaders()->RawShaders()
: nullptr,
aRenderThread.ThreadPool().Raw(), &WebRenderMallocSizeOf,
&WebRenderMallocEnclosingSizeOf, (uint32_t)wr::RenderRoot::Default,
compositor->ShouldUseNativeCompositor() ? compositor.get()
: nullptr,
mDocHandle, &wrRenderer, mMaxTextureSize)) {
// wr_window_new puts a message into gfxCriticalNote if it returns false
return;
}

Просмотреть файл

@ -225,6 +225,10 @@ struct ImageDescriptor : public wr::WrImageDescriptor {
}
};
inline uint64_t AsUint64(const NativeSurfaceId& aId) {
return static_cast<uint64_t>(aId._0);
}
// Whenever possible, use wr::WindowId instead of manipulating uint64_t.
inline uint64_t AsUint64(const WindowId& aId) {
return static_cast<uint64_t>(aId.mHandle);

Просмотреть файл

@ -22,8 +22,8 @@ use gleam::gl;
use webrender::{
api::*, api::units::*, ApiRecordingReceiver, AsyncPropertySampler, AsyncScreenshotHandle,
BinaryRecorder, DebugFlags, Device, ExternalImage, ExternalImageHandler, ExternalImageSource,
PipelineInfo, ProfilerHooks, RecordedFrameHandle, Renderer, RendererOptions, RendererStats,
BinaryRecorder, Compositor, DebugFlags, Device, ExternalImage, ExternalImageHandler, ExternalImageSource,
NativeSurfaceId, PipelineInfo, ProfilerHooks, RecordedFrameHandle, Renderer, RendererOptions, RendererStats,
SceneBuilderHooks, ShaderPrecacheFlags, Shaders, ThreadListener, UploadMethod, VertexUsageHint,
WrShaders, set_profiler_hooks,
};
@ -1135,6 +1135,120 @@ fn wr_device_new(gl_context: *mut c_void, pc: Option<&mut WrProgramCache>)
Device::new(gl, resource_override_path, upload_method, cached_programs, false, true, true, None)
}
extern "C" {
fn wr_compositor_create_surface(
compositor: *mut c_void,
id: NativeSurfaceId,
size: DeviceIntSize,
);
fn wr_compositor_destroy_surface(
compositor: *mut c_void,
id: NativeSurfaceId,
);
fn wr_compositor_bind(
compositor: *mut c_void,
id: NativeSurfaceId,
offset: &mut DeviceIntPoint,
);
fn wr_compositor_unbind(compositor: *mut c_void);
fn wr_compositor_begin_frame(compositor: *mut c_void);
fn wr_compositor_add_surface(
compositor: *mut c_void,
id: NativeSurfaceId,
position: DeviceIntPoint,
clip_rect: DeviceIntRect,
);
fn wr_compositor_end_frame(compositor: *mut c_void);
}
pub struct WrCompositor(*mut c_void);
impl Compositor for WrCompositor {
fn create_surface(
&mut self,
id: NativeSurfaceId,
size: DeviceIntSize,
) {
unsafe {
wr_compositor_create_surface(
self.0,
id,
size,
);
}
}
fn destroy_surface(
&mut self,
id: NativeSurfaceId,
) {
unsafe {
wr_compositor_destroy_surface(
self.0,
id,
);
}
}
fn bind(
&mut self,
id: NativeSurfaceId,
) -> DeviceIntPoint {
let mut offset = DeviceIntPoint::zero();
unsafe {
wr_compositor_bind(
self.0,
id,
&mut offset,
);
}
offset
}
fn unbind(
&mut self,
) {
unsafe {
wr_compositor_unbind(
self.0,
);
}
}
fn begin_frame(&mut self) {
unsafe {
wr_compositor_begin_frame(
self.0,
);
}
}
fn add_surface(
&mut self,
id: NativeSurfaceId,
position: DeviceIntPoint,
clip_rect: DeviceIntRect,
) {
unsafe {
wr_compositor_add_surface(
self.0,
id,
position,
clip_rect,
);
}
}
fn end_frame(&mut self) {
unsafe {
wr_compositor_end_frame(
self.0,
);
}
}
}
// Call MakeCurrent before this.
#[no_mangle]
pub extern "C" fn wr_window_new(window_id: WrWindowId,
@ -1151,6 +1265,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
size_of_op: VoidPtrToSizeFn,
enclosing_size_of_op: VoidPtrToSizeFn,
document_id: u32,
compositor: *mut c_void,
out_handle: &mut *mut DocumentHandle,
out_renderer: &mut *mut Renderer,
out_max_texture_size: *mut i32)
@ -1203,6 +1318,12 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
ColorF::new(0.0, 0.0, 0.0, 0.0)
};
let native_compositor : Option<Box<dyn Compositor>> = if compositor != ptr::null_mut() {
Some(Box::new(WrCompositor(compositor)))
} else {
None
};
let opts = RendererOptions {
enable_aa: true,
enable_subpixel_aa: cfg!(not(target_os = "android")),
@ -1237,6 +1358,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
enable_picture_caching,
allow_pixel_local_storage_support: false,
start_debug_server,
native_compositor,
..Default::default()
};

Просмотреть файл

@ -150,6 +150,7 @@ impl CompositeState {
}
/// An arbitrary identifier for a native (OS compositor) surface
#[repr(C)]
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]

Просмотреть файл

@ -3562,6 +3562,11 @@
value: false
mirror: once
- name: gfx.webrender.compositor
type: bool
value: false
mirror: once
#ifdef NIGHTLY_BUILD
# Keep this pref hidden on non-nightly builds to avoid people accidentally
# turning it on.