Bug 792207 - Part 4: Add Azure recording code. r=jrmuizel

This commit is contained in:
Bas Schouten 2012-09-24 15:02:50 +00:00
parent 8cf02dc4f8
commit 608b6fc192
15 changed files with 3314 additions and 2 deletions

View File

@ -833,6 +833,12 @@ protected:
SurfaceFormat mFormat;
};
class DrawEventRecorder : public RefCounted<DrawEventRecorder>
{
public:
virtual ~DrawEventRecorder() { }
};
class GFX2D_API Factory
{
public:

View File

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DrawEventRecorder.h"
#include "PathRecording.h"
namespace mozilla {
namespace gfx {
using namespace std;
const uint32_t kMagicInt = 0xc001feed;
DrawEventRecorderPrivate::DrawEventRecorderPrivate(std::ostream *aStream)
: mOutputStream(aStream)
{
}
void
DrawEventRecorderPrivate::RecordEvent(const RecordedEvent &aEvent)
{
WriteElement(*mOutputStream, aEvent.mType);
aEvent.RecordToStream(*mOutputStream);
Flush();
}
DrawEventRecorderFile::DrawEventRecorderFile(const char *aFilename)
: DrawEventRecorderPrivate(NULL)
, mOutputFile(aFilename, ofstream::binary)
{
mOutputStream = &mOutputFile;
WriteElement(*mOutputStream, kMagicInt);
WriteElement(*mOutputStream, kMajorRevision);
WriteElement(*mOutputStream, kMinorRevision);
}
DrawEventRecorderFile::~DrawEventRecorderFile()
{
mOutputFile.close();
}
void
DrawEventRecorderFile::Flush()
{
mOutputFile.flush();
}
}
}

View File

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_DRAWEVENTRECORDER_H_
#define MOZILLA_GFX_DRAWEVENTRECORDER_H_
#include "2D.h"
#include "RecordedEvent.h"
#include <ostream>
#include <fstream>
#if defined(_MSC_VER)
#include <hash_set>
#else
#include <set>
#endif
namespace mozilla {
namespace gfx {
class PathRecording;
class DrawEventRecorderPrivate : public DrawEventRecorder
{
public:
DrawEventRecorderPrivate(std::ostream *aStream);
virtual ~DrawEventRecorderPrivate() { }
void RecordEvent(const RecordedEvent &aEvent);
void WritePath(const PathRecording *aPath);
void AddStoredPath(const ReferencePtr aPath) {
mStoredPaths.insert(aPath);
}
void RemoveStoredPath(const ReferencePtr aPath) {
mStoredPaths.erase(aPath);
}
bool HasStoredPath(const ReferencePtr aPath) {
if (mStoredPaths.find(aPath) != mStoredPaths.end()) {
return true;
}
return false;
}
protected:
std::ostream *mOutputStream;
virtual void Flush() = 0;
#if defined(_MSC_VER)
typedef stdext::hash_set<const void*> ObjectSet;
#else
typedef std::set<const void*> ObjectSet;
#endif
ObjectSet mStoredPaths;
ObjectSet mStoredScaledFonts;
};
class DrawEventRecorderFile : public DrawEventRecorderPrivate
{
public:
DrawEventRecorderFile(const char *aFilename);
~DrawEventRecorderFile();
private:
virtual void Flush();
std::ofstream mOutputFile;
};
}
}
#endif /* MOZILLA_GFX_DRAWEVENTRECORDER_H_ */

View File

@ -0,0 +1,61 @@
--- DrawEventRecorder.h
+++ DrawEventRecorder.h
@@ -6,34 +6,20 @@
#ifndef MOZILLA_GFX_DRAWEVENTRECORDER_H_
#define MOZILLA_GFX_DRAWEVENTRECORDER_H_
#include "2D.h"
#include "RecordedEvent.h"
#include <ostream>
#include <fstream>
-#if defined(_MSC_VER) || defined(MOZ_WIDGET_ANDROID)
+#if defined(_MSC_VER)
#include <hash_set>
#else
-#include <ext/hash_set>
-#endif
-
-#ifndef _MSC_VER
-#ifndef MOZ_WIDGET_ANDROID
-namespace __gnu_cxx {
-#endif
-template<>
-struct hash<void *> {
- size_t operator()(const void * __x) const {
- return reinterpret_cast<size_t>(__x); }
-};
-#ifndef MOZ_WIDGET_ANDROID
-}
-#endif
+#include <unordered_set>
#endif
namespace mozilla {
namespace gfx {
class PathRecording;
class DrawEventRecorderPrivate : public DrawEventRecorder
@@ -62,20 +48,18 @@ public:
protected:
std::ostream *mOutputStream;
virtual void Flush() = 0;
#if defined(_MSC_VER)
typedef stdext::hash_set<const void*> ObjectSet;
-#elif defined(MOZ_WIDGET_ANDROID)
- typedef hash_set<const void*> ObjectSet;
#else
- typedef __gnu_cxx::hash_set<const void*, __gnu_cxx::hash<void*> > ObjectSet;
+ typedef std::unordered_set<const void*> ObjectSet;
#endif
ObjectSet mStoredPaths;
ObjectSet mStoredScaledFonts;
};
class DrawEventRecorderFile : public DrawEventRecorderPrivate
{

View File

@ -0,0 +1,468 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DrawTargetRecording.h"
#include "PathRecording.h"
#include <stdio.h>
#include "Logging.h"
#include "Tools.h"
namespace mozilla {
namespace gfx {
class SourceSurfaceRecording : public SourceSurface
{
public:
SourceSurfaceRecording(SourceSurface *aFinalSurface, DrawEventRecorderPrivate *aRecorder)
: mFinalSurface(aFinalSurface), mRecorder(aRecorder)
{
}
~SourceSurfaceRecording()
{
mRecorder->RecordEvent(RecordedSourceSurfaceDestruction(this));
}
virtual SurfaceType GetType() const { return SURFACE_RECORDING; }
virtual IntSize GetSize() const { return mFinalSurface->GetSize(); }
virtual SurfaceFormat GetFormat() const { return mFinalSurface->GetFormat(); }
virtual TemporaryRef<DataSourceSurface> GetDataSurface() { return mFinalSurface->GetDataSurface(); }
RefPtr<SourceSurface> mFinalSurface;
RefPtr<DrawEventRecorderPrivate> mRecorder;
};
class GradientStopsRecording : public GradientStops
{
public:
GradientStopsRecording(GradientStops *aFinalGradientStops, DrawEventRecorderPrivate *aRecorder)
: mFinalGradientStops(aFinalGradientStops), mRecorder(aRecorder)
{
}
~GradientStopsRecording()
{
mRecorder->RecordEvent(RecordedGradientStopsDestruction(this));
}
virtual BackendType GetBackendType() const { return BACKEND_RECORDING; }
RefPtr<GradientStops> mFinalGradientStops;
RefPtr<DrawEventRecorderPrivate> mRecorder;
};
static SourceSurface *
GetSourceSurface(SourceSurface *aSurface)
{
if (aSurface->GetType() != SURFACE_RECORDING) {
return aSurface;
}
return static_cast<SourceSurfaceRecording*>(aSurface)->mFinalSurface;
}
static GradientStops *
GetGradientStops(GradientStops *aStops)
{
if (aStops->GetBackendType() != BACKEND_RECORDING) {
return aStops;
}
return static_cast<GradientStopsRecording*>(aStops)->mFinalGradientStops;
}
struct AdjustedPattern
{
AdjustedPattern(const Pattern &aPattern)
: mPattern(NULL)
{
mOrigPattern = const_cast<Pattern*>(&aPattern);
}
~AdjustedPattern() {
if (mPattern) {
mPattern->~Pattern();
}
}
operator Pattern*()
{
switch(mOrigPattern->GetType()) {
case PATTERN_COLOR:
return mOrigPattern;
case PATTERN_SURFACE:
{
SurfacePattern *surfPat = static_cast<SurfacePattern*>(mOrigPattern);
mPattern =
new (mSurfPat) SurfacePattern(GetSourceSurface(surfPat->mSurface),
surfPat->mExtendMode, surfPat->mMatrix,
surfPat->mFilter);
return mPattern;
}
case PATTERN_LINEAR_GRADIENT:
{
LinearGradientPattern *linGradPat = static_cast<LinearGradientPattern*>(mOrigPattern);
mPattern =
new (mLinGradPat) LinearGradientPattern(linGradPat->mBegin, linGradPat->mEnd,
GetGradientStops(linGradPat->mStops),
linGradPat->mMatrix);
return mPattern;
}
case PATTERN_RADIAL_GRADIENT:
{
RadialGradientPattern *radGradPat = static_cast<RadialGradientPattern*>(mOrigPattern);
mPattern =
new (mRadGradPat) RadialGradientPattern(radGradPat->mCenter1, radGradPat->mCenter2,
radGradPat->mRadius1, radGradPat->mRadius2,
GetGradientStops(radGradPat->mStops),
radGradPat->mMatrix);
return mPattern;
}
default:
return new (mColPat) ColorPattern(Color());
}
return mPattern;
}
union {
char mColPat[sizeof(ColorPattern)];
char mLinGradPat[sizeof(LinearGradientPattern)];
char mRadGradPat[sizeof(RadialGradientPattern)];
char mSurfPat[sizeof(SurfacePattern)];
};
Pattern *mOrigPattern;
Pattern *mPattern;
};
DrawTargetRecording::DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT)
: mRecorder(static_cast<DrawEventRecorderPrivate*>(aRecorder))
, mFinalDT(aDT)
{
mRecorder->RecordEvent(RecordedDrawTargetCreation(this, mFinalDT->GetType(), mFinalDT->GetSize(), mFinalDT->GetFormat()));
mFormat = mFinalDT->GetFormat();
}
DrawTargetRecording::~DrawTargetRecording()
{
mRecorder->RecordEvent(RecordedDrawTargetDestruction(this));
}
void
DrawTargetRecording::FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions)
{
mRecorder->RecordEvent(RecordedFillRect(this, aRect, aPattern, aOptions));
mFinalDT->FillRect(aRect, *AdjustedPattern(aPattern), aOptions);
}
void
DrawTargetRecording::StrokeRect(const Rect &aRect,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions,
const DrawOptions &aOptions)
{
mRecorder->RecordEvent(RecordedStrokeRect(this, aRect, aPattern, aStrokeOptions, aOptions));
mFinalDT->StrokeRect(aRect, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
}
void
DrawTargetRecording::StrokeLine(const Point &aBegin,
const Point &aEnd,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions,
const DrawOptions &aOptions)
{
mRecorder->RecordEvent(RecordedStrokeLine(this, aBegin, aEnd, aPattern, aStrokeOptions, aOptions));
mFinalDT->StrokeLine(aBegin, aEnd, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
}
Path*
DrawTargetRecording::GetPathForPathRecording(const Path *aPath) const
{
if (aPath->GetBackendType() != BACKEND_RECORDING) {
return NULL;
}
return static_cast<const PathRecording*>(aPath)->mPath;
}
void
DrawTargetRecording::Fill(const Path *aPath,
const Pattern &aPattern,
const DrawOptions &aOptions)
{
EnsureStored(aPath);
mRecorder->RecordEvent(RecordedFill(this, const_cast<Path*>(aPath), aPattern, aOptions));
mFinalDT->Fill(GetPathForPathRecording(aPath), *AdjustedPattern(aPattern), aOptions);
}
struct RecordingFontUserData
{
void *refPtr;
RefPtr<DrawEventRecorderPrivate> recorder;
};
void RecordingFontUserDataDestroyFunc(void *aUserData)
{
RecordingFontUserData *userData =
static_cast<RecordingFontUserData*>(aUserData);
userData->recorder->RecordEvent(RecordedScaledFontDestruction(userData->refPtr));
delete userData;
}
void
DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer,
const Pattern &aPattern,
const DrawOptions &aOptions,
const GlyphRenderingOptions *aRenderingOptions)
{
if (!aFont->GetUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()))) {
mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, aFont));
RecordingFontUserData *userData = new RecordingFontUserData;
userData->refPtr = aFont;
userData->recorder = mRecorder;
aFont->AddUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()), userData,
&RecordingFontUserDataDestroyFunc);
}
mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs));
mFinalDT->FillGlyphs(aFont, aBuffer, aPattern, aOptions, aRenderingOptions);
}
void
DrawTargetRecording::Mask(const Pattern &aSource,
const Pattern &aMask,
const DrawOptions &aOptions)
{
mRecorder->RecordEvent(RecordedMask(this, aSource, aMask, aOptions));
mFinalDT->Mask(*AdjustedPattern(aSource), *AdjustedPattern(aMask), aOptions);
}
void
DrawTargetRecording::Stroke(const Path *aPath,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions,
const DrawOptions &aOptions)
{
EnsureStored(aPath);
mRecorder->RecordEvent(RecordedStroke(this, const_cast<Path*>(aPath), aPattern, aStrokeOptions, aOptions));
mFinalDT->Stroke(GetPathForPathRecording(aPath), *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
}
TemporaryRef<SourceSurface>
DrawTargetRecording::Snapshot()
{
RefPtr<SourceSurface> surf = mFinalDT->Snapshot();
RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
mRecorder->RecordEvent(RecordedSnapshot(retSurf, this));
return retSurf;
}
void
DrawTargetRecording::DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions,
const DrawOptions &aOptions)
{
mRecorder->RecordEvent(RecordedDrawSurface(this, aSurface, aDest, aSource, aSurfOptions, aOptions));
mFinalDT->DrawSurface(GetSourceSurface(aSurface), aDest, aSource, aSurfOptions, aOptions);
}
void
DrawTargetRecording::DrawSurfaceWithShadow(SourceSurface *aSurface,
const Point &aDest,
const Color &aColor,
const Point &aOffset,
Float aSigma,
CompositionOp aOp)
{
mRecorder->RecordEvent(RecordedDrawSurfaceWithShadow(this, aSurface, aDest, aColor, aOffset, aSigma, aOp));
mFinalDT->DrawSurfaceWithShadow(GetSourceSurface(aSurface), aDest, aColor, aOffset, aSigma, aOp);
}
void
DrawTargetRecording::ClearRect(const Rect &aRect)
{
mRecorder->RecordEvent(RecordedClearRect(this, aRect));
mFinalDT->ClearRect(aRect);
}
void
DrawTargetRecording::CopySurface(SourceSurface *aSurface,
const IntRect &aSourceRect,
const IntPoint &aDestination)
{
mRecorder->RecordEvent(RecordedCopySurface(this, aSurface, aSourceRect, aDestination));
mFinalDT->CopySurface(GetSourceSurface(aSurface), aSourceRect, aDestination);
}
void
DrawTargetRecording::PushClip(const Path *aPath)
{
EnsureStored(aPath);
mRecorder->RecordEvent(RecordedPushClip(this, const_cast<Path*>(aPath)));
mFinalDT->PushClip(GetPathForPathRecording(aPath));
}
void
DrawTargetRecording::PushClipRect(const Rect &aRect)
{
mRecorder->RecordEvent(RecordedPushClipRect(this, aRect));
mFinalDT->PushClipRect(aRect);
}
void
DrawTargetRecording::PopClip()
{
mRecorder->RecordEvent(RecordedPopClip(this));
mFinalDT->PopClip();
}
TemporaryRef<SourceSurface>
DrawTargetRecording::CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const
{
RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
mRecorder->RecordEvent(RecordedSourceSurfaceCreation(retSurf, aData, aStride, aSize, aFormat));
return retSurf;
}
TemporaryRef<SourceSurface>
DrawTargetRecording::OptimizeSourceSurface(SourceSurface *aSurface) const
{
RefPtr<SourceSurface> surf = mFinalDT->OptimizeSourceSurface(aSurface);
RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface();
if (!dataSurf) {
// Let's try get it off the original surface.
dataSurf = aSurface->GetDataSurface();
}
if (!dataSurf) {
gfxWarning() << "Recording failed to record SourceSurface created from OptimizeSourceSurface";
// Insert a bogus source surface.
uint8_t *sourceData = new uint8_t[surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())];
memset(sourceData, 0, surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat()));
mRecorder->RecordEvent(
RecordedSourceSurfaceCreation(retSurf, sourceData,
surf->GetSize().width * BytesPerPixel(surf->GetFormat()),
surf->GetSize(), surf->GetFormat()));
delete [] sourceData;
} else {
mRecorder->RecordEvent(
RecordedSourceSurfaceCreation(retSurf, dataSurf->GetData(), dataSurf->Stride(),
dataSurf->GetSize(), dataSurf->GetFormat()));
}
return retSurf;
}
TemporaryRef<SourceSurface>
DrawTargetRecording::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
{
RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromNativeSurface(aSurface);
RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface();
if (!dataSurf) {
gfxWarning() << "Recording failed to record SourceSurface created from OptimizeSourceSurface";
// Insert a bogus source surface.
uint8_t *sourceData = new uint8_t[surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat())];
memset(sourceData, 0, surf->GetSize().width * surf->GetSize().height * BytesPerPixel(surf->GetFormat()));
mRecorder->RecordEvent(
RecordedSourceSurfaceCreation(retSurf, sourceData,
surf->GetSize().width * BytesPerPixel(surf->GetFormat()),
surf->GetSize(), surf->GetFormat()));
delete [] sourceData;
} else {
mRecorder->RecordEvent(
RecordedSourceSurfaceCreation(retSurf, dataSurf->GetData(), dataSurf->Stride(),
dataSurf->GetSize(), dataSurf->GetFormat()));
}
return retSurf;
}
TemporaryRef<DrawTarget>
DrawTargetRecording::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
{
RefPtr<DrawTarget> dt = mFinalDT->CreateSimilarDrawTarget(aSize, aFormat);
RefPtr<DrawTarget> retDT = new DrawTargetRecording(mRecorder.get(), dt);
return retDT;
}
TemporaryRef<PathBuilder>
DrawTargetRecording::CreatePathBuilder(FillRule aFillRule) const
{
RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(aFillRule);
return new PathBuilderRecording(builder, aFillRule);
}
TemporaryRef<GradientStops>
DrawTargetRecording::CreateGradientStops(GradientStop *aStops,
uint32_t aNumStops,
ExtendMode aExtendMode) const
{
RefPtr<GradientStops> stops = mFinalDT->CreateGradientStops(aStops, aNumStops, aExtendMode);
RefPtr<GradientStops> retStops = new GradientStopsRecording(stops, mRecorder);
mRecorder->RecordEvent(RecordedGradientStopsCreation(retStops, aStops, aNumStops, aExtendMode));
return retStops;
}
void
DrawTargetRecording::SetTransform(const Matrix &aTransform)
{
mRecorder->RecordEvent(RecordedSetTransform(this, aTransform));
DrawTarget::SetTransform(aTransform);
mFinalDT->SetTransform(aTransform);
}
void
DrawTargetRecording::EnsureStored(const Path *aPath)
{
if (!mRecorder->HasStoredPath(aPath)) {
if (aPath->GetBackendType() != BACKEND_RECORDING) {
gfxWarning() << "Cannot record this fill path properly!";
} else {
PathRecording *recPath = const_cast<PathRecording*>(static_cast<const PathRecording*>(aPath));
mRecorder->RecordEvent(RecordedPathCreation(recPath));
mRecorder->AddStoredPath(aPath);
recPath->mStoredRecorders.push_back(mRecorder);
}
}
}
}
}

View File

@ -0,0 +1,273 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_DRAWTARGETRECORDING_H_
#define MOZILLA_GFX_DRAWTARGETRECORDING_H_
#include "2D.h"
#include "DrawEventRecorder.h"
namespace mozilla {
namespace gfx {
class DrawTargetRecording : public DrawTarget
{
public:
DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT);
~DrawTargetRecording();
virtual BackendType GetType() const { return mFinalDT->GetType(); }
virtual TemporaryRef<SourceSurface> Snapshot();
virtual IntSize GetSize() { return mFinalDT->GetSize(); }
/* Ensure that the DrawTarget backend has flushed all drawing operations to
* this draw target. This must be called before using the backing surface of
* this draw target outside of GFX 2D code.
*/
virtual void Flush() { mFinalDT->Flush(); }
/*
* Draw a surface to the draw target. Possibly doing partial drawing or
* applying scaling. No sampling happens outside the source.
*
* aSurface Source surface to draw
* aDest Destination rectangle that this drawing operation should draw to
* aSource Source rectangle in aSurface coordinates, this area of aSurface
* will be stretched to the size of aDest.
* aOptions General draw options that are applied to the operation
* aSurfOptions DrawSurface options that are applied
*/
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
const DrawOptions &aOptions = DrawOptions());
/*
* Blend a surface to the draw target with a shadow. The shadow is drawn as a
* gaussian blur using a specified sigma. The shadow is clipped to the size
* of the input surface, so the input surface should contain a transparent
* border the size of the approximate coverage of the blur (3 * aSigma).
* NOTE: This function works in device space!
*
* aSurface Source surface to draw.
* aDest Destination point that this drawing operation should draw to.
* aColor Color of the drawn shadow
* aOffset Offset of the shadow
* aSigma Sigma used for the guassian filter kernel
* aOperator Composition operator used
*/
virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
const Point &aDest,
const Color &aColor,
const Point &aOffset,
Float aSigma,
CompositionOp aOperator);
/*
* Clear a rectangle on the draw target to transparent black. This will
* respect the clipping region and transform.
*
* aRect Rectangle to clear
*/
virtual void ClearRect(const Rect &aRect);
/*
* This is essentially a 'memcpy' between two surfaces. It moves a pixel
* aligned area from the source surface unscaled directly onto the
* drawtarget. This ignores both transform and clip.
*
* aSurface Surface to copy from
* aSourceRect Source rectangle to be copied
* aDest Destination point to copy the surface to
*/
virtual void CopySurface(SourceSurface *aSurface,
const IntRect &aSourceRect,
const IntPoint &aDestination);
/*
* Fill a rectangle on the DrawTarget with a certain source pattern.
*
* aRect Rectangle that forms the mask of this filling operation
* aPattern Pattern that forms the source of this filling operation
* aOptions Options that are applied to this operation
*/
virtual void FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions());
/*
* Stroke a rectangle on the DrawTarget with a certain source pattern.
*
* aRect Rectangle that forms the mask of this stroking operation
* aPattern Pattern that forms the source of this stroking operation
* aOptions Options that are applied to this operation
*/
virtual void StrokeRect(const Rect &aRect,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions());
/*
* Stroke a line on the DrawTarget with a certain source pattern.
*
* aStart Starting point of the line
* aEnd End point of the line
* aPattern Pattern that forms the source of this stroking operation
* aOptions Options that are applied to this operation
*/
virtual void StrokeLine(const Point &aStart,
const Point &aEnd,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions());
/*
* Stroke a path on the draw target with a certain source pattern.
*
* aPath Path that is to be stroked
* aPattern Pattern that should be used for the stroke
* aStrokeOptions Stroke options used for this operation
* aOptions Draw options used for this operation
*/
virtual void Stroke(const Path *aPath,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions());
/*
* Fill a path on the draw target with a certain source pattern.
*
* aPath Path that is to be filled
* aPattern Pattern that should be used for the fill
* aOptions Draw options used for this operation
*/
virtual void Fill(const Path *aPath,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions());
/*
* Fill a series of clyphs on the draw target with a certain source pattern.
*/
virtual void FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions(),
const GlyphRenderingOptions *aRenderingOptions = NULL);
/*
* This takes a source pattern and a mask, and composites the source pattern
* onto the destination surface using the alpha channel of the mask pattern
* as a mask for the operation.
*
* aSource Source pattern
* aMask Mask pattern
* aOptions Drawing options
*/
virtual void Mask(const Pattern &aSource,
const Pattern &aMask,
const DrawOptions &aOptions = DrawOptions());
/*
* Push a clip to the DrawTarget.
*
* aPath The path to clip to
*/
virtual void PushClip(const Path *aPath);
/*
* Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
* is specified in user space.
*
* aRect The rect to clip to
*/
virtual void PushClipRect(const Rect &aRect);
/* Pop a clip from the DrawTarget. A pop without a corresponding push will
* be ignored.
*/
virtual void PopClip();
/*
* Create a SourceSurface optimized for use with this DrawTarget from
* existing bitmap data in memory.
*
* The SourceSurface does not take ownership of aData, and may be freed at any time.
*/
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const;
/*
* Create a SourceSurface optimized for use with this DrawTarget from
* an arbitrary other SourceSurface. This may return aSourceSurface or some
* other existing surface.
*/
virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
/*
* Create a SourceSurface for a type of NativeSurface. This may fail if the
* draw target does not know how to deal with the type of NativeSurface passed
* in.
*/
virtual TemporaryRef<SourceSurface>
CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
/*
* Create a DrawTarget whose snapshot is optimized for use with this DrawTarget.
*/
virtual TemporaryRef<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
/*
* Create a path builder with the specified fillmode.
*
* We need the fill mode up front because of Direct2D.
* ID2D1SimplifiedGeometrySink requires the fill mode
* to be set before calling BeginFigure().
*/
virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const;
/*
* Create a GradientStops object that holds information about a set of
* gradient stops, this object is required for linear or radial gradient
* patterns to represent the color stops in the gradient.
*
* aStops An array of gradient stops
* aNumStops Number of stops in the array aStops
* aExtendNone This describes how to extend the stop color outside of the
* gradient area.
*/
virtual TemporaryRef<GradientStops>
CreateGradientStops(GradientStop *aStops,
uint32_t aNumStops,
ExtendMode aExtendMode = EXTEND_CLAMP) const;
/*
* Set a transform on the surface, this transform is applied at drawing time
* to both the mask and source of the operation.
*/
virtual void SetTransform(const Matrix &aTransform);
/* Tries to get a native surface for a DrawTarget, this may fail if the
* draw target cannot convert to this surface type.
*/
virtual void *GetNativeSurface(NativeSurfaceType aType) { return mFinalDT->GetNativeSurface(aType); }
private:
Path *GetPathForPathRecording(const Path *aPath) const;
void EnsureStored(const Path *aPath);
RefPtr<DrawEventRecorderPrivate> mRecorder;
RefPtr<DrawTarget> mFinalDT;
};
}
}
#endif /* MOZILLA_GFX_DRAWTARGETRECORDING_H_ */

View File

@ -41,6 +41,10 @@ CPPSRCS = \
DrawTargetCairo.cpp \
SourceSurfaceCairo.cpp \
PathCairo.cpp \
DrawTargetRecording.cpp \
PathRecording.cpp \
RecordedEvent.cpp \
DrawEventRecorder.cpp \
Blur.cpp \
ScaledFontBase.cpp \
DrawTargetDual.cpp \

120
gfx/2d/PathRecording.cpp Normal file
View File

@ -0,0 +1,120 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PathRecording.h"
#include "DrawEventRecorder.h"
namespace mozilla {
namespace gfx {
using namespace std;
void
PathBuilderRecording::MoveTo(const Point &aPoint)
{
PathOp op;
op.mType = PathOp::OP_MOVETO;
op.mP1 = aPoint;
mPathOps.push_back(op);
mPathBuilder->MoveTo(aPoint);
}
void
PathBuilderRecording::LineTo(const Point &aPoint)
{
PathOp op;
op.mType = PathOp::OP_LINETO;
op.mP1 = aPoint;
mPathOps.push_back(op);
mPathBuilder->LineTo(aPoint);
}
void
PathBuilderRecording::BezierTo(const Point &aCP1, const Point &aCP2, const Point &aCP3)
{
PathOp op;
op.mType = PathOp::OP_BEZIERTO;
op.mP1 = aCP1;
op.mP2 = aCP2;
op.mP3 = aCP3;
mPathOps.push_back(op);
mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
}
void
PathBuilderRecording::QuadraticBezierTo(const Point &aCP1, const Point &aCP2)
{
PathOp op;
op.mType = PathOp::OP_QUADRATICBEZIERTO;
op.mP1 = aCP1;
op.mP2 = aCP2;
mPathOps.push_back(op);
mPathBuilder->QuadraticBezierTo(aCP1, aCP2);
}
void
PathBuilderRecording::Close()
{
PathOp op;
op.mType = PathOp::OP_CLOSE;
mPathOps.push_back(op);
mPathBuilder->Close();
}
Point
PathBuilderRecording::CurrentPoint() const
{
return mPathBuilder->CurrentPoint();
}
TemporaryRef<Path>
PathBuilderRecording::Finish()
{
RefPtr<Path> path = mPathBuilder->Finish();
return new PathRecording(path, mPathOps, mFillRule);
}
PathRecording::~PathRecording()
{
for (size_t i = 0; i < mStoredRecorders.size(); i++) {
mStoredRecorders[i]->RemoveStoredPath(this);
mStoredRecorders[i]->RecordEvent(RecordedPathDestruction(this));
}
}
TemporaryRef<PathBuilder>
PathRecording::CopyToBuilder(FillRule aFillRule) const
{
RefPtr<PathBuilder> pathBuilder = mPath->CopyToBuilder(aFillRule);
RefPtr<PathBuilderRecording> recording = new PathBuilderRecording(pathBuilder, aFillRule);
recording->mPathOps = mPathOps;
return recording;
}
TemporaryRef<PathBuilder>
PathRecording::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
{
RefPtr<PathBuilder> pathBuilder = mPath->TransformedCopyToBuilder(aTransform, aFillRule);
RefPtr<PathBuilderRecording> recording = new PathBuilderRecording(pathBuilder, aFillRule);
typedef std::vector<PathOp> pathOpVec;
for (pathOpVec::const_iterator iter = mPathOps.begin(); iter != mPathOps.end(); iter++) {
PathOp newPathOp;
newPathOp.mType = iter->mType;
if (sPointCount[newPathOp.mType] >= 1) {
newPathOp.mP1 = aTransform * iter->mP1;
}
if (sPointCount[newPathOp.mType] >= 2) {
newPathOp.mP2 = aTransform * iter->mP2;
}
if (sPointCount[newPathOp.mType] >= 3) {
newPathOp.mP3 = aTransform * iter->mP3;
}
recording->mPathOps.push_back(newPathOp);
}
return recording;
}
}
}

126
gfx/2d/PathRecording.h Normal file
View File

@ -0,0 +1,126 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_PATHRECORDING_H_
#define MOZILLA_GFX_PATHRECORDING_H_
#include "2D.h"
#include <vector>
namespace mozilla {
namespace gfx {
struct PathOp
{
enum OpType {
OP_MOVETO = 0,
OP_LINETO,
OP_BEZIERTO,
OP_QUADRATICBEZIERTO,
OP_ARCTO,
OP_CLOSE
};
OpType mType;
Point mP1;
Point mP2;
Point mP3;
};
const int32_t sPointCount[] = { 1, 1, 3, 2, 0, 0 };
class PathRecording;
class DrawEventRecorderPrivate;
class PathBuilderRecording : public PathBuilder
{
public:
PathBuilderRecording(PathBuilder *aBuilder, FillRule aFillRule)
: mPathBuilder(aBuilder), mFillRule(aFillRule)
{
}
/* Move the current point in the path, any figure currently being drawn will
* be considered closed during fill operations, however when stroking the
* closing line segment will not be drawn.
*/
virtual void MoveTo(const Point &aPoint);
/* Add a linesegment to the current figure */
virtual void LineTo(const Point &aPoint);
/* Add a cubic bezier curve to the current figure */
virtual void BezierTo(const Point &aCP1,
const Point &aCP2,
const Point &aCP3);
/* Add a quadratic bezier curve to the current figure */
virtual void QuadraticBezierTo(const Point &aCP1,
const Point &aCP2);
/* Close the current figure, this will essentially generate a line segment
* from the current point to the starting point for the current figure
*/
virtual void Close();
/* Add an arc to the current figure */
virtual void Arc(const Point &, float, float, float, bool) { }
/* Point the current subpath is at - or where the next subpath will start
* if there is no active subpath.
*/
virtual Point CurrentPoint() const;
virtual TemporaryRef<Path> Finish();
private:
friend class PathRecording;
RefPtr<PathBuilder> mPathBuilder;
FillRule mFillRule;
std::vector<PathOp> mPathOps;
};
class PathRecording : public Path
{
public:
PathRecording(Path *aPath, const std::vector<PathOp> aOps, FillRule aFillRule)
: mPath(aPath), mPathOps(aOps), mFillRule(aFillRule)
{
}
~PathRecording();
virtual BackendType GetBackendType() const { return BACKEND_RECORDING; }
virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FILL_WINDING) const;
virtual TemporaryRef<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
FillRule aFillRule = FILL_WINDING) const;
virtual bool ContainsPoint(const Point &aPoint, const Matrix &aTransform) const
{ return mPath->ContainsPoint(aPoint, aTransform); }
virtual Rect GetBounds(const Matrix &aTransform = Matrix()) const
{ return mPath->GetBounds(aTransform); }
virtual Rect GetStrokedBounds(const StrokeOptions &aStrokeOptions,
const Matrix &aTransform = Matrix()) const
{ return mPath->GetStrokedBounds(aStrokeOptions, aTransform); }
virtual FillRule GetFillRule() const { return mFillRule; }
void StorePath(std::ostream &aStream) const;
static void ReadPathToBuilder(std::istream &aStream, PathBuilder *aBuilder);
private:
friend class DrawTargetRecording;
friend class RecordedPathCreation;
RefPtr<Path> mPath;
std::vector<PathOp> mPathOps;
FillRule mFillRule;
// Event recorders that have this path in their event stream.
std::vector<DrawEventRecorderPrivate*> mStoredRecorders;
};
}
}
#endif /* MOZILLA_GFX_PATHRECORDING_H_ */

1198
gfx/2d/RecordedEvent.cpp Normal file

File diff suppressed because it is too large Load Diff

869
gfx/2d/RecordedEvent.h Normal file
View File

@ -0,0 +1,869 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_RECORDEDEVENT_H_
#define MOZILLA_GFX_RECORDEDEVENT_H_
#include "2D.h"
#include <ostream>
#include <sstream>
#include "RecordingTypes.h"
#include "PathRecording.h"
namespace mozilla {
namespace gfx {
// A change in major revision means a change in event binary format, causing
// loss of backwards compatibility. Old streams will not work in a player
// using a newer major revision. And new streams will not work in a player
// using an older major revision.
const uint16_t kMajorRevision = 1;
// A change in minor revision means additions of new events. New streams will
// not play in older players.
const uint16_t kMinorRevision = 0;
struct ReferencePtr
{
ReferencePtr()
: mLongPtr(0)
{}
ReferencePtr(const void* aLongPtr)
: mLongPtr(uint64_t(aLongPtr))
{}
template <typename T>
ReferencePtr(const RefPtr<T>& aPtr)
: mLongPtr(uint64_t(aPtr.get()))
{}
ReferencePtr &operator =(const void* aLongPtr) {
mLongPtr = uint64_t(aLongPtr);
return *this;
}
template <typename T>
ReferencePtr &operator =(const RefPtr<T>& aPtr) {
mLongPtr = uint64_t(aPtr.get());
return *this;
}
operator void*() const {
return (void*)mLongPtr;
}
uint64_t mLongPtr;
};
static std::string StringFromPtr(ReferencePtr aPtr)
{
std::stringstream stream;
stream << aPtr;
return stream.str();
}
class Translator
{
public:
virtual DrawTarget *LookupDrawTarget(ReferencePtr aRefPtr) = 0;
virtual Path *LookupPath(ReferencePtr aRefPtr) = 0;
virtual SourceSurface *LookupSourceSurface(ReferencePtr aRefPtr) = 0;
virtual GradientStops *LookupGradientStops(ReferencePtr aRefPtr) = 0;
virtual ScaledFont *LookupScaledFont(ReferencePtr aRefPtr) = 0;
virtual void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget *aDT) = 0;
virtual void RemoveDrawTarget(ReferencePtr aRefPtr) = 0;
virtual void AddPath(ReferencePtr aRefPtr, Path *aPath) = 0;
virtual void RemovePath(ReferencePtr aRefPtr) = 0;
virtual void AddSourceSurface(ReferencePtr aRefPtr, SourceSurface *aPath) = 0;
virtual void RemoveSourceSurface(ReferencePtr aRefPtr) = 0;
virtual void AddGradientStops(ReferencePtr aRefPtr, GradientStops *aPath) = 0;
virtual void RemoveGradientStops(ReferencePtr aRefPtr) = 0;
virtual void AddScaledFont(ReferencePtr aRefPtr, ScaledFont *aScaledFont) = 0;
virtual void RemoveScaledFont(ReferencePtr aRefPtr) = 0;
virtual DrawTarget *GetReferenceDrawTarget() = 0;
virtual FontType GetDesiredFontType() = 0;
};
struct ColorPatternStorage
{
Color mColor;
};
struct LinearGradientPatternStorage
{
Point mBegin;
Point mEnd;
ReferencePtr mStops;
Matrix mMatrix;
};
struct RadialGradientPatternStorage
{
Point mCenter1;
Point mCenter2;
Float mRadius1;
Float mRadius2;
ReferencePtr mStops;
Matrix mMatrix;
};
struct SurfacePatternStorage
{
ExtendMode mExtend;
Filter mFilter;
ReferencePtr mSurface;
Matrix mMatrix;
};
struct PatternStorage
{
PatternType mType;
union {
char *mStorage;
char mColor[sizeof(ColorPatternStorage)];
char mLinear[sizeof(LinearGradientPatternStorage)];
char mRadial[sizeof(RadialGradientPatternStorage)];
char mSurface[sizeof(SurfacePatternStorage)];
};
};
class RecordedEvent {
public:
enum EventType {
DRAWTARGETCREATION = 0,
DRAWTARGETDESTRUCTION,
FILLRECT,
STROKERECT,
STROKELINE,
CLEARRECT,
COPYSURFACE,
SETTRANSFORM,
PUSHCLIP,
PUSHCLIPRECT,
POPCLIP,
FILL,
FILLGLYPHS,
MASK,
STROKE,
DRAWSURFACE,
DRAWSURFACEWITHSHADOW,
PATHCREATION,
PATHDESTRUCTION,
SOURCESURFACECREATION,
SOURCESURFACEDESTRUCTION,
GRADIENTSTOPSCREATION,
GRADIENTSTOPSDESTRUCTION,
SNAPSHOT,
SCALEDFONTCREATION,
SCALEDFONTDESTRUCTION
};
virtual void PlayEvent(Translator *aTranslator) const {}
virtual void RecordToStream(std::ostream &aStream) const {}
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const { }
void RecordPatternData(std::ostream &aStream, const PatternStorage &aPatternStorage) const;
void ReadPatternData(std::istream &aStream, PatternStorage &aPatternStorage) const;
void StorePattern(PatternStorage &aDestination, const Pattern &aSource) const;
void RecordStrokeOptions(std::ostream &aStream, const StrokeOptions &aStrokeOptions) const;
void ReadStrokeOptions(std::istream &aStream, StrokeOptions &aStrokeOptions);
virtual std::string GetName() const = 0;
virtual ReferencePtr GetObject() const = 0;
virtual ReferencePtr GetDestinedDT() { return nullptr; }
void OutputSimplePatternInfo(const PatternStorage &aStorage, std::stringstream &aOutput) const;
static RecordedEvent *LoadEventFromStream(std::istream &aStream, EventType aType);
EventType GetType() { return (EventType)mType; }
protected:
friend class DrawEventRecorderPrivate;
RecordedEvent(int32_t aType) : mType(aType)
{}
int32_t mType;
std::vector<Float> mDashPatternStorage;
};
class RecordedDrawingEvent : public RecordedEvent
{
public:
virtual ReferencePtr GetDestinedDT() { return mDT; }
protected:
RecordedDrawingEvent(EventType aType, DrawTarget *aTarget)
: RecordedEvent(aType), mDT(aTarget)
{
}
RecordedDrawingEvent(EventType aType, std::istream &aStream);
virtual void RecordToStream(std::ostream &aStream) const;
virtual ReferencePtr GetObject() const;
DrawTarget *mDT;
};
class RecordedDrawTargetCreation : public RecordedEvent {
public:
RecordedDrawTargetCreation(ReferencePtr aRefPtr, BackendType aType, const IntSize &aSize, SurfaceFormat aFormat)
: RecordedEvent(DRAWTARGETCREATION), mRefPtr(aRefPtr), mBackendType(aType), mSize(aSize), mFormat(aFormat)
{}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "DrawTarget Creation"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
ReferencePtr mRefPtr;
BackendType mBackendType;
IntSize mSize;
SurfaceFormat mFormat;
private:
friend class RecordedEvent;
RecordedDrawTargetCreation(std::istream &aStream);
};
class RecordedDrawTargetDestruction : public RecordedEvent {
public:
RecordedDrawTargetDestruction(ReferencePtr aRefPtr)
: RecordedEvent(DRAWTARGETDESTRUCTION), mRefPtr(aRefPtr)
{}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "DrawTarget Destruction"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
ReferencePtr mRefPtr;
BackendType mBackendType;
private:
friend class RecordedEvent;
RecordedDrawTargetDestruction(std::istream &aStream);
};
class RecordedFillRect : public RecordedDrawingEvent {
public:
RecordedFillRect(DrawTarget *aDT, const Rect &aRect, const Pattern &aPattern, const DrawOptions &aOptions)
: RecordedDrawingEvent(FILLRECT, aDT), mRect(aRect), mOptions(aOptions)
{
StorePattern(mPattern, aPattern);
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "FillRect"; }
private:
friend class RecordedEvent;
RecordedFillRect(std::istream &aStream);
Rect mRect;
PatternStorage mPattern;
DrawOptions mOptions;
};
class RecordedStrokeRect : public RecordedDrawingEvent {
public:
RecordedStrokeRect(DrawTarget *aDT, const Rect &aRect, const Pattern &aPattern,
const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions)
: RecordedDrawingEvent(STROKERECT, aDT), mRect(aRect),
mStrokeOptions(aStrokeOptions), mOptions(aOptions)
{
StorePattern(mPattern, aPattern);
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "StrokeRect"; }
private:
friend class RecordedEvent;
RecordedStrokeRect(std::istream &aStream);
Rect mRect;
PatternStorage mPattern;
StrokeOptions mStrokeOptions;
DrawOptions mOptions;
};
class RecordedStrokeLine : public RecordedDrawingEvent {
public:
RecordedStrokeLine(DrawTarget *aDT, const Point &aBegin, const Point &aEnd,
const Pattern &aPattern, const StrokeOptions &aStrokeOptions,
const DrawOptions &aOptions)
: RecordedDrawingEvent(STROKELINE, aDT), mBegin(aBegin), mEnd(aEnd),
mStrokeOptions(aStrokeOptions), mOptions(aOptions)
{
StorePattern(mPattern, aPattern);
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "StrokeLine"; }
private:
friend class RecordedEvent;
RecordedStrokeLine(std::istream &aStream);
Point mBegin;
Point mEnd;
PatternStorage mPattern;
StrokeOptions mStrokeOptions;
DrawOptions mOptions;
};
class RecordedFill : public RecordedDrawingEvent {
public:
RecordedFill(DrawTarget *aDT, ReferencePtr aPath, const Pattern &aPattern, const DrawOptions &aOptions)
: RecordedDrawingEvent(FILL, aDT), mPath(aPath), mOptions(aOptions)
{
StorePattern(mPattern, aPattern);
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "Fill"; }
private:
friend class RecordedEvent;
RecordedFill(std::istream &aStream);
ReferencePtr mPath;
PatternStorage mPattern;
DrawOptions mOptions;
};
class RecordedFillGlyphs : public RecordedDrawingEvent {
public:
RecordedFillGlyphs(DrawTarget *aDT, ReferencePtr aScaledFont, const Pattern &aPattern, const DrawOptions &aOptions,
const Glyph *aGlyphs, uint32_t aNumGlyphs)
: RecordedDrawingEvent(FILLGLYPHS, aDT), mScaledFont(aScaledFont), mOptions(aOptions)
{
StorePattern(mPattern, aPattern);
mNumGlyphs = aNumGlyphs;
mGlyphs = new Glyph[aNumGlyphs];
memcpy(mGlyphs, aGlyphs, sizeof(Glyph) * aNumGlyphs);
}
virtual ~RecordedFillGlyphs();
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "FillGlyphs"; }
private:
friend class RecordedEvent;
RecordedFillGlyphs(std::istream &aStream);
ReferencePtr mScaledFont;
PatternStorage mPattern;
DrawOptions mOptions;
Glyph *mGlyphs;
uint32_t mNumGlyphs;
};
class RecordedMask : public RecordedDrawingEvent {
public:
RecordedMask(DrawTarget *aDT, const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions)
: RecordedDrawingEvent(MASK, aDT), mOptions(aOptions)
{
StorePattern(mSource, aSource);
StorePattern(mMask, aMask);
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "Mask"; }
private:
friend class RecordedEvent;
RecordedMask(std::istream &aStream);
PatternStorage mSource;
PatternStorage mMask;
DrawOptions mOptions;
};
class RecordedStroke : public RecordedDrawingEvent {
public:
RecordedStroke(DrawTarget *aDT, ReferencePtr aPath, const Pattern &aPattern,
const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions)
: RecordedDrawingEvent(STROKE, aDT), mPath(aPath),
mStrokeOptions(aStrokeOptions), mOptions(aOptions)
{
StorePattern(mPattern, aPattern);
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "Stroke"; }
private:
friend class RecordedEvent;
RecordedStroke(std::istream &aStream);
ReferencePtr mPath;
PatternStorage mPattern;
StrokeOptions mStrokeOptions;
DrawOptions mOptions;
};
class RecordedClearRect : public RecordedDrawingEvent {
public:
RecordedClearRect(DrawTarget *aDT, const Rect &aRect)
: RecordedDrawingEvent(CLEARRECT, aDT), mRect(aRect)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "ClearRect"; }
private:
friend class RecordedEvent;
RecordedClearRect(std::istream &aStream);
Rect mRect;
};
class RecordedCopySurface : public RecordedDrawingEvent {
public:
RecordedCopySurface(DrawTarget *aDT, ReferencePtr aSourceSurface,
const IntRect &aSourceRect, const IntPoint &aDest)
: RecordedDrawingEvent(COPYSURFACE, aDT), mSourceSurface(aSourceSurface),
mSourceRect(aSourceRect), mDest(aDest)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "CopySurface"; }
private:
friend class RecordedEvent;
RecordedCopySurface(std::istream &aStream);
ReferencePtr mSourceSurface;
IntRect mSourceRect;
IntPoint mDest;
};
class RecordedPushClip : public RecordedDrawingEvent {
public:
RecordedPushClip(DrawTarget *aDT, ReferencePtr aPath)
: RecordedDrawingEvent(PUSHCLIP, aDT), mPath(aPath)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "PushClip"; }
private:
friend class RecordedEvent;
RecordedPushClip(std::istream &aStream);
ReferencePtr mPath;
};
class RecordedPushClipRect : public RecordedDrawingEvent {
public:
RecordedPushClipRect(DrawTarget *aDT, const Rect &aRect)
: RecordedDrawingEvent(PUSHCLIPRECT, aDT), mRect(aRect)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "PushClipRect"; }
private:
friend class RecordedEvent;
RecordedPushClipRect(std::istream &aStream);
Rect mRect;
};
class RecordedPopClip : public RecordedDrawingEvent {
public:
RecordedPopClip(DrawTarget *aDT)
: RecordedDrawingEvent(POPCLIP, aDT)
{}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "PopClip"; }
private:
friend class RecordedEvent;
RecordedPopClip(std::istream &aStream);
};
class RecordedSetTransform : public RecordedDrawingEvent {
public:
RecordedSetTransform(DrawTarget *aDT, const Matrix &aTransform)
: RecordedDrawingEvent(SETTRANSFORM, aDT), mTransform(aTransform)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "SetTransform"; }
private:
friend class RecordedEvent;
RecordedSetTransform(std::istream &aStream);
Matrix mTransform;
};
class RecordedDrawSurface : public RecordedDrawingEvent {
public:
RecordedDrawSurface(DrawTarget *aDT, ReferencePtr aRefSource, const Rect &aDest,
const Rect &aSource, const DrawSurfaceOptions &aDSOptions,
const DrawOptions &aOptions)
: RecordedDrawingEvent(DRAWSURFACE, aDT), mRefSource(aRefSource), mDest(aDest)
, mSource(aSource), mDSOptions(aDSOptions), mOptions(aOptions)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "DrawSurface"; }
private:
friend class RecordedEvent;
RecordedDrawSurface(std::istream &aStream);
ReferencePtr mRefSource;
Rect mDest;
Rect mSource;
DrawSurfaceOptions mDSOptions;
DrawOptions mOptions;
};
class RecordedDrawSurfaceWithShadow : public RecordedDrawingEvent {
public:
RecordedDrawSurfaceWithShadow(DrawTarget *aDT, ReferencePtr aRefSource, const Point &aDest,
const Color &aColor, const Point &aOffset,
Float aSigma, CompositionOp aOp)
: RecordedDrawingEvent(DRAWSURFACEWITHSHADOW, aDT), mRefSource(aRefSource), mDest(aDest)
, mColor(aColor), mOffset(aOffset), mSigma(aSigma), mOp(aOp)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "DrawSurfaceWithShadow"; }
private:
friend class RecordedEvent;
RecordedDrawSurfaceWithShadow(std::istream &aStream);
ReferencePtr mRefSource;
Point mDest;
Color mColor;
Point mOffset;
Float mSigma;
CompositionOp mOp;
};
class RecordedPathCreation : public RecordedEvent {
public:
RecordedPathCreation(PathRecording *aPath);
~RecordedPathCreation();
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "Path Creation"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
private:
friend class RecordedEvent;
ReferencePtr mRefPtr;
FillRule mFillRule;
std::vector<PathOp> mPathOps;
RecordedPathCreation(std::istream &aStream);
};
class RecordedPathDestruction : public RecordedEvent {
public:
RecordedPathDestruction(PathRecording *aPath)
: RecordedEvent(PATHDESTRUCTION), mRefPtr(aPath)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "Path Destruction"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
private:
friend class RecordedEvent;
ReferencePtr mRefPtr;
RecordedPathDestruction(std::istream &aStream);
};
class RecordedSourceSurfaceCreation : public RecordedEvent {
public:
RecordedSourceSurfaceCreation(ReferencePtr aRefPtr, uint8_t *aData, int32_t aStride,
const IntSize &aSize, SurfaceFormat aFormat)
: RecordedEvent(SOURCESURFACECREATION), mRefPtr(aRefPtr), mData(aData)
, mStride(aStride), mSize(aSize), mFormat(aFormat), mDataOwned(false)
{
}
~RecordedSourceSurfaceCreation();
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "SourceSurface Creation"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
private:
friend class RecordedEvent;
ReferencePtr mRefPtr;
uint8_t *mData;
int32_t mStride;
IntSize mSize;
SurfaceFormat mFormat;
bool mDataOwned;
RecordedSourceSurfaceCreation(std::istream &aStream);
};
class RecordedSourceSurfaceDestruction : public RecordedEvent {
public:
RecordedSourceSurfaceDestruction(ReferencePtr aRefPtr)
: RecordedEvent(SOURCESURFACEDESTRUCTION), mRefPtr(aRefPtr)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "SourceSurface Destruction"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
private:
friend class RecordedEvent;
ReferencePtr mRefPtr;
RecordedSourceSurfaceDestruction(std::istream &aStream);
};
class RecordedGradientStopsCreation : public RecordedEvent {
public:
RecordedGradientStopsCreation(ReferencePtr aRefPtr, GradientStop *aStops,
uint32_t aNumStops, ExtendMode aExtendMode)
: RecordedEvent(GRADIENTSTOPSCREATION), mRefPtr(aRefPtr), mStops(aStops)
, mNumStops(aNumStops), mExtendMode(aExtendMode), mDataOwned(false)
{
}
~RecordedGradientStopsCreation();
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "GradientStops Creation"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
private:
friend class RecordedEvent;
ReferencePtr mRefPtr;
GradientStop *mStops;
uint32_t mNumStops;
ExtendMode mExtendMode;
bool mDataOwned;
RecordedGradientStopsCreation(std::istream &aStream);
};
class RecordedGradientStopsDestruction : public RecordedEvent {
public:
RecordedGradientStopsDestruction(ReferencePtr aRefPtr)
: RecordedEvent(GRADIENTSTOPSDESTRUCTION), mRefPtr(aRefPtr)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "GradientStops Destruction"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
private:
friend class RecordedEvent;
ReferencePtr mRefPtr;
RecordedGradientStopsDestruction(std::istream &aStream);
};
class RecordedSnapshot : public RecordedEvent {
public:
RecordedSnapshot(ReferencePtr aRefPtr, DrawTarget *aDT)
: RecordedEvent(SNAPSHOT), mRefPtr(aRefPtr), mDT(aDT)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "Snapshot"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
private:
friend class RecordedEvent;
ReferencePtr mRefPtr;
DrawTarget *mDT;
RecordedSnapshot(std::istream &aStream);
};
class RecordedScaledFontCreation : public RecordedEvent {
public:
static void FontDataProc(const uint8_t *aData, uint32_t aSize, uint32_t aIndex, Float aGlyphSize, void* aBaton)
{
static_cast<RecordedScaledFontCreation*>(aBaton)->SetFontData(aData, aSize, aIndex, aGlyphSize);
}
RecordedScaledFontCreation(ReferencePtr aRefPtr, ScaledFont *aScaledFont)
: RecordedEvent(SCALEDFONTCREATION), mRefPtr(aRefPtr), mData(NULL)
{
aScaledFont->GetFontFileData(&FontDataProc, this);
}
~RecordedScaledFontCreation();
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "ScaledFont Creation"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
void SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex, Float aGlyphSize);
private:
friend class RecordedEvent;
ReferencePtr mRefPtr;
uint8_t *mData;
uint32_t mSize;
Float mGlyphSize;
uint32_t mIndex;
RecordedScaledFontCreation(std::istream &aStream);
};
class RecordedScaledFontDestruction : public RecordedEvent {
public:
RecordedScaledFontDestruction(ReferencePtr aRefPtr)
: RecordedEvent(SCALEDFONTDESTRUCTION), mRefPtr(aRefPtr)
{
}
virtual void PlayEvent(Translator *aTranslator) const;
virtual void RecordToStream(std::ostream &aStream) const;
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
virtual std::string GetName() const { return "ScaledFont Destruction"; }
virtual ReferencePtr GetObject() const { return mRefPtr; }
private:
friend class RecordedEvent;
ReferencePtr mRefPtr;
RecordedScaledFontDestruction(std::istream &aStream);
};
}
}
#endif

41
gfx/2d/RecordingTypes.h Normal file
View File

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_RECORDINGTYPES_H_
#define MOZILLA_GFX_RECORDINGTYPES_H_
#include <ostream>
namespace mozilla {
namespace gfx {
template<class T>
struct ElementStreamFormat
{
static void Write(std::ostream &aStream, const T &aElement)
{
aStream.write(reinterpret_cast<const char*>(&aElement), sizeof(T));
}
static void Read(std::istream &aStream, T &aElement)
{
aStream.read(reinterpret_cast<char *>(&aElement), sizeof(T));
}
};
template<class T>
void WriteElement(std::ostream &aStream, const T &aElement)
{
ElementStreamFormat<T>::Write(aStream, aElement);
}
template<class T>
void ReadElement(std::istream &aStream, T &aElement)
{
ElementStreamFormat<T>::Read(aStream, aElement);
}
}
}
#endif /* MOZILLA_GFX_RECORDINGTYPES_H_ */

View File

@ -26,7 +26,8 @@ enum SurfaceType
SURFACE_COREGRAPHICS_IMAGE, /* Surface wrapping a CoreGraphics Image */
SURFACE_COREGRAPHICS_CGCONTEXT, /* Surface wrapping a CG context */
SURFACE_SKIA, /* Surface wrapping a Skia bitmap */
SURFACE_DUAL_DT /* Snapshot of a dual drawtarget */
SURFACE_DUAL_DT, /* Snapshot of a dual drawtarget */
SURFACE_RECORDING /* Surface used for recording */
};
enum SurfaceFormat
@ -44,7 +45,8 @@ enum BackendType
BACKEND_COREGRAPHICS,
BACKEND_COREGRAPHICS_ACCELERATED,
BACKEND_CAIRO,
BACKEND_SKIA
BACKEND_SKIA,
BACKEND_RECORDING
};
enum FontType

View File

@ -81,15 +81,20 @@
<ClInclude Include="BasePoint.h" />
<ClInclude Include="BaseRect.h" />
<ClInclude Include="BaseSize.h" />
<ClInclude Include="DrawEventRecorder.h" />
<ClInclude Include="DrawTargetD2D.h" />
<ClInclude Include="DrawTargetDual.h" />
<ClInclude Include="DrawTargetRecording.h" />
<ClInclude Include="GradientStopsD2D.h" />
<ClInclude Include="HelpersD2D.h" />
<ClInclude Include="ImageScaling.h" />
<ClInclude Include="Logging.h" />
<ClInclude Include="Matrix.h" />
<ClInclude Include="PathD2D.h" />
<ClInclude Include="PathRecording.h" />
<ClInclude Include="Point.h" />
<ClInclude Include="RecordedEvent.h" />
<ClInclude Include="RecordingTypes.h" />
<ClInclude Include="Rect.h" />
<ClInclude Include="ScaledFontBase.h" />
<ClInclude Include="ScaledFontDWrite.h" />
@ -101,13 +106,17 @@
<ClInclude Include="UserData.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="DrawEventRecorder.cpp" />
<ClCompile Include="DrawTargetD2D.cpp" />
<ClCompile Include="DrawTargetDual.cpp" />
<ClCompile Include="DrawTargetRecording.cpp" />
<ClCompile Include="Factory.cpp" />
<ClCompile Include="ImageScaling.cpp" />
<ClCompile Include="ImageScalingSSE2.cpp" />
<ClCompile Include="Matrix.cpp" />
<ClCompile Include="PathD2D.cpp" />
<ClCompile Include="PathRecording.cpp" />
<ClCompile Include="RecordedEvent.cpp" />
<ClCompile Include="ScaledFontBase.cpp" />
<ClCompile Include="ScaledFontDWrite.cpp" />
<ClCompile Include="SourceSurfaceD2D.cpp" />

View File

@ -126,6 +126,8 @@ GetBackendName(mozilla::gfx::BackendType aBackend)
return "cairo";
case mozilla::gfx::BACKEND_SKIA:
return "skia";
case mozilla::gfx::BACKEND_RECORDING:
return "recording";
case mozilla::gfx::BACKEND_NONE:
return "none";
}