Closed
Bug 598425
Opened 14 years ago
Closed 13 years ago
Asynchronous layer-based plugin painting on Mac
Categories
(Core Graveyard :: Plug-ins, defect)
Tracking
(firefox6-, firefox7-, blocking2.0 -)
RESOLVED
FIXED
People
(Reporter: benjamin, Assigned: BenWa)
References
Details
Attachments
(3 files, 10 obsolete files)
1010 bytes,
patch
|
romaxa
:
review+
|
Details | Diff | Splinter Review |
19.53 KB,
patch
|
Details | Diff | Splinter Review | |
30.45 KB,
patch
|
jaas
:
review+
|
Details | Diff | Splinter Review |
+++ This bug was initially created as a clone of Bug #596451 +++Asynchronous layer-based plugin painting on Mac.
Reporter | ||
Comment 1•14 years ago
|
||
Josh, should this be yours?
Blocks: 552512
I may be able to take this at some point but I'm working on other blockers at the moment. I'll try to find an owner and take if myself if necessary.
Assignee | ||
Updated•14 years ago
|
OS: Windows XP → Mac OS X
Reporter | ||
Comment 3•14 years ago
|
||
We're not going to block on this directly, although we still might take it to fix the performance issues which are a blocker.
blocking2.0: betaN+ → -
Assignee | ||
Updated•13 years ago
|
Assignee: nobody → b56girard
Assignee | ||
Comment 4•13 years ago
|
||
Assignee | ||
Comment 5•13 years ago
|
||
Attachment #533322 -
Attachment is obsolete: true
Assignee | ||
Comment 6•13 years ago
|
||
Comment on attachment 533425 [details] [diff] [review] Async Core Animation Feel free to delegate the review. I'm not sure who to ask.
Attachment #533425 -
Flags: review?(romaxa)
Assignee | ||
Comment 7•13 years ago
|
||
Added a check in UseAsyncRendering to check for Layers OPENGL
Attachment #533425 -
Attachment is obsolete: true
Attachment #533447 -
Flags: review?(romaxa)
Attachment #533425 -
Flags: review?(romaxa)
Assignee | ||
Updated•13 years ago
|
Attachment #533447 -
Attachment is patch: true
Comment 8•13 years ago
|
||
Comment on attachment 533447 [details] [diff] [review] Async Core Animation v2 > PRBool useAsyncRendering; >+#ifndef XP_MACOSX > return (mInstance && > NS_SUCCEEDED(mInstance->UseAsyncPainting(&useAsyncRendering)) && > useAsyncRendering && > (!mPluginWindow || > mPluginWindow->type == NPWindowTypeDrawable)); >+#else >+ nsRefPtr<ImageContainer> container = mObjectFrame->GetImageContainer(); >+ return (mInstance && >+ NS_SUCCEEDED(mInstance->UseAsyncPainting(&useAsyncRendering)) && >+ useAsyncRendering && >+ IsRemoteDrawingCoreAnimation() && >+ container && container->GetBackendType() == LayerManager::LAYERS_OPENGL >+ ); >+#endif would it be better ifdef only part of this condition and keep, common parts common >bool >PluginInstanceChild::ShowPluginFrame() >{ .... >+ if (!SendShow(r, currSurf, &returnSurf)) { >+ return false; >+ } >+ >+ return true; >+ } else { >+ NS_ERROR("Unsupported drawing model for async layer rendering"); >+ return false; >+ } >+#endif I'm not 100% what is IOSurface, is it double buffered magically by default? don't you need cur/back surface, readback, background paint stuff ?
Assignee | ||
Comment 9•13 years ago
|
||
(In reply to comment #8) > > I'm not 100% what is IOSurface, is it double buffered magically by default? > don't you need cur/back surface, readback, background paint stuff ? We don't need readback, background paint since the surface has proper alpha channel support (unless I am missing something). I'm not 100% sure if double buffering is required since this is shared video memory, rather then main memory like a Shmem. I haven't observed any issue yet. I discussed this with Joe and we were of the opinion that we could leave it like this and fix it later if we notice any issues.
Reporter | ||
Comment 10•13 years ago
|
||
We'd obviously like to avoid readback. But I don't understand how you can have asynchronous painting without double buffering: aren't you either setting yourself up for shearing (which will be very noticeable on video sites), or having something in the OS start locking the surface? Unlike the current synchronous setup, we are going to be painting a surface to the screen at the same time we're asking Flash to draw to it (in a different process). Unless I'm totally missing something, double buffering is the key ingredient which makes asynchronous painting possible.
Comment 11•13 years ago
|
||
Without double buffering you will get artifacts (partially painted layer), which will be visible if you open some high FPS flash example, and start scrolling firefox at the same time, so you will have a big chance that layer is painted while flash rendering into the same layer...
Assignee | ||
Comment 12•13 years ago
|
||
I haven't seen any tearing or artifacts when testing this patch (1080p video with a non optimized build) but proof by example isn't convincing to prove that it will never happen. I will speak more with the graphics teams tomorrow to understand this. I don't know enough about graphic hardware implementation but if rasterization is an atomic operation then no locking would be required? If we can avoid double buffering that would save us from having to reinitialize the PBO/CARenderer and video memory giving us significant performance benefits.
Comment 13•13 years ago
|
||
The biggest risk is if this surface is passed to the plugin, the plugin may paint in stages (e.g. background before foreground). If that is the same surface that is read asynchronously by the browser, then the browser may read only the background of a future paint. I don't know about the limitations of the APIs involved but it should be possible to keep two video memory buffers and swap between them.
Assignee | ||
Comment 14•13 years ago
|
||
(In reply to comment #13) > The biggest risk is if this surface is passed to the plugin, the plugin may > paint in stages (e.g. background before foreground). If that is the same > surface that is read asynchronously by the browser, then the browser may > read only the background of a future paint. > The plug-in does not draw directly to our surface, the plug-in draws to a CALayer. This provides double buffering in the plug-in process. I creates a test plug-in that draws 1,000,000 quads taking over 0.5 second per frame. The scene is always completed. (Browser is much more responsive with this patch BTW) Sequence: Plug-in draws to CALayer -> CALayer draws to IOSurface -> IOSurface is drawn The only legitimate concern for artifacts is when drawing the CALayer into the IOSurface. Here are the relevant section from the API of the function we use to draw the MacIOSurfaceImageOGL in the content process: Snippet from: /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers/CGLIOSurface.h > It is the rough equivalent to glTexImage2D(), except that > the underlying source data comes from an IOSurface rather than from an explicit pointer. > Note that unlike glTexImage2D(), the binding is "live", in that if the contents of > the IOSurface change, the contents become visible to OpenGL without making another > call to CGLTexImageIOSurface2D(). That being said, there are a few synchronization > things to worry about if you are using IOSurface to pass data between contexts and/or > different processes, or between the CPU and OpenGL. > > In general IOSurface follows Apple's cross-context synchronization rules for OpenGL. Put > simply, in order for changes done to an IOSurface on context A to become visible to context > B, you must flush context A's command stream (via an explicit call to glFlush, glFlushRenderAPPLE, > etc.), and then perform a 'bind' (in this case, glBindTexture()) on context B. Note that > in the case of an IOSurface backed texture used as a color buffer attachment for an FBO, > you are only required to call glBindFramebuffer() again. You do not have to call > glFramebufferTexture2D(). Thus we should be able to rely on glFlush to synchronize the change. If we bind before the flush we will be drawing the previous frame until the flush has been made. SendShow will notify that a glFlush has occurred but the changes will be visible immediately after the flush (unless the window changed, in which case a new surface is allocated).
Assignee | ||
Comment 15•13 years ago
|
||
Forgot to release the previous mIOSurface in RecvShow.
Attachment #533447 -
Attachment is obsolete: true
Attachment #533769 -
Flags: review?(romaxa)
Attachment #533447 -
Flags: review?(romaxa)
Comment 16•13 years ago
|
||
Comment on attachment 533769 [details] [diff] [review] Async Core Animation v3 Generic part seems ok for me, but I think some other mac-GFX people should take a look at this patch and prove that double buffering and sync is not needed here, and possibly this wiki rules does not apply on mac... https://wiki.mozilla.org/Gecko:AsyncPluginPainting who can do that? roc?
Attachment #533769 -
Flags: review?(romaxa) → review+
Assignee | ||
Comment 17•13 years ago
|
||
This patch only provides async Core Animation. I'll post a patch next week for async Core Graphics that will follow the plug-in strategy more closely.
Assignee | ||
Comment 18•13 years ago
|
||
Review comments for #ifdef, delete IOSurface changes did not get 'qrefresh' into previous patch.
Attachment #533769 -
Attachment is obsolete: true
Attachment #533952 -
Flags: review?(roc)
Comment on attachment 533952 [details] [diff] [review] Async Core Animation v4 Review of attachment 533952 [details] [diff] [review]: ----------------------------------------------------------------- ::: dom/plugins/ipc/PluginInstanceChild.cpp @@ +2975,5 @@ > +#ifdef XP_MACOSX > + // We can't use the thebes code with CoreAnimation so we will > + // take a different code path. > + if (mDrawingModel == NPDrawingModelCoreAnimation || > + mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) { fix indent ::: dom/plugins/ipc/PluginInstanceChild.h @@ +513,5 @@ > > +#ifdef XP_MACOSX > + // Current IOSurface available for rendering > + // We can't use thebes gfxASurface like other platforms. > + nsIOSurface *mCurrentIOSurface; nsAutoPtr (and get rid of the explicit "delete mCurrentIOSurface"). ::: dom/plugins/ipc/PluginInstanceParent.cpp @@ +533,5 @@ > + return false; > + } > + > + if (mIOSurface) { > + delete mIOSurface; PluginInstanceParent::mIOSurface should be nsAutoPtr as well
Attachment #533952 -
Flags: review?(roc) → review+
I don't really follow the explanation in comment #14. I don't think we can rely on glFlush for synchronization; that will ensure any drawing done before the glFlush shows up when we use the IOSurface after the glFlush, but the problem to worry about is what happens when the parent process uses the IOSurface to draw the previous frame while CARenderer draws the CALayer for the new frame to the IOSurface. glFlush won't prevent that, because there is no guarantee that nothing is drawn until the glFlush happens. (It would be perfectly valid for a GL implementation to draw everything synchronously and make glFlush a no-op.) But without knowing what goes on under the covers with IOSurface and CARenderers, I don't know if there's a real synchronization hazard here or not. On the other hand, if we never see any visual problems in practice, then the overhead of synchronization or copying is probably not worth it even if we need it in theory.
Assignee | ||
Comment 21•13 years ago
|
||
Adds a 16ms (60FPS) delay to let dirty rects accumulate. This solve performance problems on OS X.
Attachment #535149 -
Flags: review?(romaxa)
Comment 22•13 years ago
|
||
Comment on attachment 535149 [details] [diff] [review] Delay Invalidate Task I think this should be fine, be check it carefully on try server.
Attachment #535149 -
Flags: review?(romaxa) → review+
Assignee | ||
Comment 23•13 years ago
|
||
Applied review comments
Attachment #533952 -
Attachment is obsolete: true
Assignee | ||
Comment 24•13 years ago
|
||
This patch creates a CALayer that we use to draw Core Graphics within. This let's us use the same code path as CALayer for async and allows us to use IOSurface cross process rather then bitmap shared memory. This moves some of the work from the content process to the plugin process since we don't have to convert a CGBitmapContext to a layer. Once/If OS X gives us accelerated Core Graphics context within Core Animation we should see additional speed improvements.
Assignee | ||
Comment 25•13 years ago
|
||
Attachment #535349 -
Attachment is obsolete: true
Assignee | ||
Updated•13 years ago
|
Attachment #535351 -
Flags: review?(joshmoz)
Assignee | ||
Comment 26•13 years ago
|
||
Investigating some test failure. Patches appear to be delaying the first paint.
Assignee | ||
Comment 27•13 years ago
|
||
Will wait until bug 660721 lands to lands these fixes. Got a green try run for the Async CA/CG. Updating attachments that yield green try run.
Depends on: 660721
Assignee | ||
Comment 28•13 years ago
|
||
Fixed bit-rot and applied review comments. Carrying forward r=roc
Attachment #535345 -
Attachment is obsolete: true
Assignee | ||
Updated•13 years ago
|
Attachment #536206 -
Attachment is patch: true
Assignee | ||
Comment 29•13 years ago
|
||
Fixed bit-rot, fragile import ordering, add logging for event/drawing model on os x. Fixed mochitest failure (UseAsyncRendering condition was missing 'mInstanceOwner->UseAsyncRendering()').
Attachment #535351 -
Attachment is obsolete: true
Attachment #535351 -
Flags: review?(joshmoz)
Updated•13 years ago
|
tracking-firefox6:
--- → +
Reporter | ||
Comment 30•13 years ago
|
||
I'm not sure why this got marked tracking firefox 6, but I'm pretty damn certain I don't want it to land on Aurora. This is the kind of thing that needs lots of bake time.
Comment 32•13 years ago
|
||
This got marked tracking? because it blocks two security sensitive bugs that were both marked tracking-firefox6+ I'm totally cool with minusing this but it means re-visiting bug 552002 and bug 591409 and presumably minusing those as well. (My nomination here was about housekeeping, not advocacy)
Assignee | ||
Comment 33•13 years ago
|
||
Fix bitrot caused by nsObjectFrame refactor.
Attachment #536206 -
Attachment is obsolete: true
Assignee | ||
Comment 34•13 years ago
|
||
Fix bitrot. This patch passed tryserver before the nsObjectFrame refactor. Feel free to pass the review along if you can't get to it.
Attachment #536208 -
Attachment is obsolete: true
Attachment #536660 -
Flags: review?(joshmoz)
Comment 35•13 years ago
|
||
Comment on attachment 536660 [details] [diff] [review] Async CG via Async CA v4 Review of attachment 536660 [details] [diff] [review]: ----------------------------------------------------------------- I would combine the CA and CG patches. It's more confusing not to do that since the CA patch is first but the CG patch contains a critical fix for CA. ::: dom/plugins/ipc/PluginInstanceChild.cpp @@ +2317,5 @@ > mCurrentAsyncSetWindowTask = nsnull; > } > > mWindow.window = NULL; > +#ifdef OS_MACOSX We should just use XP_MACOSX going forward, drop the Chromium macros. No need to clean anything else up, just don't add them. ::: dom/plugins/ipc/PluginUtilsOSX.h @@ +50,5 @@ > NPError ShowCocoaContextMenu(void* aMenu, int aX, int aY, void* pluginModule, RemoteProcessEvents remoteEvent); > > void InvokeNativeEventLoop(); > > +// Need to call back into the browser's to process event. This comment doesn't really make any sense. The browser's what?
Attachment #536660 -
Flags: review?(joshmoz) → review+
Assignee | ||
Comment 36•13 years ago
|
||
http://hg.mozilla.org/mozilla-central/rev/24e35780bd8f Will fill a spin off bug for throttling.
Assignee | ||
Updated•13 years ago
|
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
Updated•13 years ago
|
tracking-firefox7:
--- → ?
Reporter | ||
Updated•13 years ago
|
Comment 37•13 years ago
|
||
Comment on attachment 536660 [details] [diff] [review] Async CG via Async CA v4 >--- a/dom/plugins/base/nsPluginInstanceOwner.cpp >+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp >@@ -258,18 +258,19 @@ nsPluginInstanceOwner::UseAsyncRendering > nsRefPtr<ImageContainer> container = mObjectFrame->GetImageContainer(); > #endif > > PRBool useAsyncRendering; > return (mInstance && > NS_SUCCEEDED(mInstance->UseAsyncPainting(&useAsyncRendering)) && > useAsyncRendering && > #ifdef XP_MACOSX >- IsRemoteDrawingCoreAnimation() && >- container && container->GetBackendType() == LayerManager::LAYERS_OPENGL >+ mObjectFrame && mObjectFrame->GetImageContainer().get() && >+ mObjectFrame->GetImageContainer().get()->GetBackendType() == >+ LayerManager::LAYERS_OPENGL This leaks.
Assignee | ||
Comment 38•13 years ago
|
||
You're right. This isn't picked up since this code isn't being hit because of bug 663259. I'm working on a patch that will fix these issue as well as some test failures.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
This bug is pretty big, patches have landed. I'd vote for a new followup bug rather than reopening this one.
Assignee | ||
Comment 40•13 years ago
|
||
Agreed, going to do follow up work on bug 663259
Status: REOPENED → RESOLVED
Closed: 13 years ago → 13 years ago
Resolution: --- → FIXED
Updated•13 years ago
|
Updated•2 years ago
|
Product: Core → Core Graveyard
You need to log in
before you can comment on or make changes to this bug.
Description
•