Bug 1196927 - Force plugin BGRX image surface data to always have valid alpha. r=jrmuizel, r=BenWa

This commit is contained in:
Lee Salzman 2015-08-25 18:28:03 -04:00
Родитель 464e664e73
Коммит fe3e6b99bc
1 изменённых файлов: 25 добавлений и 12 удалений

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

@ -104,18 +104,14 @@ struct RunnableMethodTraits<PluginInstanceChild>
static RefPtr<DrawTarget>
CreateDrawTargetForSurface(gfxASurface *aSurface)
{
SurfaceFormat format;
if (aSurface->GetContentType() == gfxContentType::ALPHA) {
format = SurfaceFormat::A8;
} else if (aSurface->GetContentType() == gfxContentType::COLOR) {
format = SurfaceFormat::B8G8R8X8;
} else {
format = SurfaceFormat::B8G8R8A8;
}
SurfaceFormat format = aSurface->GetSurfaceFormat();
RefPtr<DrawTarget> drawTarget =
Factory::CreateDrawTargetForCairoSurface(aSurface->CairoSurface(),
aSurface->GetSize(),
&format);
if (!drawTarget) {
NS_RUNTIMEABORT("CreateDrawTargetForSurface failed in plugin");
}
aSurface->SetData(&kDrawTarget, drawTarget, nullptr);
return drawTarget;
}
@ -3257,11 +3253,28 @@ PluginInstanceChild::PaintRectToSurface(const nsIntRect& aRect,
PaintRectToPlatformSurface(plPaintRect, renderSurface);
if (renderSurface != aSurface) {
RefPtr<DrawTarget> dt;
if (aSurface == mCurrentSurface &&
aSurface->GetType() == gfxSurfaceType::Image &&
aSurface->GetSurfaceFormat() == SurfaceFormat::B8G8R8X8) {
gfxImageSurface* imageSurface = static_cast<gfxImageSurface*>(aSurface);
// Bug 1196927 - Reinterpret target surface as BGRA to fill alpha with opaque.
// Certain backends (i.e. Skia) may not truly support BGRX formats, so they must
// be emulated by filling the alpha channel opaque as if it was BGRA data. Cairo
// leaves the alpha zeroed out for BGRX, so we cause Cairo to fill it as opaque
// by handling the copy target as a BGRA surface.
dt = Factory::CreateDrawTargetForData(BackendType::CAIRO,
imageSurface->Data(),
imageSurface->GetSize(),
imageSurface->Stride(),
SurfaceFormat::B8G8R8A8);
} else {
// Copy helper surface content to target
RefPtr<DrawTarget> dt = CreateDrawTargetForSurface(aSurface);
RefPtr<SourceSurface> surface =
gfxPlatform::GetSourceSurfaceForSurface(dt, renderSurface);
dt->CopySurface(surface, aRect, aRect.TopLeft());
dt = CreateDrawTargetForSurface(aSurface);
}
RefPtr<SourceSurface> surface =
gfxPlatform::GetSourceSurfaceForSurface(dt, renderSurface);
dt->CopySurface(surface, aRect, aRect.TopLeft());
}
}