зеркало из https://github.com/mozilla/gecko-dev.git
Bug 740200 - Azure content rendering on Linux; r=roc
This commit is contained in:
Родитель
ecaa863490
Коммит
db6296930d
|
@ -8,10 +8,14 @@
|
|||
#include "gfxXlibSurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxAlphaRecovery.h"
|
||||
#include "cairo-xlib.h"
|
||||
#include "cairo-xlib-xrender.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
#define NATIVE_DRAWING_NOTE(m) fprintf(stderr, m)
|
||||
|
@ -134,8 +138,28 @@ gfxXlibNativeRenderer::DrawDirect(gfxContext *ctx, nsIntSize size,
|
|||
uint32_t flags,
|
||||
Screen *screen, Visual *visual)
|
||||
{
|
||||
cairo_t *cr = ctx->GetCairo();
|
||||
if (ctx->IsCairo()) {
|
||||
return DrawCairo(ctx->GetCairo(), size, flags, screen, visual);
|
||||
}
|
||||
|
||||
// We need to actually borrow the context because we want to read out the
|
||||
// clip rectangles.
|
||||
BorrowedCairoContext borrowed(ctx->GetDrawTarget());
|
||||
if (!borrowed.mCairo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool direct = DrawCairo(borrowed.mCairo, size, flags, screen, visual);
|
||||
borrowed.Finish();
|
||||
|
||||
return direct;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxXlibNativeRenderer::DrawCairo(cairo_t* cr, nsIntSize size,
|
||||
uint32_t flags,
|
||||
Screen *screen, Visual *visual)
|
||||
{
|
||||
/* Check that the target surface is an xlib surface. */
|
||||
cairo_surface_t *target = cairo_get_group_target (cr);
|
||||
if (cairo_surface_get_type (target) != CAIRO_SURFACE_TYPE_XLIB) {
|
||||
|
@ -450,7 +474,6 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
|
|||
result->mUniformColor = false;
|
||||
}
|
||||
|
||||
bool drawIsOpaque = (flags & DRAW_IS_OPAQUE) != 0;
|
||||
gfxMatrix matrix = ctx->CurrentMatrix();
|
||||
|
||||
// We can only draw direct or onto a copied background if pixels align and
|
||||
|
@ -488,7 +511,7 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
|
|||
|
||||
if (canDrawOverBackground &&
|
||||
DrawDirect(ctx, size, flags, screen, visual))
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
nsIntRect drawingRect(nsIntPoint(0, 0), size);
|
||||
|
@ -506,29 +529,56 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
|
|||
int32_t(clipExtents.Width()),
|
||||
int32_t(clipExtents.Height()));
|
||||
drawingRect.IntersectRect(drawingRect, intExtents);
|
||||
|
||||
if (ctx->IsCairo()) {
|
||||
nsRefPtr<gfxASurface> target(ctx->CurrentSurface());
|
||||
DrawFallback(nullptr, ctx, target, size, drawingRect, canDrawOverBackground,
|
||||
flags, screen, visual, result);
|
||||
} else {
|
||||
DrawTarget* drawTarget = ctx->GetDrawTarget();
|
||||
if (!drawTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> target = gfxPlatform::GetPlatform()->
|
||||
GetThebesSurfaceForDrawTarget(drawTarget);
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
DrawFallback(drawTarget, ctx, target, size, drawingRect, canDrawOverBackground,
|
||||
flags, screen, visual, result);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxXlibNativeRenderer::DrawFallback(DrawTarget* drawTarget, gfxContext* ctx, gfxASurface* target,
|
||||
nsIntSize& size, nsIntRect& drawingRect,
|
||||
bool canDrawOverBackground, uint32_t flags,
|
||||
Screen* screen, Visual* visual, DrawOutput* result)
|
||||
{
|
||||
gfxPoint offset(drawingRect.x, drawingRect.y);
|
||||
|
||||
DrawingMethod method;
|
||||
nsRefPtr<gfxASurface> target = ctx->CurrentSurface();
|
||||
nsRefPtr<gfxXlibSurface> tempXlibSurface =
|
||||
CreateTempXlibSurface(target, drawingRect.Size(),
|
||||
canDrawOverBackground, flags, screen, visual,
|
||||
&method);
|
||||
if (!tempXlibSurface)
|
||||
return;
|
||||
|
||||
|
||||
if (drawingRect.Size() != size || method == eCopyBackground) {
|
||||
// Only drawing a portion, or copying background,
|
||||
// so won't return a result.
|
||||
result = nullptr;
|
||||
}
|
||||
|
||||
|
||||
nsRefPtr<gfxContext> tmpCtx;
|
||||
bool drawIsOpaque = (flags & DRAW_IS_OPAQUE) != 0;
|
||||
if (!drawIsOpaque) {
|
||||
tmpCtx = new gfxContext(tempXlibSurface);
|
||||
if (method == eCopyBackground) {
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpCtx->SetSource(target, -(offset + matrix.GetTranslation()));
|
||||
tmpCtx->SetSource(target, -(offset + ctx->CurrentMatrix().GetTranslation()));
|
||||
// The copy from the tempXlibSurface to the target context should
|
||||
// use operator SOURCE, but that would need a mask to bound the
|
||||
// operation. Here we only copy opaque backgrounds so operator
|
||||
|
@ -547,8 +597,16 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
|
|||
}
|
||||
|
||||
if (method != eAlphaExtraction) {
|
||||
ctx->SetSource(tempXlibSurface, offset);
|
||||
ctx->Paint();
|
||||
if (drawTarget) {
|
||||
RefPtr<SourceSurface> sourceSurface = gfxPlatform::GetPlatform()->
|
||||
GetSourceSurfaceForSurface(drawTarget, tempXlibSurface);
|
||||
drawTarget->DrawSurface(sourceSurface,
|
||||
Rect(offset.x, offset.y, size.width, size.height),
|
||||
Rect(0, 0, size.width, size.height));
|
||||
} else {
|
||||
ctx->SetSource(tempXlibSurface, offset);
|
||||
ctx->Paint();
|
||||
}
|
||||
if (result) {
|
||||
result->mSurface = tempXlibSurface;
|
||||
/* fill in the result with what we know, which is really just what our
|
||||
|
@ -576,8 +634,7 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
|
|||
result ? &analysis : nullptr))
|
||||
return;
|
||||
|
||||
ctx->SetSource(blackImage, offset);
|
||||
|
||||
gfxASurface* paintSurface = blackImage;
|
||||
/* if the caller wants to retrieve the rendered image, put it into
|
||||
a 'similar' surface, and use that as the source for the drawing right
|
||||
now. This means we always return a surface similar to the surface
|
||||
|
@ -604,10 +661,18 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
|
|||
copyCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
copyCtx.Paint();
|
||||
|
||||
ctx->SetSource(result->mSurface);
|
||||
paintSurface = result->mSurface;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->Paint();
|
||||
if (drawTarget) {
|
||||
RefPtr<SourceSurface> sourceSurface = gfxPlatform::GetPlatform()->
|
||||
GetSourceSurfaceForSurface(drawTarget, paintSurface);
|
||||
drawTarget->DrawSurface(sourceSurface,
|
||||
Rect(offset.x, offset.y, size.width, size.height),
|
||||
Rect(0, 0, size.width, size.height));
|
||||
} else {
|
||||
ctx->SetSource(paintSurface, offset);
|
||||
ctx->Paint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,19 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class DrawTarget;
|
||||
}
|
||||
}
|
||||
|
||||
class gfxASurface;
|
||||
class gfxXlibSurface;
|
||||
class gfxContext;
|
||||
struct nsIntRect;
|
||||
struct nsIntPoint;
|
||||
struct nsIntSize;
|
||||
typedef struct _cairo cairo_t;
|
||||
|
||||
/**
|
||||
* This class lets us take code that draws into an X drawable and lets us
|
||||
|
@ -91,6 +98,15 @@ private:
|
|||
bool DrawDirect(gfxContext *ctx, nsIntSize bounds,
|
||||
uint32_t flags, Screen *screen, Visual *visual);
|
||||
|
||||
bool DrawCairo(cairo_t* cr, nsIntSize size,
|
||||
uint32_t flags, Screen *screen, Visual *visual);
|
||||
|
||||
void DrawFallback(mozilla::gfx::DrawTarget* dt, gfxContext* ctx,
|
||||
gfxASurface* aSurface, nsIntSize& size,
|
||||
nsIntRect& drawingRect, bool canDrawOverBackground,
|
||||
uint32_t flags, Screen* screen, Visual* visual,
|
||||
DrawOutput* result);
|
||||
|
||||
bool DrawOntoTempSurface(gfxXlibSurface *tempXlibSurface,
|
||||
nsIntPoint offset);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче