Bug 688342 - Make nsCanvasRenderingContext2D support Azure backends other than Direct2D. r=Bas

This commit is contained in:
Matt Woodrow 2011-11-03 08:55:03 +13:00
Родитель 1926ac43f9
Коммит 54ee03f30c
11 изменённых файлов: 76 добавлений и 14 удалений

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

@ -988,15 +988,15 @@ PRUint8 (*nsCanvasRenderingContext2DAzure::sPremultiplyTable)[256] = nsnull;
nsresult
NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
{
#ifndef XP_WIN
return NS_ERROR_NOT_AVAILABLE;
#else
#ifdef XP_WIN
if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
gfxWindowsPlatform::RENDER_DIRECT2D ||
!gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) {
return NS_ERROR_NOT_AVAILABLE;
}
#elif !defined XP_MACOSX
return NS_ERROR_NOT_AVAILABLE;
#endif
nsRefPtr<nsIDOMCanvasRenderingContext2D> ctx = new nsCanvasRenderingContext2DAzure();
if (!ctx)
@ -1004,7 +1004,6 @@ NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
*aResult = ctx.forget().get();
return NS_OK;
#endif
}
nsCanvasRenderingContext2DAzure::nsCanvasRenderingContext2DAzure()
@ -1253,7 +1252,7 @@ nsCanvasRenderingContext2DAzure::SetDimensions(PRInt32 width, PRInt32 height)
if (layerManager) {
target = layerManager->CreateDrawTarget(size, format);
} else {
target = Factory::CreateDrawTarget(BACKEND_DIRECT2D, size, format);
target = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(size, format);
}
}
@ -1293,7 +1292,7 @@ nsCanvasRenderingContext2DAzure::InitializeWithTarget(DrawTarget *target, PRInt3
*/
if (!target)
{
mTarget = Factory::CreateDrawTarget(BACKEND_DIRECT2D, IntSize(1, 1), FORMAT_B8G8R8A8);
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1, 1), FORMAT_B8G8R8A8);
} else {
mValid = true;
}

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

@ -218,8 +218,8 @@ TemporaryRef<DrawTarget>
LayerManager::CreateDrawTarget(const IntSize &aSize,
SurfaceFormat aFormat)
{
// Right now this doesn't work on the general layer manager.
return NULL;
return gfxPlatform::GetPlatform()->
CreateOffscreenDrawTarget(aSize, aFormat);
}
#ifdef DEBUG

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

@ -45,6 +45,7 @@
#include "gfxImageSurface.h"
#include "gfxContext.h"
#include "GLContextProvider.h"
#include "gfxPlatform.h"
#ifdef XP_WIN
#include "gfxWindowsSurface.h"
@ -91,7 +92,10 @@ CanvasLayerOGL::Initialize(const Data& aData)
mOGLManager->MakeCurrent();
if (aData.mSurface) {
if (aData.mDrawTarget) {
mDrawTarget = aData.mDrawTarget;
mNeedsYFlip = false;
} else if (aData.mSurface) {
mCanvasSurface = aData.mSurface;
mNeedsYFlip = false;
#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
@ -133,7 +137,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
MakeTexture();
// This should only ever occur with 2d canvas, WebGL can't already have a texture
// of this size can it?
NS_ABORT_IF_FALSE(mCanvasSurface,
NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget,
"Invalid texture size when WebGL surface already exists at that size?");
}
}
@ -184,7 +188,11 @@ CanvasLayerOGL::UpdateSurface()
}
} else {
nsRefPtr<gfxASurface> updatedAreaSurface;
if (mCanvasSurface) {
if (mDrawTarget) {
// TODO: This is suboptimal - We should have direct handling for the surface types instead of
// going via a gfxASurface.
updatedAreaSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
} else if (mCanvasSurface) {
updatedAreaSurface = mCanvasSurface;
} else if (mCanvasGLContext) {
nsRefPtr<gfxImageSurface> updatedAreaImageSurface =

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

@ -82,6 +82,7 @@ protected:
nsRefPtr<gfxASurface> mCanvasSurface;
nsRefPtr<GLContext> mCanvasGLContext;
gl::ShaderProgramType mLayerProgram;
RefPtr<gfx::DrawTarget> mDrawTarget;
void MakeTexture();
GLuint mTexture;

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

@ -500,7 +500,25 @@ gfxPlatform::GetScaledFontForFont(gfxFont *aFont)
already_AddRefed<gfxASurface>
gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
{
// Don't know how to do this outside of Windows with D2D yet.
RefPtr<SourceSurface> source = aTarget->Snapshot();
RefPtr<DataSourceSurface> data = source->GetDataSurface();
if (!data) {
return NULL;
}
IntSize size = data->GetSize();
gfxASurface::gfxImageFormat format = gfxASurface::FormatFromContent(ContentForFormat(data->GetFormat()));
nsRefPtr<gfxImageSurface> image =
new gfxImageSurface(data->GetData(), gfxIntSize(size.width, size.height),
data->Stride(), format);
return image.forget();
}
RefPtr<DrawTarget>
gfxPlatform::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
{
return NULL;
}

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

@ -185,6 +185,9 @@ public:
virtual already_AddRefed<gfxASurface>
GetThebesSurfaceForDrawTarget(mozilla::gfx::DrawTarget *aTarget);
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
CreateOffscreenDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
/*
* Font bits
*/

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

@ -41,6 +41,7 @@
#include "gfxImageSurface.h"
#include "gfxQuartzSurface.h"
#include "gfxQuartzImageSurface.h"
#include "mozilla/gfx/2D.h"
#include "gfxMacPlatformFontList.h"
#include "gfxMacFont.h"
@ -58,6 +59,7 @@
#include <dlfcn.h>
using namespace mozilla;
using namespace mozilla::gfx;
// cribbed from CTFontManager.h
enum {
@ -137,6 +139,12 @@ gfxPlatformMac::CreateOffscreenSurface(const gfxIntSize& size,
return newSurface;
}
RefPtr<DrawTarget>
gfxPlatformMac::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
{
return NULL;
}
already_AddRefed<gfxASurface>
gfxPlatformMac::OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format)

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

@ -62,6 +62,9 @@ public:
already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxContentType contentType);
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
CreateOffscreenDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
already_AddRefed<gfxASurface> OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format);

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

@ -474,6 +474,17 @@ gfxWindowsPlatform::CreateOffscreenSurface(const gfxIntSize& size,
return surf;
}
RefPtr<DrawTarget>
gfxWindowsPlatform::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
{
#ifdef CAIRO_HAS_D2D_SURFACE
if (mRenderMode == RENDER_DIRECT2D) {
return Factory::CreateDrawTarget(BACKEND_DIRECT2D, aSize, aFormat);
}
#endif
return NULL;
}
RefPtr<ScaledFont>
gfxWindowsPlatform::GetScaledFontForFont(gfxFont *aFont)
{

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

@ -131,6 +131,8 @@ public:
GetScaledFontForFont(gfxFont *aFont);
virtual already_AddRefed<gfxASurface>
GetThebesSurfaceForDrawTarget(mozilla::gfx::DrawTarget *aTarget);
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
CreateOffscreenDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
enum RenderMode {
/* Use GDI and windows surfaces */

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

@ -45,6 +45,7 @@
#include "nsUnicharUtils.h"
#include "mozilla/FunctionTimer.h"
#include "nsToolkit.h"
#include "mozilla/Preferences.h"
#import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>
@ -177,7 +178,15 @@ GfxInfo::GetD2DEnabled(bool *aEnabled)
NS_IMETHODIMP
GfxInfo::GetAzureEnabled(bool *aEnabled)
{
return NS_ERROR_FAILURE;
bool azure = false;
nsresult rv = mozilla::Preferences::GetBool("gfx.canvas.azure.enabled", &azure);
if (NS_SUCCEEDED(rv) && azure) {
*aEnabled = true;
} else {
*aEnabled = false;
}
return NS_OK;
}
NS_IMETHODIMP