diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp index 1e24d7593473..de6714a46e2d 100644 --- a/widget/gtk2/nsWindow.cpp +++ b/widget/gtk2/nsWindow.cpp @@ -2112,12 +2112,31 @@ nsWindow::OnExposeEvent(cairo_t *cr) return TRUE; } + gfxASurface* surf; #if defined(MOZ_WIDGET_GTK2) - nsRefPtr ctx = new gfxContext(GetThebesSurface()); + surf = GetThebesSurface(); #else - nsRefPtr ctx = new gfxContext(GetThebesSurface(cr)); + surf = GetThebesSurface(cr); #endif + nsRefPtr ctx; + if (gfxPlatform::GetPlatform()-> + SupportsAzureContentForType(BACKEND_CAIRO)) { + IntSize intSize(surf->GetSize().width, surf->GetSize().height); + ctx = new gfxContext(gfxPlatform::GetPlatform()-> + CreateDrawTargetForSurface(surf, intSize)); + } else if (gfxPlatform::GetPlatform()-> + SupportsAzureContentForType(BACKEND_SKIA) && + surf->GetType() != gfxASurface::SurfaceTypeImage) { + gfxImageSurface* imgSurf = static_cast(surf); + SurfaceFormat format = ImageFormatToSurfaceFormat(imgSurf->Format()); + IntSize intSize(surf->GetSize().width, surf->GetSize().height); + ctx = new gfxContext(gfxPlatform::GetPlatform()->CreateDrawTargetForData( + imgSurf->Data(), intSize, imgSurf->Stride(), format)); + } else { + ctx = new gfxContext(surf); + } + #ifdef MOZ_X11 nsIntRect boundsRect; // for shaped only @@ -2181,23 +2200,7 @@ nsWindow::OnExposeEvent(cairo_t *cr) if (painted) { nsRefPtr pattern = ctx->PopGroup(); - nsRefPtr img = - new gfxImageSurface(gfxIntSize(boundsRect.width, boundsRect.height), - gfxImageSurface::ImageFormatA8); - if (img && !img->CairoStatus()) { - img->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y)); - - nsRefPtr imgCtx = new gfxContext(img); - if (imgCtx) { - imgCtx->SetPattern(pattern); - imgCtx->SetOperator(gfxContext::OPERATOR_SOURCE); - imgCtx->Paint(); - } - - UpdateTranslucentWindowAlphaInternal(nsIntRect(boundsRect.x, boundsRect.y, - boundsRect.width, boundsRect.height), - img->Data(), img->Stride()); - } + UpdateAlpha(pattern, boundsRect); ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetPattern(pattern); @@ -2245,6 +2248,44 @@ nsWindow::OnExposeEvent(cairo_t *cr) return TRUE; } +void +nsWindow::UpdateAlpha(gfxPattern* aPattern, nsIntRect aBoundsRect) +{ + if (gfxPlatform::GetPlatform()->SupportsAzureContent()) { + // We need to create our own buffer to force the stride to match the + // expected stride. + int32_t stride = GetAlignedStride<4>(BytesPerPixel(FORMAT_A8) * + aBoundsRect.width); + int32_t bufferSize = stride * aBoundsRect.height; + nsAutoArrayPtr imageBuffer(new (std::nothrow) PRUint8[bufferSize]); + RefPtr drawTarget = gfxPlatform::GetPlatform()-> + CreateDrawTargetForData(imageBuffer, ToIntSize(aBoundsRect.Size()), + stride, FORMAT_A8); + + if (drawTarget) { + drawTarget->FillRect(ToRect(aBoundsRect), + *aPattern->GetPattern(drawTarget), + DrawOptions(1.0, OP_SOURCE)); + } + UpdateTranslucentWindowAlphaInternal(aBoundsRect, imageBuffer, stride); + } else { + nsRefPtr img = + new gfxImageSurface(ThebesIntSize(aBoundsRect.Size()), + gfxImageSurface::ImageFormatA8); + if (img && !img->CairoStatus()) { + img->SetDeviceOffset(-aBoundsRect.TopLeft()); + + nsRefPtr imgCtx = new gfxContext(img); + imgCtx->SetPattern(aPattern); + imgCtx->SetOperator(gfxContext::OPERATOR_SOURCE); + imgCtx->Paint(); + + UpdateTranslucentWindowAlphaInternal(aBoundsRect, img->Data(), + img->Stride()); + } + } +} + gboolean nsWindow::OnConfigureEvent(GtkWidget *aWidget, GdkEventConfigure *aEvent) { diff --git a/widget/gtk2/nsWindow.h b/widget/gtk2/nsWindow.h index 076a8e16d087..75ec970164aa 100644 --- a/widget/gtk2/nsWindow.h +++ b/widget/gtk2/nsWindow.h @@ -64,6 +64,7 @@ extern PRLogModuleInfo *gWidgetDrawLog; #endif /* MOZ_LOGGING */ +class gfxPattern; class nsDragService; #if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) # define MOZ_HAVE_SHMIMAGE @@ -201,6 +202,8 @@ public: #endif private: + void UpdateAlpha(gfxPattern* aPattern, nsIntRect aBoundsRect); + void NativeResize(int32_t aWidth, int32_t aHeight, bool aRepaint);