Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: sw=4 ts=4 et :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef dom_plugins_PluginInstanceChild_h
8 #define dom_plugins_PluginInstanceChild_h 1
10 #include "mozilla/plugins/PPluginInstanceChild.h"
11 #include "mozilla/plugins/PluginScriptableObjectChild.h"
12 #include "mozilla/plugins/StreamNotifyChild.h"
13 #include "mozilla/plugins/PPluginSurfaceChild.h"
14 #include "mozilla/ipc/CrossProcessMutex.h"
15 #include "nsClassHashtable.h"
16 #if defined(OS_WIN)
17 #include "mozilla/gfx/SharedDIBWin.h"
18 #elif defined(MOZ_WIDGET_COCOA)
19 #include "PluginUtilsOSX.h"
20 #include "mozilla/gfx/QuartzSupport.h"
21 #include "base/timer.h"
23 #endif
25 #include "npfunctions.h"
26 #include "nsAutoPtr.h"
27 #include "nsTArray.h"
28 #include "ChildAsyncCall.h"
29 #include "ChildTimer.h"
30 #include "nsRect.h"
31 #include "nsTHashtable.h"
32 #include "mozilla/PaintTracker.h"
34 #include <map>
36 #if (MOZ_WIDGET_GTK == 2)
37 #include "gtk2xtbin.h"
38 #endif
40 class gfxASurface;
42 namespace mozilla {
44 namespace layers {
45 struct RemoteImageData;
46 }
48 namespace plugins {
50 class PBrowserStreamChild;
51 class BrowserStreamChild;
52 class StreamNotifyChild;
54 class PluginInstanceChild : public PPluginInstanceChild
55 {
56 friend class BrowserStreamChild;
57 friend class PluginStreamChild;
58 friend class StreamNotifyChild;
60 #ifdef OS_WIN
61 friend LRESULT CALLBACK PluginWindowProc(HWND hWnd,
62 UINT message,
63 WPARAM wParam,
64 LPARAM lParam);
65 static LRESULT CALLBACK PluginWindowProcInternal(HWND hWnd,
66 UINT message,
67 WPARAM wParam,
68 LPARAM lParam);
69 #endif
71 protected:
72 virtual bool AnswerNPP_SetWindow(const NPRemoteWindow& window) MOZ_OVERRIDE;
74 virtual bool
75 AnswerNPP_GetValue_NPPVpluginWantsAllNetworkStreams(bool* wantsAllStreams, NPError* rv) MOZ_OVERRIDE;
76 virtual bool
77 AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(bool* needs, NPError* rv) MOZ_OVERRIDE;
78 virtual bool
79 AnswerNPP_GetValue_NPPVpluginScriptableNPObject(PPluginScriptableObjectChild** value,
80 NPError* result) MOZ_OVERRIDE;
81 virtual bool
82 AnswerNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(nsCString* aPlugId,
83 NPError* aResult) MOZ_OVERRIDE;
84 virtual bool
85 AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value, NPError* result) MOZ_OVERRIDE;
87 virtual bool
88 AnswerNPP_HandleEvent(const NPRemoteEvent& event, int16_t* handled) MOZ_OVERRIDE;
89 virtual bool
90 AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event,
91 Shmem& mem,
92 int16_t* handled,
93 Shmem* rtnmem) MOZ_OVERRIDE;
94 virtual bool
95 AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
96 const uint32_t& surface,
97 int16_t* handled) MOZ_OVERRIDE;
99 // Async rendering
100 virtual bool
101 RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
102 const NPRemoteWindow& aWindow) MOZ_OVERRIDE;
104 virtual void
105 DoAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
106 const NPRemoteWindow& aWindow,
107 bool aIsAsync);
109 virtual PPluginSurfaceChild*
110 AllocPPluginSurfaceChild(const WindowsSharedMemoryHandle&,
111 const gfxIntSize&, const bool&) MOZ_OVERRIDE {
112 return new PPluginSurfaceChild();
113 }
115 virtual bool DeallocPPluginSurfaceChild(PPluginSurfaceChild* s) MOZ_OVERRIDE {
116 delete s;
117 return true;
118 }
120 virtual bool
121 AnswerPaint(const NPRemoteEvent& event, int16_t* handled) MOZ_OVERRIDE
122 {
123 PaintTracker pt;
124 return AnswerNPP_HandleEvent(event, handled);
125 }
127 virtual bool
128 RecvWindowPosChanged(const NPRemoteEvent& event) MOZ_OVERRIDE;
130 virtual bool
131 RecvContentsScaleFactorChanged(const double& aContentsScaleFactor) MOZ_OVERRIDE;
133 virtual bool
134 AnswerNPP_Destroy(NPError* result) MOZ_OVERRIDE;
136 virtual PPluginScriptableObjectChild*
137 AllocPPluginScriptableObjectChild() MOZ_OVERRIDE;
139 virtual bool
140 DeallocPPluginScriptableObjectChild(PPluginScriptableObjectChild* aObject) MOZ_OVERRIDE;
142 virtual bool
143 RecvPPluginScriptableObjectConstructor(PPluginScriptableObjectChild* aActor) MOZ_OVERRIDE;
145 virtual PBrowserStreamChild*
146 AllocPBrowserStreamChild(const nsCString& url,
147 const uint32_t& length,
148 const uint32_t& lastmodified,
149 PStreamNotifyChild* notifyData,
150 const nsCString& headers,
151 const nsCString& mimeType,
152 const bool& seekable,
153 NPError* rv,
154 uint16_t *stype) MOZ_OVERRIDE;
156 virtual bool
157 AnswerPBrowserStreamConstructor(
158 PBrowserStreamChild* aActor,
159 const nsCString& url,
160 const uint32_t& length,
161 const uint32_t& lastmodified,
162 PStreamNotifyChild* notifyData,
163 const nsCString& headers,
164 const nsCString& mimeType,
165 const bool& seekable,
166 NPError* rv,
167 uint16_t* stype) MOZ_OVERRIDE;
169 virtual bool
170 DeallocPBrowserStreamChild(PBrowserStreamChild* stream) MOZ_OVERRIDE;
172 virtual PPluginStreamChild*
173 AllocPPluginStreamChild(const nsCString& mimeType,
174 const nsCString& target,
175 NPError* result) MOZ_OVERRIDE;
177 virtual bool
178 DeallocPPluginStreamChild(PPluginStreamChild* stream) MOZ_OVERRIDE;
180 virtual PStreamNotifyChild*
181 AllocPStreamNotifyChild(const nsCString& url, const nsCString& target,
182 const bool& post, const nsCString& buffer,
183 const bool& file,
184 NPError* result) MOZ_OVERRIDE;
186 virtual bool
187 DeallocPStreamNotifyChild(PStreamNotifyChild* notifyData) MOZ_OVERRIDE;
189 virtual bool
190 AnswerSetPluginFocus() MOZ_OVERRIDE;
192 virtual bool
193 AnswerUpdateWindow() MOZ_OVERRIDE;
195 virtual bool
196 RecvNPP_DidComposite() MOZ_OVERRIDE;
198 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
199 bool CreateWindow(const NPRemoteWindow& aWindow);
200 void DeleteWindow();
201 #endif
203 public:
204 PluginInstanceChild(const NPPluginFuncs* aPluginIface);
206 virtual ~PluginInstanceChild();
208 bool Initialize();
210 NPP GetNPP()
211 {
212 return &mData;
213 }
215 NPError
216 NPN_GetValue(NPNVariable aVariable, void* aValue);
218 NPError
219 NPN_SetValue(NPPVariable aVariable, void* aValue);
221 PluginScriptableObjectChild*
222 GetActorForNPObject(NPObject* aObject);
224 NPError
225 NPN_NewStream(NPMIMEType aMIMEType, const char* aWindow,
226 NPStream** aStream);
228 void InvalidateRect(NPRect* aInvalidRect);
230 #ifdef MOZ_WIDGET_COCOA
231 void Invalidate();
232 #endif // definied(MOZ_WIDGET_COCOA)
234 uint32_t ScheduleTimer(uint32_t interval, bool repeat, TimerFunc func);
235 void UnscheduleTimer(uint32_t id);
237 void AsyncCall(PluginThreadCallback aFunc, void* aUserData);
239 int GetQuirks();
241 void NPN_URLRedirectResponse(void* notifyData, NPBool allow);
243 NPError NPN_InitAsyncSurface(NPSize *size, NPImageFormat format,
244 void *initData, NPAsyncSurface *surface);
245 NPError NPN_FinalizeAsyncSurface(NPAsyncSurface *surface);
247 void NPN_SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed);
249 void DoAsyncRedraw();
250 private:
251 friend class PluginModuleChild;
253 NPError
254 InternalGetNPObjectForValue(NPNVariable aValue,
255 NPObject** aObject);
257 bool IsAsyncDrawing();
259 NPError DeallocateAsyncBitmapSurface(NPAsyncSurface *aSurface);
261 virtual bool RecvUpdateBackground(const SurfaceDescriptor& aBackground,
262 const nsIntRect& aRect) MOZ_OVERRIDE;
264 virtual PPluginBackgroundDestroyerChild*
265 AllocPPluginBackgroundDestroyerChild() MOZ_OVERRIDE;
267 virtual bool
268 RecvPPluginBackgroundDestroyerConstructor(PPluginBackgroundDestroyerChild* aActor) MOZ_OVERRIDE;
270 virtual bool
271 DeallocPPluginBackgroundDestroyerChild(PPluginBackgroundDestroyerChild* aActor) MOZ_OVERRIDE;
273 #if defined(OS_WIN)
274 static bool RegisterWindowClass();
275 bool CreatePluginWindow();
276 void DestroyPluginWindow();
277 void ReparentPluginWindow(HWND hWndParent);
278 void SizePluginWindow(int width, int height);
279 int16_t WinlessHandleEvent(NPEvent& event);
280 void CreateWinlessPopupSurrogate();
281 void DestroyWinlessPopupSurrogate();
282 void InitPopupMenuHook();
283 void SetupFlashMsgThrottle();
284 void UnhookWinlessFlashThrottle();
285 void HookSetWindowLongPtr();
286 static inline bool SetWindowLongHookCheck(HWND hWnd,
287 int nIndex,
288 LONG_PTR newLong);
289 void FlashThrottleMessage(HWND, UINT, WPARAM, LPARAM, bool);
290 static LRESULT CALLBACK DummyWindowProc(HWND hWnd,
291 UINT message,
292 WPARAM wParam,
293 LPARAM lParam);
294 static LRESULT CALLBACK PluginWindowProc(HWND hWnd,
295 UINT message,
296 WPARAM wParam,
297 LPARAM lParam);
298 static BOOL WINAPI TrackPopupHookProc(HMENU hMenu,
299 UINT uFlags,
300 int x,
301 int y,
302 int nReserved,
303 HWND hWnd,
304 CONST RECT *prcRect);
305 static BOOL CALLBACK EnumThreadWindowsCallback(HWND hWnd,
306 LPARAM aParam);
307 static LRESULT CALLBACK WinlessHiddenFlashWndProc(HWND hWnd,
308 UINT message,
309 WPARAM wParam,
310 LPARAM lParam);
311 #ifdef _WIN64
312 static LONG_PTR WINAPI SetWindowLongPtrAHook(HWND hWnd,
313 int nIndex,
314 LONG_PTR newLong);
315 static LONG_PTR WINAPI SetWindowLongPtrWHook(HWND hWnd,
316 int nIndex,
317 LONG_PTR newLong);
319 #else
320 static LONG WINAPI SetWindowLongAHook(HWND hWnd,
321 int nIndex,
322 LONG newLong);
323 static LONG WINAPI SetWindowLongWHook(HWND hWnd,
324 int nIndex,
325 LONG newLong);
326 #endif
328 class FlashThrottleAsyncMsg : public ChildAsyncCall
329 {
330 public:
331 FlashThrottleAsyncMsg();
332 FlashThrottleAsyncMsg(PluginInstanceChild* aInst,
333 HWND aWnd, UINT aMsg,
334 WPARAM aWParam, LPARAM aLParam,
335 bool isWindowed)
336 : ChildAsyncCall(aInst, nullptr, nullptr),
337 mWnd(aWnd),
338 mMsg(aMsg),
339 mWParam(aWParam),
340 mLParam(aLParam),
341 mWindowed(isWindowed)
342 {}
344 void Run() MOZ_OVERRIDE;
346 WNDPROC GetProc();
347 HWND GetWnd() { return mWnd; }
348 UINT GetMsg() { return mMsg; }
349 WPARAM GetWParam() { return mWParam; }
350 LPARAM GetLParam() { return mLParam; }
352 private:
353 HWND mWnd;
354 UINT mMsg;
355 WPARAM mWParam;
356 LPARAM mLParam;
357 bool mWindowed;
358 };
360 #endif
361 const NPPluginFuncs* mPluginIface;
362 NPP_t mData;
363 NPWindow mWindow;
364 #if defined(XP_MACOSX)
365 double mContentsScaleFactor;
366 #endif
367 int16_t mDrawingModel;
368 NPAsyncSurface* mCurrentAsyncSurface;
369 struct AsyncBitmapData {
370 void *mRemotePtr;
371 Shmem mShmem;
372 };
374 static PLDHashOperator DeleteSurface(NPAsyncSurface* surf, nsAutoPtr<AsyncBitmapData> &data, void* userArg);
375 nsClassHashtable<nsPtrHashKey<NPAsyncSurface>, AsyncBitmapData> mAsyncBitmaps;
376 Shmem mRemoteImageDataShmem;
377 mozilla::layers::RemoteImageData *mRemoteImageData;
378 nsAutoPtr<CrossProcessMutex> mRemoteImageDataMutex;
379 mozilla::Mutex mAsyncInvalidateMutex;
380 CancelableTask *mAsyncInvalidateTask;
382 // Cached scriptable actors to avoid IPC churn
383 PluginScriptableObjectChild* mCachedWindowActor;
384 PluginScriptableObjectChild* mCachedElementActor;
386 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
387 NPSetWindowCallbackStruct mWsInfo;
388 #if (MOZ_WIDGET_GTK == 2)
389 bool mXEmbed;
390 XtClient mXtClient;
391 #endif
392 #elif defined(OS_WIN)
393 HWND mPluginWindowHWND;
394 WNDPROC mPluginWndProc;
395 HWND mPluginParentHWND;
396 int mNestedEventLevelDepth;
397 HWND mCachedWinlessPluginHWND;
398 HWND mWinlessPopupSurrogateHWND;
399 nsIntPoint mPluginSize;
400 WNDPROC mWinlessThrottleOldWndProc;
401 HWND mWinlessHiddenMsgHWND;
402 #endif
404 friend class ChildAsyncCall;
406 Mutex mAsyncCallMutex;
407 nsTArray<ChildAsyncCall*> mPendingAsyncCalls;
408 nsTArray<nsAutoPtr<ChildTimer> > mTimers;
410 /**
411 * During destruction we enumerate all remaining scriptable objects and
412 * invalidate/delete them. Enumeration can re-enter, so maintain a
413 * hash separate from PluginModuleChild.mObjectMap.
414 */
415 nsAutoPtr< nsTHashtable<DeletingObjectEntry> > mDeletingHash;
417 #if defined(OS_WIN)
418 private:
419 // Shared dib rendering management for windowless plugins.
420 bool SharedSurfaceSetWindow(const NPRemoteWindow& aWindow);
421 int16_t SharedSurfacePaint(NPEvent& evcopy);
422 void SharedSurfaceRelease();
423 bool AlphaExtractCacheSetup();
424 void AlphaExtractCacheRelease();
425 void UpdatePaintClipRect(RECT* aRect);
427 private:
428 enum {
429 RENDER_NATIVE,
430 RENDER_BACK_ONE,
431 RENDER_BACK_TWO
432 };
433 gfx::SharedDIBWin mSharedSurfaceDib;
434 struct {
435 uint16_t doublePass;
436 HDC hdc;
437 HBITMAP bmp;
438 } mAlphaExtract;
439 #endif // defined(OS_WIN)
440 #if defined(MOZ_WIDGET_COCOA)
441 private:
442 #if defined(__i386__)
443 NPEventModel mEventModel;
444 #endif
445 CGColorSpaceRef mShColorSpace;
446 CGContextRef mShContext;
447 mozilla::RefPtr<nsCARenderer> mCARenderer;
448 void *mCGLayer;
450 // Core Animation drawing model requires a refresh timer.
451 uint32_t mCARefreshTimer;
453 public:
454 const NPCocoaEvent* getCurrentEvent() {
455 return mCurrentEvent;
456 }
458 bool CGDraw(CGContextRef ref, nsIntRect aUpdateRect);
460 #if defined(__i386__)
461 NPEventModel EventModel() { return mEventModel; }
462 #endif
464 private:
465 const NPCocoaEvent *mCurrentEvent;
466 #endif
468 bool CanPaintOnBackground();
470 bool IsVisible() {
471 #ifdef XP_MACOSX
472 return mWindow.clipRect.top != mWindow.clipRect.bottom &&
473 mWindow.clipRect.left != mWindow.clipRect.right;
474 #else
475 return mWindow.clipRect.top != 0 ||
476 mWindow.clipRect.left != 0 ||
477 mWindow.clipRect.bottom != 0 ||
478 mWindow.clipRect.right != 0;
479 #endif
480 }
482 // ShowPluginFrame - in general does four things:
483 // 1) Create mCurrentSurface optimized for rendering to parent process
484 // 2) Updated mCurrentSurface to be a complete copy of mBackSurface
485 // 3) Draw the invalidated plugin area into mCurrentSurface
486 // 4) Send it to parent process.
487 bool ShowPluginFrame(void);
489 // If we can read back safely from mBackSurface, copy
490 // mSurfaceDifferenceRect from mBackSurface to mFrontSurface.
491 // @return Whether the back surface could be read.
492 bool ReadbackDifferenceRect(const nsIntRect& rect);
494 // Post ShowPluginFrame task
495 void AsyncShowPluginFrame(void);
497 // In the PaintRect functions, aSurface is the size of the full plugin
498 // window. Each PaintRect function renders into the subrectangle aRect of
499 // aSurface (possibly more if we're working around a Flash bug).
501 // Paint plugin content rectangle to surface with bg color filling
502 void PaintRectToSurface(const nsIntRect& aRect,
503 gfxASurface* aSurface,
504 const gfxRGBA& aColor);
506 // Render plugin content to surface using
507 // white/black image alpha extraction algorithm
508 void PaintRectWithAlphaExtraction(const nsIntRect& aRect,
509 gfxASurface* aSurface);
511 // Call plugin NPAPI function to render plugin content to surface
512 // @param - aSurface - should be compatible with current platform plugin rendering
513 // @return - FALSE if plugin not painted to surface
514 void PaintRectToPlatformSurface(const nsIntRect& aRect,
515 gfxASurface* aSurface);
517 // Update NPWindow platform attributes and call plugin "setwindow"
518 // @param - aForceSetWindow - call setwindow even if platform attributes are the same
519 void UpdateWindowAttributes(bool aForceSetWindow = false);
521 // Create optimized mCurrentSurface for parent process rendering
522 // @return FALSE if optimized surface not created
523 bool CreateOptSurface(void);
525 // Create mHelperSurface if mCurrentSurface non compatible with plugins
526 // @return TRUE if helper surface created successfully, or not needed
527 bool MaybeCreatePlatformHelperSurface(void);
529 // Make sure that we have surface for rendering
530 bool EnsureCurrentBuffer(void);
532 // Helper function for delayed InvalidateRect call
533 // non null mCurrentInvalidateTask will call this function
534 void InvalidateRectDelayed(void);
536 // Clear mCurrentSurface/mCurrentSurfaceActor/mHelperSurface
537 void ClearCurrentSurface();
539 // Swap mCurrentSurface/mBackSurface and their associated actors
540 void SwapSurfaces();
542 // Clear all surfaces in response to NPP_Destroy
543 void ClearAllSurfaces();
545 // Set as true when SetupLayer called
546 // and go with different path in InvalidateRect function
547 bool mLayersRendering;
549 // Current surface available for rendering
550 nsRefPtr<gfxASurface> mCurrentSurface;
552 // Back surface, just keeping reference to
553 // surface which is on ParentProcess side
554 nsRefPtr<gfxASurface> mBackSurface;
556 #ifdef XP_MACOSX
557 // Current IOSurface available for rendering
558 // We can't use thebes gfxASurface like other platforms.
559 PluginUtilsOSX::nsDoubleBufferCARenderer mDoubleBufferCARenderer;
560 #endif
562 // (Not to be confused with mBackSurface). This is a recent copy
563 // of the opaque pixels under our object frame, if
564 // |mIsTransparent|. We ask the plugin render directly onto a
565 // copy of the background pixels if available, and fall back on
566 // alpha recovery otherwise.
567 nsRefPtr<gfxASurface> mBackground;
569 #ifdef XP_WIN
570 // These actors mirror mCurrentSurface/mBackSurface
571 PPluginSurfaceChild* mCurrentSurfaceActor;
572 PPluginSurfaceChild* mBackSurfaceActor;
573 #endif
575 // Accumulated invalidate rect, while back buffer is not accessible,
576 // in plugin coordinates.
577 nsIntRect mAccumulatedInvalidRect;
579 // Plugin only call SetTransparent
580 // and does not remember their transparent state
581 // and p->getvalue return always false
582 bool mIsTransparent;
584 // Surface type optimized of parent process
585 gfxSurfaceType mSurfaceType;
587 // Keep InvalidateRect task pointer to be able Cancel it on Destroy
588 CancelableTask *mCurrentInvalidateTask;
590 // Keep AsyncSetWindow task pointer to be able to Cancel it on Destroy
591 CancelableTask *mCurrentAsyncSetWindowTask;
593 // True while plugin-child in plugin call
594 // Use to prevent plugin paint re-enter
595 bool mPendingPluginCall;
597 // On some platforms, plugins may not support rendering to a surface with
598 // alpha, or not support rendering to an image surface.
599 // In those cases we need to draw to a temporary platform surface; we cache
600 // that surface here.
601 nsRefPtr<gfxASurface> mHelperSurface;
603 // true when plugin does not support painting to ARGB32
604 // surface this is false if plugin supports
605 // NPPVpluginTransparentAlphaBool (which is not part of
606 // NPAPI yet)
607 bool mDoAlphaExtraction;
609 // true when the plugin has painted at least once. We use this to ensure
610 // that we ask a plugin to paint at least once even if it's invisible;
611 // some plugin (instances) rely on this in order to work properly.
612 bool mHasPainted;
614 // Cached rectangle rendered to previous surface(mBackSurface)
615 // Used for reading back to current surface and syncing data,
616 // in plugin coordinates.
617 nsIntRect mSurfaceDifferenceRect;
618 };
620 } // namespace plugins
621 } // namespace mozilla
623 #endif // ifndef dom_plugins_PluginInstanceChild_h