mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 629799, part 4: Fix alpha-recovery fallback on windows and try to use the SIMD path when possible. r=roc a=b
This commit is contained in:
parent
dcca6ef421
commit
d7b67cda16
@ -2538,8 +2538,8 @@ PluginInstanceChild::UpdateWindowAttributes(bool aForceSetWindow)
|
||||
HDC dc = NULL;
|
||||
|
||||
if (curSurface) {
|
||||
NS_ASSERTION(SharedDIBSurface::IsSharedDIBSurface(curSurface),
|
||||
"Expected (SharedDIB) image surface.");
|
||||
if (!SharedDIBSurface::IsSharedDIBSurface(curSurface))
|
||||
NS_RUNTIMEABORT("Expected SharedDIBSurface!");
|
||||
|
||||
SharedDIBSurface* dibsurf = static_cast<SharedDIBSurface*>(curSurface.get());
|
||||
dc = dibsurf->GetHDC();
|
||||
@ -2760,46 +2760,100 @@ void
|
||||
PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect,
|
||||
gfxASurface* aSurface)
|
||||
{
|
||||
// Paint onto black image
|
||||
bool needImageSurface = true;
|
||||
nsRefPtr<gfxImageSurface> blackImage;
|
||||
gfxIntSize clipSize(aRect.width, aRect.height);
|
||||
gfxPoint deviceOffset(-aRect.x, -aRect.y);
|
||||
// Try to re-use existing image surface, and avoid one copy
|
||||
if (aSurface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||
gfxImageSurface *surface = static_cast<gfxImageSurface*>(aSurface);
|
||||
if (surface->Format() == gfxASurface::ImageFormatARGB32) {
|
||||
needImageSurface = false;
|
||||
blackImage = surface->GetSubimage(GfxFromNsRect(aRect));
|
||||
NS_ABORT_IF_FALSE(aSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA,
|
||||
"Refusing to pointlessly recover alpha");
|
||||
|
||||
nsIntRect rect(aRect);
|
||||
// If |aSurface| can be used to paint and can have alpha values
|
||||
// recovered directly to it, do that to save a tmp surface and
|
||||
// copy.
|
||||
bool useSurfaceSubimageForBlack = false;
|
||||
if (gfxASurface::SurfaceTypeImage == aSurface->GetType()) {
|
||||
gfxImageSurface* surfaceAsImage =
|
||||
static_cast<gfxImageSurface*>(aSurface);
|
||||
useSurfaceSubimageForBlack =
|
||||
(surfaceAsImage->Format() == gfxASurface::ImageFormatARGB32);
|
||||
// If we're going to use a subimage, nudge the rect so that we
|
||||
// can use optimal alpha recovery. If we're not using a
|
||||
// subimage, the temporaries should automatically get
|
||||
// fast-path alpha recovery so we don't need to do anything.
|
||||
if (useSurfaceSubimageForBlack) {
|
||||
rect =
|
||||
gfxAlphaRecovery::AlignRectForSubimageRecovery(aRect,
|
||||
surfaceAsImage);
|
||||
}
|
||||
}
|
||||
// otherwise create new helper surface
|
||||
if (needImageSurface) {
|
||||
blackImage = new gfxImageSurface(clipSize, gfxASurface::ImageFormatARGB32);
|
||||
|
||||
nsRefPtr<gfxImageSurface> whiteImage;
|
||||
nsRefPtr<gfxImageSurface> blackImage;
|
||||
gfxRect targetRect(rect.x, rect.y, rect.width, rect.height);
|
||||
gfxIntSize targetSize(rect.width, rect.height);
|
||||
gfxPoint deviceOffset = -targetRect.pos;
|
||||
|
||||
// We always use a temporary "white image"
|
||||
whiteImage = new gfxImageSurface(targetSize, gfxASurface::ImageFormatRGB24);
|
||||
|
||||
#ifdef XP_WIN
|
||||
// On windows, we need an HDC and so can't paint directly to
|
||||
// vanilla image surfaces. Bifurcate this painting code so that
|
||||
// we don't accidentally attempt that.
|
||||
if (!SharedDIBSurface::IsSharedDIBSurface(aSurface))
|
||||
NS_RUNTIMEABORT("Expected SharedDIBSurface!");
|
||||
|
||||
// Paint the plugin directly onto the target, with a white
|
||||
// background and copy the result
|
||||
PaintRectToSurface(rect, aSurface, gfxRGBA(1.0, 1.0, 1.0));
|
||||
{
|
||||
gfxRect copyRect(gfxPoint(0, 0), targetRect.size);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(whiteImage);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(aSurface, deviceOffset);
|
||||
ctx->Rectangle(copyRect);
|
||||
ctx->Fill();
|
||||
}
|
||||
|
||||
// Paint to black image
|
||||
blackImage->SetDeviceOffset(deviceOffset);
|
||||
PaintRectToSurface(aRect, blackImage, gfxRGBA(0.0, 0.0, 0.0));
|
||||
// Paint the plugin directly onto the target, with a black
|
||||
// background
|
||||
PaintRectToSurface(rect, aSurface, gfxRGBA(0.0, 0.0, 0.0));
|
||||
|
||||
// Paint onto white image
|
||||
nsRefPtr<gfxImageSurface> whiteImage =
|
||||
new gfxImageSurface(clipSize, gfxASurface::ImageFormatRGB24);
|
||||
// Don't copy the result, just extract a subimage so that we can
|
||||
// recover alpha directly into the target
|
||||
gfxImageSurface *image = static_cast<gfxImageSurface*>(aSurface);
|
||||
blackImage = image->GetSubimage(targetRect);
|
||||
|
||||
#else
|
||||
// Paint onto white background
|
||||
whiteImage->SetDeviceOffset(deviceOffset);
|
||||
PaintRectToSurface(aRect, whiteImage, gfxRGBA(1.0, 1.0, 1.0));
|
||||
PaintRectToSurface(rect, whiteImage, gfxRGBA(1.0, 1.0, 1.0));
|
||||
|
||||
// Extract Alpha from black and white image and store to black Image
|
||||
gfxRect rect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage, nsnull)) {
|
||||
if (useSurfaceSubimageForBlack) {
|
||||
gfxImageSurface *surface = static_cast<gfxImageSurface*>(aSurface);
|
||||
blackImage = surface->GetSubimage(targetRect);
|
||||
} else {
|
||||
blackImage = new gfxImageSurface(targetSize,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
}
|
||||
|
||||
// Paint onto black background
|
||||
blackImage->SetDeviceOffset(deviceOffset);
|
||||
PaintRectToSurface(rect, blackImage, gfxRGBA(0.0, 0.0, 0.0));
|
||||
#endif
|
||||
|
||||
NS_ABORT_IF_FALSE(whiteImage && blackImage, "Didn't paint enough!");
|
||||
|
||||
// Extract alpha from black and white image and store to black
|
||||
// image
|
||||
if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (needImageSurface) {
|
||||
// If we had to use a temporary black surface, copy the pixels
|
||||
// with alpha back to the target
|
||||
if (!useSurfaceSubimageForBlack) {
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(blackImage);
|
||||
ctx->Rectangle(GfxFromNsRect(aRect));
|
||||
ctx->Rectangle(targetRect);
|
||||
ctx->Fill();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user