author | Benjamin Smedberg <benjamin@smedbergs.us> |
Fri, 05 Nov 2010 10:40:55 -0400 | |
changeset 57225 | 6ff3fcbb784501e3dc241e511aeea04ff759a468 |
parent 57224 | 24a2e0ac428f81256fc54025a8a9437dafde37b8 |
child 57226 | df0cf7e8e9e6611f0a723c3239625bd5b1e94339 |
push id | 16846 |
push user | bsmedberg@mozilla.com |
push date | Wed, 10 Nov 2010 15:29:47 +0000 |
treeherder | mozilla-central@bdbef533364f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 606285, 583109 |
milestone | 2.0b8pre |
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
|
--- a/dom/plugins/PPluginInstance.ipdl +++ b/dom/plugins/PPluginInstance.ipdl @@ -119,20 +119,16 @@ child: returns (int16_t handled); // this is only used on windows to forward WM_WINDOWPOSCHANGE async WindowPosChanged(NPRemoteEvent event); // ********************** Async plugins rendering // see https://wiki.mozilla.org/Gecko:AsyncPluginPainting // ********************** - // Plugin parent notify child that plugin frame - // has been painted to the screen - async PaintFinished(); - // Async version of SetWindow call // @param surfaceType - gfxASurface::gfxSurfaceType // plugin child must create offscreen buffer // with type equals to surfaceType async AsyncSetWindow(gfxSurfaceType surfaceType, NPRemoteWindow window); rpc NPP_Destroy() returns (NPError rv);
--- a/dom/plugins/PluginInstanceChild.cpp +++ b/dom/plugins/PluginInstanceChild.cpp @@ -2157,42 +2157,31 @@ PluginInstanceChild::NPN_NewStream(NPMIM return result; } *aStream = &ps->mStream; return NPERR_NO_ERROR; } bool -PluginInstanceChild::RecvPaintFinished(void) -{ - if (mPendingForcePaint) { - nsIntRect r(0, 0, mWindow.width, mWindow.height); - mAccumulatedInvalidRect.UnionRect(r, mAccumulatedInvalidRect); - mPendingForcePaint = false; - } - if (!mAccumulatedInvalidRect.IsEmpty()) { - AsyncShowPluginFrame(); - } - - return true; -} - -bool PluginInstanceChild::RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType, const NPRemoteWindow& aWindow) { AssertPluginThread(); mWindow.window = reinterpret_cast<void*>(aWindow.window); if (mWindow.width != aWindow.width || mWindow.height != aWindow.height) { mCurrentSurface = nsnull; mHelperSurface = nsnull; - mPendingForcePaint = true; + mAccumulatedInvalidRect = nsIntRect(0, 0, aWindow.width, aWindow.height); } + if (mWindow.clipRect.top != aWindow.clipRect.top || + mWindow.clipRect.left != aWindow.clipRect.left || + mWindow.clipRect.bottom != aWindow.clipRect.bottom || + mWindow.clipRect.right != aWindow.clipRect.right) mWindow.x = aWindow.x; mWindow.y = aWindow.y; mWindow.width = aWindow.width; mWindow.height = aWindow.height; mWindow.clipRect = aWindow.clipRect; mWindow.type = aWindow.type; @@ -2205,16 +2194,20 @@ PluginInstanceChild::RecvAsyncSetWindow( #ifdef XP_WIN if (mQuirks & QUIRK_WINLESS_TRACKPOPUP_HOOK) CreateWinlessPopupSurrogate(); if (mQuirks & QUIRK_FLASH_THROTTLE_WMUSER_EVENTS) SetupFlashMsgThrottle(); #endif + if (!mAccumulatedInvalidRect.IsEmpty()) { + AsyncShowPluginFrame(); + } + return true; } static inline gfxRect GfxFromNsRect(const nsIntRect& aRect) { return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height); } @@ -2425,33 +2418,36 @@ PluginInstanceChild::UpdateWindowAttribu needWindowUpdate = true; } #endif // XP_WIN if (!needWindowUpdate) { return; } - // The clip rect is relative to drawable top-left. - nsIntRect clipRect; #ifndef XP_WIN // On Windows, we translate the device context, in order for the window // origin to be correct. mWindow.x = mWindow.y = 0; #endif - // Don't ask the plugin to draw outside the drawable. The clip rect - // is in plugin coordinates, not window coordinates. - // This also ensures that the unsigned clip rectangle offsets won't be -ve. - clipRect.SetRect(0, 0, mWindow.width, mWindow.height); - - mWindow.clipRect.left = 0; - mWindow.clipRect.top = 0; - mWindow.clipRect.right = clipRect.XMost(); - mWindow.clipRect.bottom = clipRect.YMost(); + if (IsVisible()) { + // The clip rect is relative to drawable top-left. + nsIntRect clipRect; + + // Don't ask the plugin to draw outside the drawable. The clip rect + // is in plugin coordinates, not window coordinates. + // This also ensures that the unsigned clip rectangle offsets won't be -ve. + clipRect.SetRect(0, 0, mWindow.width, mWindow.height); + + mWindow.clipRect.left = 0; + mWindow.clipRect.top = 0; + mWindow.clipRect.right = clipRect.XMost(); + mWindow.clipRect.bottom = clipRect.YMost(); + } #ifdef XP_WIN // Windowless plugins on Windows need a WM_WINDOWPOSCHANGED event to update // their location... or at least Flash does: Silverlight uses the // window.x/y passed to NPP_SetWindow if (mPluginIface->event) { WINDOWPOS winpos = { @@ -2787,34 +2783,34 @@ PluginInstanceChild::ReadbackDifferenceR ctx->Fill(); return true; } void PluginInstanceChild::InvalidateRectDelayed(void) { - if (!mCurrentInvalidateTask) { + if (!mCurrentInvalidateTask || !IsVisible()) { return; } mCurrentInvalidateTask = nsnull; if (mAccumulatedInvalidRect.IsEmpty()) { return; } if (!ShowPluginFrame()) { AsyncShowPluginFrame(); } } void PluginInstanceChild::AsyncShowPluginFrame(void) { - if (mCurrentInvalidateTask) { + if (mCurrentInvalidateTask || !IsVisible()) { return; } mCurrentInvalidateTask = NewRunnableMethod(this, &PluginInstanceChild::InvalidateRectDelayed); MessageLoop::current()->PostTask(FROM_HERE, mCurrentInvalidateTask); }
--- a/dom/plugins/PluginInstanceChild.h +++ b/dom/plugins/PluginInstanceChild.h @@ -97,17 +97,16 @@ protected: AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event, Shmem& mem, int16_t* handled, Shmem* rtnmem); virtual bool AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event, const uint32_t& surface, int16_t* handled); // Async rendering virtual bool RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType, const NPRemoteWindow& aWindow); - virtual bool RecvPaintFinished(void); NS_OVERRIDE virtual bool AnswerPaint(const NPRemoteEvent& event, int16_t* handled) { PaintTracker pt; return AnswerNPP_HandleEvent(event, handled); } @@ -404,16 +403,23 @@ public: #if defined(__i386__) NPEventModel EventModel() { return mEventModel; } #endif private: const NPCocoaEvent *mCurrentEvent; #endif + bool IsVisible() { + return mWindow.clipRect.top != 0 || + mWindow.clipRect.left != 0 || + mWindow.clipRect.bottom != 0 || + mWindow.clipRect.right != 0; + } + // ShowPluginFrame - in general does four things: // 1) Create mCurrentSurface optimized for rendering to parent process // 2) Updated mCurrentSurface to be a complete copy of mBackSurface // 3) Draw the invalidated plugin area into mCurrentSurface // 4) Send it to parent process. bool ShowPluginFrame(void); // If we can read back safely from mBackSurface, copy
--- a/dom/plugins/PluginInstanceParent.cpp +++ b/dom/plugins/PluginInstanceParent.cpp @@ -96,17 +96,16 @@ PluginInstanceParent::PluginInstancePare , mQuirks(0) #if defined(XP_MACOSX) , mShWidth(0) , mShHeight(0) , mShColorSpace(nsnull) , mDrawingModel(NPDrawingModelCoreGraphics) , mIOSurface(nsnull) #endif - , mSentPaintNotification(PR_FALSE) { InitQuirksModes(aMimeType); } void PluginInstanceParent::InitQuirksModes(const nsCString& aMimeType) { #ifdef OS_MACOSX @@ -503,18 +502,16 @@ PluginInstanceParent::RecvShow(const NPR else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorWin) { SurfaceDescriptorWin windesc = newSurface.get_SurfaceDescriptorWin(); SharedDIBSurface* dibsurf = new SharedDIBSurface(); if (dibsurf->Attach(windesc.handle(), windesc.size().width, windesc.size().height, windesc.transparent())) surface = dibsurf; } #endif - mSentPaintNotification = PR_FALSE; - #ifdef MOZ_X11 if (mFrontSurface && mFrontSurface->GetType() == gfxASurface::SurfaceTypeXlib) XSync(DefaultXDisplay(), False); #endif if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface)) *prevSurface = static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem(); @@ -534,36 +531,24 @@ PluginInstanceParent::AsyncSetWindow(NPW mWindowType = aWindow->type; window.window = reinterpret_cast<unsigned long>(aWindow->window); window.x = aWindow->x; window.y = aWindow->y; window.width = aWindow->width; window.height = aWindow->height; window.clipRect = aWindow->clipRect; window.type = aWindow->type; - mSentPaintNotification = PR_FALSE; if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(), window)) return NS_ERROR_FAILURE; return NS_OK; } nsresult -PluginInstanceParent::NotifyPainted(void) -{ - bool rv = true; - if (!mSentPaintNotification) { - rv = SendPaintFinished(); - mSentPaintNotification = rv; - } - return rv ? NS_OK : NS_ERROR_FAILURE; -} - -nsresult PluginInstanceParent::GetSurface(gfxASurface** aSurface) { if (mFrontSurface) { NS_ADDREF(*aSurface = mFrontSurface); return NS_OK; } return NS_ERROR_NOT_AVAILABLE; }
--- a/dom/plugins/PluginInstanceParent.h +++ b/dom/plugins/PluginInstanceParent.h @@ -256,17 +256,16 @@ public: virtual bool AnswerPluginFocusChange(const bool& gotFocus); #if defined(OS_MACOSX) void Invalidate(); #endif // definied(OS_MACOSX) nsresult AsyncSetWindow(NPWindow* window); - nsresult NotifyPainted(void); nsresult GetSurface(gfxASurface** aSurface); private: // Quirks mode support for various plugin mime types enum PluginQuirks { // OSX: Don't use the refresh timer for plug-ins // using this quirk. These plug-in most have another // way to refresh the window. @@ -316,18 +315,15 @@ private: size_t mShHeight; CGColorSpaceRef mShColorSpace; int16_t mDrawingModel; nsIOSurface *mIOSurface; #endif // definied(OS_MACOSX) // ObjectFrame layer wrapper nsRefPtr<gfxASurface> mFrontSurface; - - // Don't spam plugin process with extra paint notifications - PRPackedBool mSentPaintNotification; }; } // namespace plugins } // namespace mozilla #endif // ifndef dom_plugins_PluginInstanceParent_h
--- a/dom/plugins/PluginLibrary.h +++ b/dom/plugins/PluginLibrary.h @@ -75,17 +75,16 @@ public: virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) = 0; #endif virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved, NPError* error) = 0; virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window) = 0; - virtual nsresult NotifyPainted(NPP instance) = 0; virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface) = 0; virtual bool UseAsyncPainting() = 0; }; } // namespace mozilla #endif // ifndef mozilla_PluginLibrary_h
--- a/dom/plugins/PluginModuleParent.cpp +++ b/dom/plugins/PluginModuleParent.cpp @@ -619,26 +619,16 @@ PluginModuleParent::AsyncSetWindow(NPP i PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->AsyncSetWindow(window); } nsresult -PluginModuleParent::NotifyPainted(NPP instance) -{ - PluginInstanceParent* i = InstCast(instance); - if (!i) - return NS_ERROR_FAILURE; - - return i->NotifyPainted(); -} - -nsresult PluginModuleParent::GetSurface(NPP instance, gfxASurface** aSurface) { PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->GetSurface(aSurface); }
--- a/dom/plugins/PluginModuleParent.h +++ b/dom/plugins/PluginModuleParent.h @@ -217,17 +217,16 @@ private: NPReason reason, void* notifyData); static NPError NPP_GetValue(NPP instance, NPPVariable variable, void *ret_value); static NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value); virtual bool HasRequiredFunctions(); virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window); - virtual nsresult NotifyPainted(NPP instance); virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface); NS_OVERRIDE virtual bool UseAsyncPainting() { return true; } #if defined(XP_UNIX) && !defined(XP_MACOSX) virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error); #else virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error); #endif
--- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -1103,19 +1103,16 @@ nsObjectFrame::CallSetWindow() !win) return; nsPluginNativeWindow *window = (nsPluginNativeWindow *)win; #ifdef XP_MACOSX mInstanceOwner->FixUpPluginWindow(ePluginPaintDisable); #endif - if (IsHidden()) - return; - // refresh the plugin port as well window->window = mInstanceOwner->GetPluginPortFromWidget(); // Adjust plugin dimensions according to pixel snap results // and reduce amount of SetWindow calls nsPresContext* presContext = PresContext(); nsRootPresContext* rootPC = presContext->GetRootPresContext(); if (!rootPC) @@ -1733,37 +1730,43 @@ nsObjectFrame::BuildLayer(nsDisplayListB NPWindow* window = nsnull; mInstanceOwner->GetWindow(window); if (!window) return nsnull; if (window->width <= 0 || window->height <= 0) return nsnull; +#ifndef XP_MACOSX + mInstanceOwner->UpdateWindowVisibility(PR_TRUE); +#endif + nsRect area = GetContentRect() + aBuilder->ToReferenceFrame(GetParent()); gfxRect r = nsLayoutUtils::RectToGfxRect(area, PresContext()->AppUnitsPerDevPixel()); // to provide crisper and faster drawing. r.Round(); nsRefPtr<Layer> layer = (aBuilder->LayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem)); if (!layer) { mInstanceOwner->NotifyPaintWaiter(aBuilder, aManager); // Initialize ImageLayer layer = aManager->CreateImageLayer(); } +#if 0 nsCOMPtr<nsIPluginInstance> pi; mInstanceOwner->GetInstance(*getter_AddRefs(pi)); // Give plugin info about layer paint if (pi) { if (NS_FAILED(pi->NotifyPainted())) { return nsnull; } } +#endif if (!layer) return nsnull; NS_ASSERTION(layer->GetType() == Layer::TYPE_IMAGE, "ObjectFrame works only with ImageLayer"); // Create image nsRefPtr<ImageContainer> container = GetImageContainer(); if (!container) @@ -1938,18 +1941,16 @@ nsObjectFrame::PaintPlugin(nsDisplayList } dirtyGfxRect.RoundOut(); // Look if it's windowless NPWindow *window; mInstanceOwner->GetWindow(window); if (window->type == NPWindowTypeDrawable) { - // check if we need to call SetWindow with updated parameters - PRBool doupdatewindow = PR_FALSE; // the offset of the DC nsPoint origin; gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect); #ifdef MOZ_IPC if (nativeDraw.IsDoublePass()) { // OOP plugin specific: let the shim know before we paint if we are doing a // double pass render. If this plugin isn't oop, the register window message @@ -1974,16 +1975,21 @@ nsObjectFrame::PaintPlugin(nsDisplayList // XXX how can we be sure that window->window doesn't point to // a dead DC and hdc has been reallocated at the same address? if (reinterpret_cast<HDC>(window->window) != hdc || window->x != dest.left || window->y != dest.top) { window->window = hdc; window->x = dest.left; window->y = dest.top; + window->clipRect.left = 0; + window->clipRect.top = 0; + // if we're painting, we're visible. + window->clipRect.right = window->width; + window->clipRect.bottom = window->height; // Windowless plugins on windows need a special event to update their location, // see bug 135737. // // bug 271442: note, the rectangle we send is now purely the bounds of the plugin // relative to the window it is contained in, which is useful for the plugin to // correctly translate mouse coordinates. // @@ -1996,19 +2002,17 @@ nsObjectFrame::PaintPlugin(nsDisplayList // the originator of bug 135737), it seems that windowless plugins are not relying // on information here for clipping their drawing, and we can safely use this message // to tell the plugin exactly where it is in all cases. nsIntPoint origin = GetWindowOriginInPixels(PR_TRUE); nsIntRect winlessRect = nsIntRect(origin, nsIntSize(window->width, window->height)); // XXX I don't think we can be certain that the location wrt to // the window only changes when the location wrt to the drawable - // changes, but the hdc probably changes on every paint so - // doupdatewindow is rarely false, and there is not likely to be - // a problem. + // changes, but the hdc probably changes on every paint. if (mWindowlessRect != winlessRect) { mWindowlessRect = winlessRect; WINDOWPOS winpos; memset(&winpos, 0, sizeof(winpos)); winpos.x = mWindowlessRect.x; winpos.y = mWindowlessRect.y; winpos.cx = mWindowlessRect.width; @@ -6453,17 +6457,17 @@ void* nsPluginInstanceOwner::FixUpPlugin void nsPluginInstanceOwner::UpdateWindowClipRect(PRBool aSetWindow) { if (!mPluginWindow) return; // For windowless plugins a non-empty clip rectangle will be // passed to the plugin during paint, an additional update // of the the clip rectangle here is not required - if (aSetWindow && !mWidget && mPluginWindowVisible) + if (aSetWindow && !mWidget && mPluginWindowVisible && !UseLayers()) return; const NPRect oldClipRect = mPluginWindow->clipRect; mPluginWindow->clipRect.left = 0; mPluginWindow->clipRect.top = 0; if (mPluginWindowVisible) {
--- a/modules/plugin/base/src/PluginPRLibrary.cpp +++ b/modules/plugin/base/src/PluginPRLibrary.cpp @@ -190,24 +190,16 @@ nsresult PluginPRLibrary::AsyncSetWindow(NPP instance, NPWindow* window) { nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); return NS_ERROR_NOT_IMPLEMENTED; } nsresult -PluginPRLibrary::NotifyPainted(NPP instance) -{ - nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; - NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult PluginPRLibrary::GetSurface(NPP instance, gfxASurface** aSurface) { nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); *aSurface = nsnull; return NS_OK; }
--- a/modules/plugin/base/src/PluginPRLibrary.h +++ b/modules/plugin/base/src/PluginPRLibrary.h @@ -129,17 +129,16 @@ public: #endif virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved, NPError* error); virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window); - virtual nsresult NotifyPainted(NPP instance); virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface); NS_OVERRIDE virtual bool UseAsyncPainting() { return false; } private: NP_InitializeFunc mNP_Initialize; NP_ShutdownFunc mNP_Shutdown; NP_GetMIMEDescriptionFunc mNP_GetMIMEDescription; #if defined(XP_UNIX) && !defined(XP_MACOSX)
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp +++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp @@ -850,29 +850,18 @@ nsNPAPIPluginInstance::GetSurface(gfxASu return library->GetSurface(&mNPP, aSurface); } NS_IMETHODIMP nsNPAPIPluginInstance::NotifyPainted(void) { - if (RUNNING != mRunning) - return NS_OK; - - PluginDestructionGuard guard(this); - - if (!mPlugin) - return NS_ERROR_FAILURE; - - PluginLibrary* library = mPlugin->GetLibrary(); - if (!library) - return NS_ERROR_FAILURE; - - return library->NotifyPainted(&mNPP); + NS_NOTREACHED("Dead code, shouldn't be called."); + return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP nsNPAPIPluginInstance::UseAsyncPainting(PRBool* aIsAsync) { if (!mUsePluginLayersPref) { *aIsAsync = mUsePluginLayersPref; return NS_OK;