Bug 596451 part I - Read back from the current Windows surface, instead of repainting the entire client area every time, r-pending=jmathies

This commit is contained in:
Benjamin Smedberg 2010-10-27 09:09:15 -04:00
Родитель b69278fd2f
Коммит 0db29dc6c4
2 изменённых файлов: 42 добавлений и 21 удалений

Просмотреть файл

@ -2532,27 +2532,7 @@ PluginInstanceChild::ShowPluginFrame()
nsIntRect rect = mAccumulatedInvalidRect; nsIntRect rect = mAccumulatedInvalidRect;
mAccumulatedInvalidRect.Empty(); mAccumulatedInvalidRect.Empty();
#ifdef MOZ_X11 if (!ReadbackDifferenceRect(rect)) {
// We can read safely from XSurface, because PluginHost is not able to modify that surface
if (mBackSurface && mBackSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
if (!mSurfaceDifferenceRect.IsEmpty()) {
// Read back previous content
nsRefPtr<gfxContext> ctx = new gfxContext(mCurrentSurface);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetSource(mBackSurface);
// Subtract from mSurfaceDifferenceRect area which is overlapping with rect
nsIntRegion result;
result.Sub(mSurfaceDifferenceRect, nsIntRegion(rect));
nsIntRegionRectIterator iter(result);
const nsIntRect* r;
while ((r = iter.Next()) != nsnull) {
ctx->Rectangle(GfxFromNsRect(*r));
}
ctx->Fill();
}
} else
#endif
{
// Just repaint whole plugin, because we cannot read back from Shmem which is owned by another process // Just repaint whole plugin, because we cannot read back from Shmem which is owned by another process
rect.SetRect(0, 0, mWindow.width, mWindow.height); rect.SetRect(0, 0, mWindow.width, mWindow.height);
} }
@ -2611,6 +2591,42 @@ PluginInstanceChild::ShowPluginFrame()
return true; return true;
} }
bool
PluginInstanceChild::ReadbackDifferenceRect(const nsIntRect& rect)
{
if (!mBackSurface)
return false;
// We can read safely from XSurface and SharedDIBSurface, because
// PluginHost is not able to modify that surface
#if defined(MOZ_X11)
if (mBackSurface->GetType() != gfxASurface::SurfaceTypeXlib)
return false;
#elif defined(XP_WIN)
if (!SharedDIBSurface::IsSharedDIBSurface(mBackSurface))
return false;
#else
return false;
#endif
if (mSurfaceDifferenceRect.IsEmpty())
return true;
// Read back previous content
nsRefPtr<gfxContext> ctx = new gfxContext(mCurrentSurface);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetSource(mBackSurface);
// Subtract from mSurfaceDifferenceRect area which is overlapping with rect
nsIntRegion result;
result.Sub(mSurfaceDifferenceRect, nsIntRegion(rect));
nsIntRegionRectIterator iter(result);
const nsIntRect* r;
while ((r = iter.Next()) != nsnull) {
ctx->Rectangle(GfxFromNsRect(*r));
}
ctx->Fill();
}
void void
PluginInstanceChild::InvalidateRectDelayed(void) PluginInstanceChild::InvalidateRectDelayed(void)
{ {

Просмотреть файл

@ -394,6 +394,11 @@ private:
// 4) Send it to parent process. // 4) Send it to parent process.
bool ShowPluginFrame(void); bool ShowPluginFrame(void);
// If we can read back safely from mBackSurface, copy
// mSurfaceDifferenceRect from mBackSurface to mFrontSurface.
// @return Whether the back surface could be read.
bool ReadbackDifferenceRect(const nsIntRect& rect);
// Post ShowPluginFrame task // Post ShowPluginFrame task
void AsyncShowPluginFrame(void); void AsyncShowPluginFrame(void);