Skip to content

Commit

Permalink
Bug 857895 - Run canvas rendering asynchronously on OSX. r=Bas,bholley
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwoodrow committed Apr 9, 2013
1 parent 4870b4d commit 59baa2d
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 31 deletions.
210 changes: 195 additions & 15 deletions dom/canvas/CanvasRenderingContext2D.cpp

Large diffs are not rendered by default.

78 changes: 70 additions & 8 deletions dom/canvas/CanvasRenderingContext2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#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"
Expand All @@ -27,6 +28,7 @@
#include "mozilla/EnumeratedArray.h"
#include "FilterSupport.h"
#include "nsSVGEffects.h"
#include "MediaTaskQueue.h"

class nsGlobalWindow;
class nsXULElement;
Expand All @@ -52,6 +54,7 @@ template<typename T> class Optional;
struct CanvasBidiProcessor;
class CanvasRenderingContext2DUserData;
class CanvasDrawObserver;
class CanvasShutdownObserver;

/**
** CanvasRenderingContext2D
Expand Down Expand Up @@ -442,14 +445,7 @@ typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
const char16_t* aEncoderOptions,
nsIInputStream **aStream) override;

mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) override
{
EnsureTarget();
if (aPremultAlpha) {
*aPremultAlpha = true;
}
return mTarget->Snapshot();
}
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) override;

NS_IMETHOD SetIsOpaque(bool isOpaque) override;
bool GetIsOpaque() override { return mOpaque; }
Expand Down Expand Up @@ -521,6 +517,7 @@ typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
}

friend class CanvasRenderingContext2DUserData;
friend class CanvasShutdownObserver;

virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) override;

Expand All @@ -532,6 +529,21 @@ typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
// 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,
Expand All @@ -550,6 +562,8 @@ typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
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.
Expand Down Expand Up @@ -713,6 +727,54 @@ typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
// 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
Expand Down
2 changes: 2 additions & 0 deletions dom/media/MediaPromise.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ namespace mozilla {

extern PRLogModuleInfo* gMediaPromiseLog;

void EnsureMediaPromiseLog();

#define PROMISE_LOG(x, ...) \
MOZ_ASSERT(gMediaPromiseLog); \
PR_LOG(gMediaPromiseLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__))
Expand Down
1 change: 1 addition & 0 deletions dom/media/MediaTaskQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ MediaTaskQueue::~MediaTaskQueue()
{
MonitorAutoLock mon(mQueueMonitor);
MOZ_ASSERT(mIsShutdown);
MOZ_DIAGNOSTIC_ASSERT(mTasks.empty());
MOZ_COUNT_DTOR(MediaTaskQueue);
}

Expand Down
12 changes: 6 additions & 6 deletions gfx/2d/2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ struct DrawSurfaceOptions {
* matching DrawTarget. Not adhering to this condition will make a draw call
* fail.
*/
class GradientStops : public RefCounted<GradientStops>
class GradientStops : public external::AtomicRefCounted<GradientStops>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops)
Expand Down Expand Up @@ -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 RefCounted<SourceSurface>
class SourceSurface : public external::AtomicRefCounted<SourceSurface>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface)
Expand Down Expand Up @@ -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 RefCounted<Path>
class Path : public external::AtomicRefCounted<Path>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(Path)
Expand Down Expand Up @@ -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 RefCounted<ScaledFont>
class ScaledFont : public external::AtomicRefCounted<ScaledFont>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
Expand Down Expand Up @@ -622,7 +622,7 @@ class ScaledFont : public RefCounted<ScaledFont>
* parameters. This is because different platforms have unique rendering
* parameters.
*/
class GlyphRenderingOptions : public RefCounted<GlyphRenderingOptions>
class GlyphRenderingOptions : public external::AtomicRefCounted<GlyphRenderingOptions>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptions)
Expand All @@ -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 RefCounted<DrawTarget>
class DrawTarget : public external::AtomicRefCounted<DrawTarget>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget)
Expand Down
32 changes: 31 additions & 1 deletion gfx/2d/DrawCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class DrawFilterCommand : public DrawingCommand
public:
DrawFilterCommand(FilterNode* aFilter, const Rect& aSourceRect,
const Point& aDestPoint, const DrawOptions& aOptions)
: DrawingCommand(CommandType::DRAWSURFACE)
: DrawingCommand(CommandType::DRAWFILTER)
, mFilter(aFilter), mSourceRect(aSourceRect)
, mDestPoint(aDestPoint), mOptions(aOptions)
{
Expand All @@ -166,6 +166,36 @@ class DrawFilterCommand : public DrawingCommand
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:
Expand Down
14 changes: 14 additions & 0 deletions gfx/2d/DrawTargetCapture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ DrawTargetCaptureImpl::Init(const IntSize& aSize, DrawTarget* aRefDT)
}

mRefDT = aRefDT;
mFormat = mRefDT->GetFormat();

mSize = aSize;
return true;
Expand Down Expand Up @@ -69,6 +70,18 @@ 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)
{
Expand Down Expand Up @@ -178,6 +191,7 @@ void
DrawTargetCaptureImpl::SetTransform(const Matrix& aTransform)
{
AppendCommand(SetTransformCommand)(aTransform);
mTransform = aTransform;
}

void
Expand Down
2 changes: 1 addition & 1 deletion gfx/2d/DrawTargetCapture.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class DrawTargetCaptureImpl : public DrawTargetCapture
const Color &aColor,
const Point &aOffset,
Float aSigma,
CompositionOp aOperator) { /* Not implemented */ }
CompositionOp aOperator);

virtual void ClearRect(const Rect &aRect);
virtual void MaskSurface(const Pattern &aSource,
Expand Down

0 comments on commit 59baa2d

Please sign in to comment.