Back out 4f682f01262e (bug 857895) for widespread destruction

CLOSED TREE
This commit is contained in:
Phil Ringnalda 2015-05-11 19:53:28 -07:00
parent ac5a1d4235
commit 1bc57a17f1
7 changed files with 31 additions and 317 deletions

View File

@ -19,8 +19,6 @@
#include "nsSVGEffects.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "nsWidgetsCID.h"
#include "nsIAppShell.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIFrame.h"
@ -116,7 +114,6 @@
#include "nsDeviceContext.h"
#include "nsFontMetrics.h"
#include "Units.h"
#include "mozilla/Services.h"
#undef free // apparently defined by some windows header, clashing with a free()
// method in SkTypes.h
@ -182,64 +179,6 @@ public:
NS_IMPL_ISUPPORTS(Canvas2dPixelsReporter, nsIMemoryReporter)
class CanvasShutdownObserver : public nsIObserver
{
virtual ~CanvasShutdownObserver() {}
public:
NS_DECL_ISUPPORTS
explicit CanvasShutdownObserver(CanvasRenderingContext2D* aCanvas)
: mCanvas(aCanvas)
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
observerService->AddObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, false);
}
void Shutdown() {
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
observerService->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
}
NS_IMETHOD Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData) override
{
mCanvas->ShutdownTaskQueue();
return NS_OK;
}
private:
CanvasRenderingContext2D* mCanvas;
};
NS_IMPL_ISUPPORTS(CanvasShutdownObserver, nsIObserver);
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
void
CanvasRenderingContext2D::RecordCommand()
{
static uint32_t kBatchSize = 5;
if (++mPendingCommands > kBatchSize) {
mPendingCommands = 0;
FlushDelayedTarget();
return;
}
if (mScheduledFlush) {
return;
}
mScheduledFlush = true;
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(this, &CanvasRenderingContext2D::StableStateReached);
appShell->RunInStableState(r);
}
class CanvasRadialGradient : public CanvasGradient
{
public:
@ -454,11 +393,6 @@ public:
mCtx->CurrentState().filterAdditionalImages,
mPostFilterBounds.TopLeft() - mOffset,
DrawOptions(1.0f, mCompositionOp));
// DrawTargetCapture doesn't properly support filter nodes because they are
// mutable. Block until drawing is done to avoid races.
mCtx->FlushDelayedTarget();
mCtx->FinishDelayedRendering();
}
DrawTarget* DT()
@ -883,9 +817,6 @@ public:
if (!context || !context->mTarget)
return;
context->FlushDelayedTarget();
context->FinishDelayedRendering();
// Since SkiaGL default to store drawing command until flush
// We will have to flush it before present.
context->mTarget->Flush();
@ -1007,8 +938,6 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
, mZero(false), mOpaque(false)
, mResetLayer(true)
, mIPC(false)
, mPendingCommands(0)
, mScheduledFlush(false)
, mDrawObserver(nullptr)
, mIsEntireFrameInvalid(false)
, mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
@ -1016,14 +945,6 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
{
sNumLivingContexts++;
#ifdef XP_MACOSX
// Restrict async rendering to OSX for now until the failures on other
// platforms get resolved.
mTaskQueue = new MediaTaskQueue(SharedThreadPool::Get(NS_LITERAL_CSTRING("Canvas Rendering"),
4));
mShutdownObserver = new CanvasShutdownObserver(this);
#endif
// The default is to use OpenGL mode
if (!gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas()) {
mRenderingMode = RenderingMode::SoftwareBackendMode;
@ -1036,9 +957,6 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
CanvasRenderingContext2D::~CanvasRenderingContext2D()
{
if (mTaskQueue) {
ShutdownTaskQueue();
}
RemoveDrawObserver();
RemovePostRefreshObserver();
Reset();
@ -1061,19 +979,6 @@ CanvasRenderingContext2D::~CanvasRenderingContext2D()
RemoveDemotableContext(this);
}
void
CanvasRenderingContext2D::ShutdownTaskQueue()
{
mShutdownObserver->Shutdown();
mShutdownObserver = nullptr;
FlushDelayedTarget();
FinishDelayedRendering();
mTaskQueue->BeginShutdown();
mTaskQueue = nullptr;
mDelayedTarget = nullptr;
}
JSObject*
CanvasRenderingContext2D::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
{
@ -1129,10 +1034,7 @@ CanvasRenderingContext2D::Reset()
gCanvasAzureMemoryUsed -= mWidth * mHeight * 4;
}
FinishDelayedRendering();
mTarget = nullptr;
mDelayedTarget = nullptr;
mFinalTarget = nullptr;
// reset hit regions
mHitRegionsOptions.ClearAndRetainStorage();
@ -1199,8 +1101,6 @@ CanvasRenderingContext2D::StyleColorToString(const nscolor& aColor, nsAString& a
nsresult
CanvasRenderingContext2D::Redraw()
{
RecordCommand();
if (mIsEntireFrameInvalid) {
return NS_OK;
}
@ -1222,7 +1122,6 @@ CanvasRenderingContext2D::Redraw()
void
CanvasRenderingContext2D::Redraw(const mgfx::Rect &r)
{
RecordCommand();
++mInvalidateCount;
if (mIsEntireFrameInvalid) {
@ -1245,18 +1144,6 @@ CanvasRenderingContext2D::Redraw(const mgfx::Rect &r)
mCanvasElement->InvalidateCanvasContent(&r);
}
TemporaryRef<SourceSurface>
CanvasRenderingContext2D::GetSurfaceSnapshot(bool* aPremultAlpha /* = nullptr */)
{
EnsureTarget();
if (aPremultAlpha) {
*aPremultAlpha = true;
}
FlushDelayedTarget();
FinishDelayedRendering();
return mFinalTarget->Snapshot();
}
void
CanvasRenderingContext2D::DidRefresh()
{
@ -1274,7 +1161,6 @@ CanvasRenderingContext2D::RedrawUser(const gfxRect& r)
{
if (mIsEntireFrameInvalid) {
++mInvalidateCount;
RecordCommand();
return;
}
@ -1300,7 +1186,7 @@ bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
}
#endif
RefPtr<SourceSurface> snapshot = GetSurfaceSnapshot();
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
RefPtr<DrawTarget> oldTarget = mTarget;
mTarget = nullptr;
mResetLayer = true;
@ -1474,8 +1360,6 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
if (glue && glue->GetGrContext() && glue->GetGLContext()) {
// Don't use mFinalTarget (async canvas drawing) with SkiaGL, because we currently
// use a single GLContext and need them all to be on the same thread.
mTarget = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(), size, format);
if (mTarget) {
AddDemotableContext(this);
@ -1486,32 +1370,18 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
}
#endif
if (!mTarget) {
mFinalTarget = layerManager->CreateDrawTarget(size, format);
mTarget = layerManager->CreateDrawTarget(size, format);
}
} else {
mFinalTarget = layerManager->CreateDrawTarget(size, format);
mTarget = layerManager->CreateDrawTarget(size, format);
mode = RenderingMode::SoftwareBackendMode;
}
} else {
mFinalTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
mode = RenderingMode::SoftwareBackendMode;
}
}
// Restrict async canvas drawing to OSX for now since we get test failures
// on other platforms.
#ifdef XP_MACOSX
if (mFinalTarget) {
mTarget = mDelayedTarget = mFinalTarget->CreateCaptureDT(size);
} else {
mFinalTarget = mTarget;
}
#else
mFinalTarget = mTarget;
#endif
mPendingCommands = 0;
if (mTarget) {
static bool registered = false;
if (!registered) {
@ -1545,7 +1415,7 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
Redraw();
} else {
EnsureErrorTarget();
mTarget = mFinalTarget = sErrorTarget;
mTarget = sErrorTarget;
}
return mode;
@ -1565,51 +1435,6 @@ CanvasRenderingContext2D::GetHeight() const
}
#endif
class DrawCaptureTask : public nsRunnable
{
public:
DrawCaptureTask(DrawTargetCapture *aReplay, DrawTarget* aDest)
: mReplay(aReplay)
, mDest(aDest)
{
}
NS_IMETHOD Run()
{
mDest->DrawCapturedDT(mReplay, Matrix());
return NS_OK;
}
private:
RefPtr<DrawTargetCapture> mReplay;
RefPtr<DrawTarget> mDest;
};
void
CanvasRenderingContext2D::FlushDelayedTarget()
{
if (!mDelayedTarget) {
return;
}
mPendingCommands = 0;
nsCOMPtr<nsIRunnable> task = new DrawCaptureTask(mDelayedTarget, mFinalTarget);
mTaskQueue->Dispatch(task.forget());
mDelayedTarget = mFinalTarget->CreateCaptureDT(IntSize(mWidth, mHeight));
mDelayedTarget->SetTransform(mTarget->GetTransform());
mTarget = mDelayedTarget;
}
void
CanvasRenderingContext2D::FinishDelayedRendering()
{
if (mTaskQueue) {
mTaskQueue->AwaitIdle();
}
}
NS_IMETHODIMP
CanvasRenderingContext2D::SetDimensions(int32_t width, int32_t height)
{
@ -1759,7 +1584,7 @@ CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer,
*aFormat = 0;
EnsureTarget();
RefPtr<SourceSurface> snapshot = GetSurfaceSnapshot();
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
if (!snapshot) {
return;
}
@ -2178,7 +2003,7 @@ CanvasRenderingContext2D::CreatePattern(const HTMLImageOrCanvasOrVideoElement& e
// of animated images
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(htmlElement,
nsLayoutUtils::SFE_WANT_FIRST_FRAME, mFinalTarget);
nsLayoutUtils::SFE_WANT_FIRST_FRAME, mTarget);
if (!res.mSourceSurface) {
error.Throw(NS_ERROR_NOT_AVAILABLE);
@ -4489,7 +4314,7 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
nsLayoutUtils::SurfaceFromElementResult res =
CachedSurfaceFromElement(element);
if (!res.mSourceSurface)
res = nsLayoutUtils::SurfaceFromElement(element, sfeFlags, mFinalTarget);
res = nsLayoutUtils::SurfaceFromElement(element, sfeFlags, mTarget);
if (!res.mSourceSurface && !res.mDrawInfo.mImgContainer) {
// The spec says to silently do nothing in the following cases:
@ -4833,12 +4658,7 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindow& window, double x,
if (gfxPlatform::GetPlatform()->SupportsAzureContentForDrawTarget(mTarget) &&
GlobalAlpha() == 1.0f)
{
// Complete any async rendering and use synchronous rendering for DrawWindow
// until we're confident it works for all content.
FlushDelayedTarget();
FinishDelayedRendering();
thebes = new gfxContext(mFinalTarget);
thebes = new gfxContext(mTarget);
thebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21,
matrix._22, matrix._31, matrix._32));
} else {
@ -5095,7 +4915,7 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
IntRect srcReadRect = srcRect.Intersect(destRect);
RefPtr<DataSourceSurface> readback;
if (!srcReadRect.IsEmpty() && !mZero) {
RefPtr<SourceSurface> snapshot = GetSurfaceSnapshot();
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
if (snapshot) {
readback = snapshot->GetDataSurface();
}
@ -5469,7 +5289,7 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
return nullptr;
}
FlushDelayedTarget();
mTarget->Flush();
if (!mResetLayer && aOldLayer) {
CanvasRenderingContext2DUserData* userData =
@ -5518,8 +5338,6 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
userData = new CanvasRenderingContext2DUserData(this);
canvasLayer->SetDidTransactionCallback(
CanvasRenderingContext2DUserData::DidTransactionCallback, userData);
canvasLayer->SetPreTransactionCallback(
CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
canvasLayer->SetUserData(&g2DContextLayerUserData, userData);
CanvasLayer::Data data;
@ -5528,13 +5346,16 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
GLuint skiaGLTex = SkiaGLTex();
if (skiaGLTex) {
canvasLayer->SetPreTransactionCallback(
CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
MOZ_ASSERT(glue);
data.mGLContext = glue->GetGLContext();
data.mFrontbufferGLTex = skiaGLTex;
} else {
data.mDrawTarget = mFinalTarget;
data.mDrawTarget = mTarget;
}
canvasLayer->Initialize(data);

View File

@ -10,7 +10,6 @@
#include "nsIDOMCanvasRenderingContext2D.h"
#include "nsICanvasRenderingContextInternal.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Monitor.h"
#include "nsColor.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/dom/HTMLVideoElement.h"
@ -28,7 +27,6 @@
#include "mozilla/EnumeratedArray.h"
#include "FilterSupport.h"
#include "nsSVGEffects.h"
#include "MediaTaskQueue.h"
class nsGlobalWindow;
class nsXULElement;
@ -54,7 +52,6 @@ template<typename T> class Optional;
struct CanvasBidiProcessor;
class CanvasRenderingContext2DUserData;
class CanvasDrawObserver;
class CanvasShutdownObserver;
/**
** CanvasRenderingContext2D
@ -445,7 +442,14 @@ public:
const char16_t* aEncoderOptions,
nsIInputStream **aStream) override;
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) override;
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) override
{
EnsureTarget();
if (aPremultAlpha) {
*aPremultAlpha = true;
}
return mTarget->Snapshot();
}
NS_IMETHOD SetIsOpaque(bool isOpaque) override;
bool GetIsOpaque() override { return mOpaque; }
@ -517,7 +521,6 @@ public:
}
friend class CanvasRenderingContext2DUserData;
friend class CanvasShutdownObserver;
virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) override;
@ -529,21 +532,6 @@ public:
// return true and fills in the bound rect if element has a hit region.
bool GetHitRegionRect(Element* aElement, nsRect& aRect) override;
/**
* Deferred rendering functions
*/
/**
* Called when the event loop reaches a stable
* state, and trigger us to flush any outstanding
* commands to the rendering thread.
*/
void StableStateReached()
{
mScheduledFlush = false;
FlushDelayedTarget();
}
protected:
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
uint32_t aWidth, uint32_t aHeight,
@ -562,8 +550,6 @@ protected:
nsresult InitializeWithTarget(mozilla::gfx::DrawTarget *surface,
int32_t width, int32_t height);
void ShutdownTaskQueue();
/**
* The number of living nsCanvasRenderingContexts. When this goes down to
* 0, we free the premultiply and unpremultiply tables, if they exist.
@ -727,54 +713,6 @@ protected:
// sErrorTarget.
mozilla::RefPtr<mozilla::gfx::DrawTarget> mTarget;
/**
* Deferred rendering implementation
*/
// If we are using deferred rendering, then this is the current
// deferred rendering target. It is the same pointer as mTarget.
mozilla::RefPtr<mozilla::gfx::DrawTargetCapture> mDelayedTarget;
// If we are using deferred rendering, then this is the actual destination
// buffer.
mozilla::RefPtr<mozilla::gfx::DrawTarget> mFinalTarget;
/**
* Add the current DelayedDrawTarget to the rendering queue,
* schedule a rendering job if required, and create a new
* DelayedDrawTarget.
*/
void FlushDelayedTarget();
/**
* Make sure all commands have been flushed to
* the rendering thread, and block until they
* are completed.
*/
void FinishDelayedRendering();
/**
* Called when a command is added to the current
* delayed draw target.
*
* Either flushes the current batch of commands to
* the rendering thread, or ensures that this happens
* the next time the event loop reaches a stable state.
*/
void RecordCommand();
// The number of commands currently waiting to be sent
// to the rendering thread.
uint32_t mPendingCommands;
// True if we have scheduled FlushDelayedTarget to be
// called in the next browser stable state.
bool mScheduledFlush;
nsRefPtr<MediaTaskQueue> mTaskQueue;
nsRefPtr<CanvasShutdownObserver> mShutdownObserver;
uint32_t SkiaGLTex() const;
// This observes our draw calls at the beginning of the canvas

View File

@ -27,7 +27,6 @@ MediaTaskQueue::~MediaTaskQueue()
{
MonitorAutoLock mon(mQueueMonitor);
MOZ_ASSERT(mIsShutdown);
MOZ_DIAGNOSTIC_ASSERT(mTasks.empty());
MOZ_COUNT_DTOR(MediaTaskQueue);
}

View File

@ -155,7 +155,7 @@ struct DrawSurfaceOptions {
* matching DrawTarget. Not adhering to this condition will make a draw call
* fail.
*/
class GradientStops : public external::AtomicRefCounted<GradientStops>
class GradientStops : public RefCounted<GradientStops>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops)
@ -318,7 +318,7 @@ class DrawTargetCaptureImpl;
* which may be used as a source in a SurfacePattern or a DrawSurface call.
* They cannot be drawn to directly.
*/
class SourceSurface : public external::AtomicRefCounted<SourceSurface>
class SourceSurface : public RefCounted<SourceSurface>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface)
@ -476,7 +476,7 @@ class FlattenedPath;
/** The path class is used to create (sets of) figures of any shape that can be
* filled or stroked to a DrawTarget
*/
class Path : public external::AtomicRefCounted<Path>
class Path : public RefCounted<Path>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(Path)
@ -577,7 +577,7 @@ struct GlyphBuffer
* at a particular size. It is passed into text drawing calls to describe
* the font used for the drawing call.
*/
class ScaledFont : public external::AtomicRefCounted<ScaledFont>
class ScaledFont : public RefCounted<ScaledFont>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
@ -622,7 +622,7 @@ protected:
* parameters. This is because different platforms have unique rendering
* parameters.
*/
class GlyphRenderingOptions : public external::AtomicRefCounted<GlyphRenderingOptions>
class GlyphRenderingOptions : public RefCounted<GlyphRenderingOptions>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptions)
@ -641,7 +641,7 @@ class DrawTargetCapture;
* may be used either through a Snapshot or by flushing the target and directly
* accessing the backing store a DrawTarget was created with.
*/
class DrawTarget : public external::AtomicRefCounted<DrawTarget>
class DrawTarget : public RefCounted<DrawTarget>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget)

View File

@ -148,7 +148,7 @@ class DrawFilterCommand : public DrawingCommand
public:
DrawFilterCommand(FilterNode* aFilter, const Rect& aSourceRect,
const Point& aDestPoint, const DrawOptions& aOptions)
: DrawingCommand(CommandType::DRAWFILTER)
: DrawingCommand(CommandType::DRAWSURFACE)
, mFilter(aFilter), mSourceRect(aSourceRect)
, mDestPoint(aDestPoint), mOptions(aOptions)
{
@ -166,36 +166,6 @@ private:
DrawOptions mOptions;
};
class DrawSurfaceWithShadowCommand : public DrawingCommand
{
public:
DrawSurfaceWithShadowCommand(SourceSurface* aSurface, const Point& aDest,
const Color& aColor, const Point& aOffset,
Float aSigma, CompositionOp aOperator)
: DrawingCommand(CommandType::DRAWSURFACEWITHSHADOW)
, mSurface(aSurface)
, mDest(aDest)
, mColor(aColor)
, mOffset(aOffset)
, mSigma(aSigma)
, mOperator(aOperator)
{
}
virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&)
{
aDT->DrawSurfaceWithShadow(mSurface, mDest, mColor, mOffset, mSigma, mOperator);
}
private:
RefPtr<SourceSurface> mSurface;
Point mDest;
Color mColor;
Point mOffset;
Float mSigma;
CompositionOp mOperator;
};
class ClearRectCommand : public DrawingCommand
{
public:

View File

@ -30,7 +30,6 @@ DrawTargetCaptureImpl::Init(const IntSize& aSize, DrawTarget* aRefDT)
}
mRefDT = aRefDT;
mFormat = mRefDT->GetFormat();
mSize = aSize;
return true;
@ -70,18 +69,6 @@ DrawTargetCaptureImpl::DrawFilter(FilterNode *aNode,
AppendCommand(DrawFilterCommand)(aNode, aSourceRect, aDestPoint, aOptions);
}
void
DrawTargetCaptureImpl::DrawSurfaceWithShadow(SourceSurface *aSurface,
const Point &aDest,
const Color &aColor,
const Point &aOffset,
Float aSigma,
CompositionOp aOperator)
{
aSurface->GuaranteePersistance();
AppendCommand(DrawSurfaceWithShadowCommand)(aSurface, aDest, aColor, aOffset, aSigma, aOperator);
}
void
DrawTargetCaptureImpl::ClearRect(const Rect &aRect)
{
@ -191,7 +178,6 @@ void
DrawTargetCaptureImpl::SetTransform(const Matrix& aTransform)
{
AppendCommand(SetTransformCommand)(aTransform);
mTransform = aTransform;
}
void

View File

@ -45,7 +45,7 @@ public:
const Color &aColor,
const Point &aOffset,
Float aSigma,
CompositionOp aOperator);
CompositionOp aOperator) { /* Not implemented */ }
virtual void ClearRect(const Rect &aRect);
virtual void MaskSurface(const Pattern &aSource,