Bug 1340997 - add external image callback in RendererOGL. r=sotaro
authorJerryShih <hshih@mozilla.com>
Wed, 01 Mar 2017 17:08:56 +0800
changeset 394767 e306b40ff823a65433b153cd0ab85f720ab05e02
parent 394766 169c2f5176bbc98d0ee8d2158f78a1a0d9cbf3c7
child 394768 7d88bb71fefb36157f16769e87658a39248a2a91
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1340997
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1340997 - add external image callback in RendererOGL. r=sotaro MozReview-Commit-ID: 8aCSe1iu44C
gfx/webrender_bindings/RendererOGL.cpp
gfx/webrender_bindings/RendererOGL.h
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderTypes.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi.h
--- a/gfx/webrender_bindings/RendererOGL.cpp
+++ b/gfx/webrender_bindings/RendererOGL.cpp
@@ -9,16 +9,29 @@
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/widget/CompositorWidget.h"
 
 namespace mozilla {
 namespace wr {
 
+WrExternalImage LockExternalImage(void* aObj, WrExternalImageId aId)
+{
+  return WrExternalImage { WrExternalImageIdType::TEXTURE_HANDLE, 0.0f, 0.0f, 0.0f, 0.0f, 0 };
+}
+
+void UnlockExternalImage(void* aObj, WrExternalImageId aId)
+{
+}
+
+void ReleaseExternalImage(void* aObj, WrExternalImageId aId)
+{
+}
+
 RendererOGL::RendererOGL(RefPtr<RenderThread>&& aThread,
                          RefPtr<gl::GLContext>&& aGL,
                          RefPtr<widget::CompositorWidget>&& aWidget,
                          wr::WindowId aWindowId,
                          WrRenderer* aWrRenderer,
                          layers::CompositorBridgeParentBase* aBridge)
   : mThread(aThread)
   , mGL(aGL)
@@ -36,16 +49,27 @@ RendererOGL::RendererOGL(RefPtr<RenderTh
 }
 
 RendererOGL::~RendererOGL()
 {
   MOZ_COUNT_DTOR(RendererOGL);
   wr_renderer_delete(mWrRenderer);
 }
 
+WrExternalImageHandler
+RendererOGL::GetExternalImageHandler()
+{
+  return WrExternalImageHandler {
+    this,
+    LockExternalImage,
+    UnlockExternalImage,
+    ReleaseExternalImage,
+  };
+}
+
 void
 RendererOGL::Update()
 {
   wr_renderer_update(mWrRenderer);
 }
 
 bool
 RendererOGL::Render()
--- a/gfx/webrender_bindings/RendererOGL.h
+++ b/gfx/webrender_bindings/RendererOGL.h
@@ -33,17 +33,23 @@ namespace wr {
 
 /// Owns the WebRender renderer and GL context.
 ///
 /// There is one renderer per window, all owned by the render thread.
 /// This class is a similar abstraction to CompositorOGL except that it is used
 /// on the render thread instead of the compositor thread.
 class RendererOGL
 {
+  friend WrExternalImage LockExternalImage(void* aObj, WrExternalImageId aId);
+  friend void UnlockExternalImage(void* aObj, WrExternalImageId aId);
+  friend void ReleaseExternalImage(void* aObj, WrExternalImageId aId);
+
 public:
+  WrExternalImageHandler GetExternalImageHandler();
+
   /// This can be called on the render thread only.
   void Update();
 
   /// This can be called on the render thread only.
   bool Render();
 
   /// This can be called on the render thread only.
   bool RenderToTarget(gfx::DrawTarget& aTarget);
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -46,28 +46,32 @@ public:
     if (!gl || !gl->MakeCurrent()) {
       return;
     }
 
     gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, mMaxTextureSize);
     *mUseANGLE = gl->IsANGLE();
 
     WrRenderer* wrRenderer = nullptr;
-    if (!wr_window_new(aWindowId, gl.get(), this->mEnableProfiler, nullptr, mWrApi, &wrRenderer)) {
+    if (!wr_window_new(aWindowId, gl.get(), this->mEnableProfiler, mWrApi, &wrRenderer)) {
       return;
     }
     MOZ_ASSERT(wrRenderer);
 
     RefPtr<RenderThread> thread = &aRenderThread;
     auto renderer = MakeUnique<RendererOGL>(Move(thread),
                                             Move(gl),
                                             Move(mCompositorWidget),
                                             aWindowId,
                                             wrRenderer,
                                             mBridge);
+    if (wrRenderer && renderer) {
+      WrExternalImageHandler handler = renderer->GetExternalImageHandler();
+      wr_renderer_set_external_image_handler(wrRenderer, &handler);
+    }
 
     aRenderThread.AddRenderer(aWindowId, Move(renderer));
   }
 
 private:
   WrAPI** mWrApi;
   GLint* mMaxTextureSize;
   bool* mUseANGLE;
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -233,16 +233,23 @@ static inline WrRect ToWrRect(const gfx:
 static inline WrPoint ToWrPoint(const gfx::Point& point)
 {
   WrPoint p;
   p.x = point.x;
   p.y = point.y;
   return p;
 }
 
+static inline WrExternalImageId ToWrExternalImageId(uint64_t aID)
+{
+  WrExternalImageId id;
+  id.id = aID;
+  return id;
+}
+
 struct ByteBuffer
 {
   ByteBuffer(size_t aLength, uint8_t* aData)
     : mLength(aLength)
     , mData(aData)
     , mOwned(false)
   {}
 
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -130,16 +130,32 @@ pub unsafe extern fn wr_renderer_readbac
 }
 
 #[no_mangle]
 pub extern fn wr_renderer_set_profiler_enabled(renderer: &mut Renderer, enabled: bool) {
     renderer.set_profiler_enabled(enabled);
 }
 
 #[no_mangle]
+pub extern fn wr_renderer_set_external_image_handler(renderer: &mut Renderer,
+                                                     external_image_handler: *mut WrExternalImageHandler) {
+    if !external_image_handler.is_null() {
+        renderer.set_external_image_handler(Box::new(
+            unsafe {
+                WrExternalImageHandler {
+                    external_image_obj: (*external_image_handler).external_image_obj,
+                    lock_func: (*external_image_handler).lock_func,
+                    unlock_func: (*external_image_handler).unlock_func,
+                    release_func: (*external_image_handler).release_func,
+                }
+            }));
+    }
+}
+
+#[no_mangle]
 pub extern fn wr_renderer_current_epoch(renderer: &mut Renderer,
                                         pipeline_id: PipelineId,
                                         out_epoch: &mut Epoch) -> bool {
     if let Some(epoch) = renderer.current_epoch(pipeline_id) {
         *out_epoch = epoch;
         return true;
     }
     return false;
@@ -188,17 +204,16 @@ pub extern fn wr_api_generate_frame(api:
   api.generate_frame(None);
 }
 
 // Call MakeCurrent before this.
 #[no_mangle]
 pub extern fn wr_window_new(window_id: WrWindowId,
                             gl_context: *mut c_void,
                             enable_profiler: bool,
-                            external_image_handler: *mut WrExternalImageHandler,
                             out_api: &mut *mut RenderApi,
                             out_renderer: &mut *mut Renderer) -> bool {
     assert!(unsafe { is_in_render_thread() });
 
     let recorder: Option<Box<ApiRecordingReceiver>> = if ENABLE_RECORDING {
         let name = format!("wr-record-{}.bin", window_id.0);
         Some(Box::new(BinaryRecorder::new(&PathBuf::from(name))))
     } else {
@@ -224,28 +239,16 @@ pub extern fn wr_window_new(window_id: W
         Err(e) => {
             println!(" Failed to create a Renderer: {:?}", e);
             return false;
         }
     };
 
     renderer.set_render_notifier(Box::new(CppNotifier { window_id: window_id }));
 
-    if !external_image_handler.is_null() {
-        renderer.set_external_image_handler(Box::new(
-            unsafe {
-                WrExternalImageHandler {
-                    external_image_obj: (*external_image_handler).external_image_obj,
-                    lock_func: (*external_image_handler).lock_func,
-                    unlock_func: (*external_image_handler).unlock_func,
-                    release_func: (*external_image_handler).release_func,
-                }
-            }));
-    }
-
     *out_api = Box::into_raw(Box::new(sender.create_api()));
     *out_renderer = Box::into_raw(Box::new(renderer));
 
     return true;
 }
 
 #[no_mangle]
 pub extern fn wr_state_new(pipeline_id: PipelineId) -> *mut WrState {
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -364,16 +364,21 @@ struct WrImageDescriptor {
 
 // Structs defined in Rust, but opaque to C++ code.
 struct WrRenderedEpochs;
 struct WrRenderer;
 struct WrState;
 struct WrAPI;
 
 WR_INLINE void
+wr_renderer_set_external_image_handler(WrRenderer* renderer,
+                                       WrExternalImageHandler* handler)
+WR_FUNC;
+
+WR_INLINE void
 wr_renderer_update(WrRenderer* renderer)
 WR_FUNC;
 
 WR_INLINE void
 wr_renderer_render(WrRenderer* renderer, uint32_t width, uint32_t height)
 WR_FUNC;
 
 WR_INLINE void
@@ -399,17 +404,16 @@ wr_rendered_epochs_next(WrRenderedEpochs
 
 WR_INLINE void
 wr_rendered_epochs_delete(WrRenderedEpochs* pipeline_epochs) WR_DESTRUCTOR_SAFE_FUNC;
 
 WR_INLINE bool
 wr_window_new(WrWindowId window_id,
               void* aGLContext,
               bool enable_profiler,
-              WrExternalImageHandler* handler,
               WrAPI** out_api,
               WrRenderer** out_renderer)
 WR_FUNC;
 
 WR_INLINE void
 wr_api_delete(WrAPI* api)
 WR_DESTRUCTOR_SAFE_FUNC;