Bug 1451469 - Add the plumbing to hook up the sampler callbacks. r?nical draft
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 16 Apr 2018 17:39:14 -0400
changeset 783271 6f616bb4c87796e063deb980e288bd0b4c4cffca
parent 783270 ba7e3de7c05b6f9e9c22bc2e32985a6938fcba3d
child 783272 cdc71fad9b309d491746fc5336958c0a58fb43da
push id106651
push userkgupta@mozilla.com
push dateMon, 16 Apr 2018 21:40:40 +0000
reviewersnical
bugs1451469
milestone61.0a1
Bug 1451469 - Add the plumbing to hook up the sampler callbacks. r?nical MozReview-Commit-ID: GhCKVFXKfjX
gfx/layers/apz/src/APZSampler.cpp
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi.h
gfx/webrender_bindings/webrender_ffi_generated.h
--- a/gfx/layers/apz/src/APZSampler.cpp
+++ b/gfx/layers/apz/src/APZSampler.cpp
@@ -8,16 +8,17 @@
 
 #include "APZCTreeManager.h"
 #include "AsyncPanZoomController.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/LayerMetricsWrapper.h"
 #include "mozilla/layers/SynchronousTask.h"
 #include "TreeTraversal.h"
+#include "mozilla/webrender/WebRenderAPI.h"
 
 namespace mozilla {
 namespace layers {
 
 StaticMutex APZSampler::sWindowIdLock;
 std::unordered_map<uint64_t, APZSampler*> APZSampler::sWindowIdMap;
 
 
@@ -218,8 +219,24 @@ APZSampler::GetSampler(const wr::WrWindo
   if (it != sWindowIdMap.end()) {
     sampler = it->second;
   }
   return sampler.forget();
 }
 
 } // namespace layers
 } // namespace mozilla
+
+void
+apz_register_sampler(mozilla::wr::WrWindowId aWindowId)
+{
+}
+
+void
+apz_sample_transforms(mozilla::wr::WrWindowId aWindowId,
+                      mozilla::wr::Transaction *aTransaction)
+{
+}
+
+void
+apz_deregister_sampler(mozilla::wr::WrWindowId aWindowId)
+{
+}
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -7,17 +7,17 @@ use std::sync::Arc;
 use std::os::raw::{c_void, c_char, c_float};
 use gleam::gl;
 
 use webrender::api::*;
 use webrender::{ReadPixelsFormat, Renderer, RendererOptions, ThreadListener};
 use webrender::{ExternalImage, ExternalImageHandler, ExternalImageSource};
 use webrender::DebugFlags;
 use webrender::{ApiRecordingReceiver, BinaryRecorder};
-use webrender::{PipelineInfo, SceneBuilderHooks};
+use webrender::{AsyncPropertySampler, PipelineInfo, SceneBuilderHooks};
 use webrender::{ProgramCache, UploadMethod, VertexUsageHint};
 use thread_profiler::register_thread_with_profiler;
 use moz2d_renderer::Moz2dImageRenderer;
 use app_units::Au;
 use rayon;
 use euclid::SideOffsets2D;
 use log;
 
@@ -679,24 +679,33 @@ pub unsafe extern "C" fn wr_renderer_flu
 
 /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC
 #[no_mangle]
 pub unsafe extern "C" fn wr_pipeline_info_delete(_info: WrPipelineInfo) {
     // _info will be dropped here, and the drop impl on FfiVec will free
     // the underlying vec memory
 }
 
+#[allow(improper_ctypes)] // this is needed so that rustc doesn't complain about passing the &mut Transaction to an extern function
 extern "C" {
+    // These callbacks are invoked from the scene builder thread (aka the APZ
+    // updater thread)
     fn apz_register_updater(window_id: WrWindowId);
     fn apz_pre_scene_swap(window_id: WrWindowId);
     // This function takes ownership of the pipeline_info and is responsible for
     // freeing it via wr_pipeline_info_delete.
     fn apz_post_scene_swap(window_id: WrWindowId, pipeline_info: WrPipelineInfo);
     fn apz_run_updater(window_id: WrWindowId);
     fn apz_deregister_updater(window_id: WrWindowId);
+
+    // These callbacks are invoked from the render backend thread (aka the APZ
+    // sampler thread)
+    fn apz_register_sampler(window_id: WrWindowId);
+    fn apz_sample_transforms(window_id: WrWindowId, transaction: &mut Transaction);
+    fn apz_deregister_sampler(window_id: WrWindowId);
 }
 
 struct APZCallbacks {
     window_id: WrWindowId,
 }
 
 impl APZCallbacks {
     pub fn new(window_id: WrWindowId) -> Self {
@@ -724,16 +733,45 @@ impl SceneBuilderHooks for APZCallbacks 
         unsafe { apz_run_updater(self.window_id) }
     }
 
     fn deregister(&self) {
         unsafe { apz_deregister_updater(self.window_id) }
     }
 }
 
+struct SamplerCallback {
+    window_id: WrWindowId,
+}
+
+impl SamplerCallback {
+    pub fn new(window_id: WrWindowId) -> Self {
+        SamplerCallback {
+            window_id,
+        }
+    }
+}
+
+impl AsyncPropertySampler for SamplerCallback {
+    fn register(&self) {
+        unsafe { apz_register_sampler(self.window_id) }
+    }
+
+    fn sample(&self) -> Vec<FrameMsg> {
+        let mut transaction = Transaction::new();
+        unsafe { apz_sample_transforms(self.window_id, &mut transaction) };
+        // TODO: also omta_sample_transforms(...)
+        transaction.get_frame_ops()
+    }
+
+    fn deregister(&self) {
+        unsafe { apz_deregister_sampler(self.window_id) }
+    }
+}
+
 extern "C" {
     fn gecko_profiler_register_thread(name: *const ::std::os::raw::c_char);
     fn gecko_profiler_unregister_thread();
 }
 
 struct GeckoProfilerThreadListener {}
 
 impl GeckoProfilerThreadListener {
@@ -864,16 +902,17 @@ pub extern "C" fn wr_window_new(window_i
                     Ok(override_str) => Some(PathBuf::from(override_str)),
                     _ => None
                 }
             }
         },
         renderer_id: Some(window_id.0),
         upload_method,
         scene_builder_hooks: Some(Box::new(APZCallbacks::new(window_id))),
+        sampler: Some(Box::new(SamplerCallback::new(window_id))),
         ..Default::default()
     };
 
     let notifier = Box::new(CppNotifier {
         window_id: window_id,
     });
     let (renderer, sender) = match Renderer::new(gl, notifier, opts) {
         Ok((renderer, sender)) => (renderer, sender),
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -80,28 +80,32 @@ struct FontInstanceFlags {
     FONT_SMOOTHING    = 1 << 16,
 
     FORCE_AUTOHINT    = 1 << 16,
     NO_AUTOHINT       = 1 << 17,
     VERTICAL_LAYOUT   = 1 << 18
   };
 };
 
+struct Transaction;
 struct WrWindowId;
 struct WrPipelineInfo;
 
 } // namespace wr
 } // namespace mozilla
 
 void apz_register_updater(mozilla::wr::WrWindowId aWindowId);
 void apz_pre_scene_swap(mozilla::wr::WrWindowId aWindowId);
 void apz_post_scene_swap(mozilla::wr::WrWindowId aWindowId, mozilla::wr::WrPipelineInfo aInfo);
 void apz_run_updater(mozilla::wr::WrWindowId aWindowId);
 void apz_deregister_updater(mozilla::wr::WrWindowId aWindowId);
 
+void apz_register_sampler(mozilla::wr::WrWindowId aWindowId);
+void apz_sample_transforms(mozilla::wr::WrWindowId aWindowId, mozilla::wr::Transaction *aTransaction);
+void apz_deregister_sampler(mozilla::wr::WrWindowId aWindowId);
 } // extern "C"
 
 // Some useful defines to stub out webrender binding functions for when we
 // build gecko without webrender. We try to tell the compiler these functions
 // are unreachable in that case, but VC++ emits a warning if it finds any
 // unreachable functions invoked from destructors. That warning gets turned into
 // an error and causes the build to fail. So for wr_* functions called by
 // destructors in C++ classes, use WR_DESTRUCTOR_SAFE_FUNC instead, which omits
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -973,27 +973,34 @@ extern void AddFontData(WrFontKey aKey,
                         const ArcVecU8 *aVec);
 
 extern void AddNativeFontHandle(WrFontKey aKey,
                                 void *aHandle,
                                 uint32_t aIndex);
 
 extern void DeleteFontData(WrFontKey aKey);
 
+extern void apz_deregister_sampler(WrWindowId aWindowId);
+
 extern void apz_deregister_updater(WrWindowId aWindowId);
 
 extern void apz_post_scene_swap(WrWindowId aWindowId,
                                 WrPipelineInfo aPipelineInfo);
 
 extern void apz_pre_scene_swap(WrWindowId aWindowId);
 
+extern void apz_register_sampler(WrWindowId aWindowId);
+
 extern void apz_register_updater(WrWindowId aWindowId);
 
 extern void apz_run_updater(WrWindowId aWindowId);
 
+extern void apz_sample_transforms(WrWindowId aWindowId,
+                                  Transaction *aTransaction);
+
 extern void gecko_printf_stderr_output(const char *aMsg);
 
 extern void gecko_profiler_register_thread(const char *aName);
 
 extern void gecko_profiler_unregister_thread();
 
 extern void gfx_critical_error(const char *aMsg);