Bug 601064. Ensure we ask each plugin instance to paint at least once. Some plugin instances assume they will be asked to paint even if they're always invisible. r=bsmedberg,a=blocking

This commit is contained in:
Robert O'Callahan 2011-01-04 16:56:05 +13:00
parent dd702c0785
commit d743af006f
2 changed files with 50 additions and 32 deletions

View File

@ -143,6 +143,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface)
, mCurrentAsyncSetWindowTask(nsnull) , mCurrentAsyncSetWindowTask(nsnull)
, mPendingPluginCall(false) , mPendingPluginCall(false)
, mDoAlphaExtraction(false) , mDoAlphaExtraction(false)
, mHasPainted(false)
, mSurfaceDifferenceRect(0,0,0,0) , mSurfaceDifferenceRect(0,0,0,0)
#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
, mMaemoImageRendering(PR_FALSE) , mMaemoImageRendering(PR_FALSE)
@ -2558,7 +2559,8 @@ PluginInstanceChild::UpdateWindowAttributes(bool aForceSetWindow)
WINDOWPOS winpos = { WINDOWPOS winpos = {
0, 0, 0, 0,
mWindow.x, mWindow.y, mWindow.x, mWindow.y,
mWindow.width, mWindow.height mWindow.width, mWindow.height,
0
}; };
NPEvent pluginEvent = { NPEvent pluginEvent = {
WM_WINDOWPOSCHANGED, 0, WM_WINDOWPOSCHANGED, 0,
@ -2571,15 +2573,20 @@ PluginInstanceChild::UpdateWindowAttributes(bool aForceSetWindow)
if (mPluginIface->setwindow) { if (mPluginIface->setwindow) {
mPluginIface->setwindow(&mData, &mWindow); mPluginIface->setwindow(&mData, &mWindow);
} }
return;
} }
void void
PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect, PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
gfxASurface* aSurface) gfxASurface* aSurface)
{ {
bool temporarilyMakeVisible = !IsVisible() && !mHasPainted;
if (temporarilyMakeVisible) {
mWindow.clipRect.right = mWindow.width;
mWindow.clipRect.bottom = mWindow.height;
}
UpdateWindowAttributes(); UpdateWindowAttributes();
#ifdef MOZ_X11 #ifdef MOZ_X11
#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6) #if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
// On maemo5 we do support Image rendering NPAPI // On maemo5 we do support Image rendering NPAPI
@ -2618,32 +2625,30 @@ PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
exposeEvent.major_code = 0; exposeEvent.major_code = 0;
exposeEvent.minor_code = 0; exposeEvent.minor_code = 0;
mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent)); mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
return; } else
#endif
{
NS_ASSERTION(aSurface->GetType() == gfxASurface::SurfaceTypeXlib,
"Non supported platform surface type");
NPEvent pluginEvent;
XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
exposeEvent.type = GraphicsExpose;
exposeEvent.display = mWsInfo.display;
exposeEvent.drawable = static_cast<gfxXlibSurface*>(aSurface)->XDrawable();
exposeEvent.x = aRect.x;
exposeEvent.y = aRect.y;
exposeEvent.width = aRect.width;
exposeEvent.height = aRect.height;
exposeEvent.count = 0;
// information not set:
exposeEvent.serial = 0;
exposeEvent.send_event = False;
exposeEvent.major_code = 0;
exposeEvent.minor_code = 0;
mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
} }
#endif #elif defined(XP_WIN)
NS_ASSERTION(aSurface->GetType() == gfxASurface::SurfaceTypeXlib,
"Non supported platform surface type");
NPEvent pluginEvent;
XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
exposeEvent.type = GraphicsExpose;
exposeEvent.display = mWsInfo.display;
exposeEvent.drawable = static_cast<gfxXlibSurface*>(aSurface)->XDrawable();
exposeEvent.x = aRect.x;
exposeEvent.y = aRect.y;
exposeEvent.width = aRect.width;
exposeEvent.height = aRect.height;
exposeEvent.count = 0;
// information not set:
exposeEvent.serial = 0;
exposeEvent.send_event = False;
exposeEvent.major_code = 0;
exposeEvent.minor_code = 0;
mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
return;
#endif
#ifdef XP_WIN
NS_ASSERTION(SharedDIBSurface::IsSharedDIBSurface(aSurface), NS_ASSERTION(SharedDIBSurface::IsSharedDIBSurface(aSurface),
"Expected (SharedDIB) image surface."); "Expected (SharedDIB) image surface.");
@ -2663,10 +2668,17 @@ PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
::SetViewportOrgEx((HDC) mWindow.window, -mWindow.x, -mWindow.y, NULL); ::SetViewportOrgEx((HDC) mWindow.window, -mWindow.x, -mWindow.y, NULL);
mPluginIface->event(&mData, reinterpret_cast<void*>(&paintEvent)); mPluginIface->event(&mData, reinterpret_cast<void*>(&paintEvent));
return; #else
NS_RUNTIMEABORT("Surface type not implemented.");
#endif #endif
NS_RUNTIMEABORT("Surface type not implemented."); if (temporarilyMakeVisible) {
mWindow.clipRect.right = mWindow.clipRect.bottom = 0;
if (mPluginIface->setwindow) {
mPluginIface->setwindow(&mData, &mWindow);
}
}
} }
void void
@ -2800,6 +2812,7 @@ PluginInstanceChild::ShowPluginFrame()
} else { } else {
PaintRectToSurface(rect, mCurrentSurface, gfxRGBA(0.0, 0.0, 0.0, 0.0)); PaintRectToSurface(rect, mCurrentSurface, gfxRGBA(0.0, 0.0, 0.0, 0.0));
} }
mHasPainted = true;
NPRect r = { (uint16_t)rect.y, (uint16_t)rect.x, NPRect r = { (uint16_t)rect.y, (uint16_t)rect.x,
(uint16_t)rect.YMost(), (uint16_t)rect.XMost() }; (uint16_t)rect.YMost(), (uint16_t)rect.XMost() };
@ -2897,7 +2910,7 @@ PluginInstanceChild::InvalidateRectDelayed(void)
} }
mCurrentInvalidateTask = nsnull; mCurrentInvalidateTask = nsnull;
if (mAccumulatedInvalidRect.IsEmpty() || !IsVisible()) { if (mAccumulatedInvalidRect.IsEmpty() || (mHasPainted && !IsVisible())) {
return; return;
} }
@ -2909,7 +2922,7 @@ PluginInstanceChild::InvalidateRectDelayed(void)
void void
PluginInstanceChild::AsyncShowPluginFrame(void) PluginInstanceChild::AsyncShowPluginFrame(void)
{ {
if (mCurrentInvalidateTask || !IsVisible()) { if (mCurrentInvalidateTask || (mHasPainted && !IsVisible())) {
return; return;
} }

View File

@ -501,6 +501,11 @@ private:
// supports NPPVpluginTransparentAlphaBool (which is not part of NPAPI yet) // supports NPPVpluginTransparentAlphaBool (which is not part of NPAPI yet)
bool mDoAlphaExtraction; bool mDoAlphaExtraction;
// true when the plugin has painted at least once. We use this to ensure
// that we ask a plugin to paint at least once even if it's invisible;
// some plugin (instances) rely on this in order to work properly.
bool mHasPainted;
// Cached rectangle rendered to previous surface(mBackSurface) // Cached rectangle rendered to previous surface(mBackSurface)
// Used for reading back to current surface and syncing data, // Used for reading back to current surface and syncing data,
// in plugin coordinates. // in plugin coordinates.