Disable async rendering paths when a plugin is using direct drawing. (bug 1217665 part 3, r=aklotz)
authorDavid Anderson <danderson@mozilla.com>
Wed, 02 Dec 2015 11:31:16 -0800
changeset 309451 9e77cc23c491b89bc7051c670266247f1ec491d3
parent 309450 71328ca2c9c088d0e7cca6ced9878c6097523b6f
child 309452 1079b6b580c2a749ee470981a7458e8351b3960e
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1217665
milestone45.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
Disable async rendering paths when a plugin is using direct drawing. (bug 1217665 part 3, r=aklotz)
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceParent.cpp
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -3009,16 +3009,19 @@ PluginInstanceChild::UpdateWindowAttribu
 }
 
 void
 PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
                                                 gfxASurface* aSurface)
 {
     UpdateWindowAttributes();
 
+    // We should not send an async surface if we're using direct rendering.
+    MOZ_ASSERT(!IsUsingDirectDrawing());
+
 #ifdef MOZ_X11
     {
         NS_ASSERTION(aSurface->GetType() == gfxSurfaceType::Xlib,
                      "Non supported platform surface type");
 
         NPEvent pluginEvent;
         XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
         exposeEvent.type = GraphicsExpose;
@@ -3244,16 +3247,20 @@ PluginInstanceChild::ShowPluginFrame()
     // mLayersRendering can be false if we somehow get here without
     // receiving AsyncSetWindow() first.  mPendingPluginCall is our
     // re-entrancy guard; we can't paint while nested inside another
     // paint.
     if (!mLayersRendering || mPendingPluginCall) {
         return false;
     }
 
+    // We should not attempt to asynchronously show the plugin if we're using
+    // direct rendering.
+    MOZ_ASSERT(!IsUsingDirectDrawing());
+
     AutoRestore<bool> pending(mPendingPluginCall);
     mPendingPluginCall = true;
 
     bool temporarilyMakeVisible = !IsVisible() && !mHasPainted;
     if (temporarilyMakeVisible && mWindow.width && mWindow.height) {
         mWindow.clipRect.right = mWindow.width;
         mWindow.clipRect.bottom = mWindow.height;
     } else if (!IsVisible()) {
@@ -3523,16 +3530,23 @@ PluginInstanceChild::InvalidateRectDelay
 
 void
 PluginInstanceChild::AsyncShowPluginFrame(void)
 {
     if (mCurrentInvalidateTask) {
         return;
     }
 
+    // When the plugin is using direct surfaces to draw, it is not driving
+    // paints via paint events - it will drive painting via its own events
+    // and/or DidComposite callbacks.
+    if (IsUsingDirectDrawing()) {
+        return;
+    }
+
     mCurrentInvalidateTask =
         NewRunnableMethod(this, &PluginInstanceChild::InvalidateRectDelayed);
     MessageLoop::current()->PostTask(FROM_HERE, mCurrentInvalidateTask);
 }
 
 void
 PluginInstanceChild::InvalidateRect(NPRect* aInvalidRect)
 {
@@ -3544,16 +3558,21 @@ PluginInstanceChild::InvalidateRect(NPRe
       NS_ASSERTION(IsWindow(mPluginWindowHWND), "Bad window?!");
       RECT rect = { aInvalidRect->left, aInvalidRect->top,
                     aInvalidRect->right, aInvalidRect->bottom };
       ::InvalidateRect(mPluginWindowHWND, &rect, FALSE);
       return;
     }
 #endif
 
+    if (IsUsingDirectDrawing()) {
+        NS_ASSERTION(false, "Should not call InvalidateRect() in direct surface mode!");
+        return;
+    }
+
     if (mLayersRendering) {
         nsIntRect r(aInvalidRect->left, aInvalidRect->top,
                     aInvalidRect->right - aInvalidRect->left,
                     aInvalidRect->bottom - aInvalidRect->top);
 
         mAccumulatedInvalidRect.UnionRect(r, mAccumulatedInvalidRect);
         // If we are able to paint and invalidate sent, then reset
         // accumulated rectangle
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -594,16 +594,18 @@ PluginInstanceParent::RecvShow(const NPR
                                SurfaceDescriptor* prevSurface)
 {
     PLUGIN_LOG_DEBUG(
         ("[InstanceParent][%p] RecvShow for <x=%d,y=%d, w=%d,h=%d>",
          this, updatedRect.left, updatedRect.top,
          updatedRect.right - updatedRect.left,
          updatedRect.bottom - updatedRect.top));
 
+    MOZ_ASSERT(!IsUsingDirectDrawing());
+
     // XXXjwatt rewrite to use Moz2D
     RefPtr<gfxASurface> surface;
     if (newSurface.type() == SurfaceDescriptor::TShmem) {
         if (!newSurface.get_Shmem().IsReadable()) {
             NS_WARNING("back surface not readable");
             return false;
         }
         surface = gfxSharedImageSurface::Open(newSurface.get_Shmem());
@@ -732,16 +734,26 @@ PluginInstanceParent::AsyncSetWindow(NPW
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
 nsresult
 PluginInstanceParent::GetImageContainer(ImageContainer** aContainer)
 {
+    if (IsUsingDirectDrawing()) {
+        // Use the image container created by the most recent direct surface
+        // call, if any. We don't create one if no surfaces were presented
+        // yet.
+        ImageContainer *container = mImageContainer;
+        NS_IF_ADDREF(container);
+        *aContainer = container;
+        return NS_OK;
+    }
+
 #ifdef XP_MACOSX
     MacIOSurface* ioSurface = nullptr;
 
     if (mFrontIOSurface) {
       ioSurface = mFrontIOSurface;
     } else if (mIOSurface) {
       ioSurface = mIOSurface;
     }
@@ -772,16 +784,24 @@ PluginInstanceParent::GetImageContainer(
     NS_IF_ADDREF(container);
     *aContainer = container;
     return NS_OK;
 }
 
 nsresult
 PluginInstanceParent::GetImageSize(nsIntSize* aSize)
 {
+    if (IsUsingDirectDrawing()) {
+        if (!mImageContainer) {
+            return NS_ERROR_NOT_AVAILABLE;
+        }
+        *aSize = mImageContainer->GetCurrentSize();
+        return NS_OK;
+    }
+
     if (mFrontSurface) {
         mozilla::gfx::IntSize size = mFrontSurface->GetSize();
         *aSize = nsIntSize(size.width, size.height);
         return NS_OK;
     }
 
 #ifdef XP_MACOSX
     if (mFrontIOSurface) {