mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 688368 - Make SourceSurfaceSkia data surfaces copy-on-write. r=joe
This commit is contained in:
parent
20deb50620
commit
f3a5978660
@ -201,16 +201,17 @@ DrawTargetSkia::DrawTargetSkia()
|
||||
|
||||
DrawTargetSkia::~DrawTargetSkia()
|
||||
{
|
||||
MarkChanged();
|
||||
}
|
||||
|
||||
TemporaryRef<SourceSurface>
|
||||
DrawTargetSkia::Snapshot()
|
||||
{
|
||||
//TODO: Wrong! Copy the pixels, preferably lazily
|
||||
RefPtr<SourceSurfaceSkia> source = new SourceSurfaceSkia();
|
||||
if (!source->InitWithBitmap(mCanvas.get(), mFormat)) {
|
||||
if (!source->InitWithBitmap(mBitmap, mFormat, this)) {
|
||||
return NULL;
|
||||
}
|
||||
AppendSnapshot(source);
|
||||
return source;
|
||||
}
|
||||
|
||||
@ -383,6 +384,8 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
|
||||
return;
|
||||
}
|
||||
|
||||
MarkChanged();
|
||||
|
||||
NS_ASSERTION(aSurfOptions.mFilter == FILTER_LINEAR, "Only linear filtering supported currently!");
|
||||
SkRect destRect = RectToSkRect(aDest);
|
||||
SkRect sourceRect = RectToSkRect(aSource);
|
||||
@ -407,6 +410,7 @@ DrawTargetSkia::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
||||
Float aSigma,
|
||||
CompositionOp aOperator)
|
||||
{
|
||||
MarkChanged();
|
||||
mCanvas->save(SkCanvas::kMatrix_SaveFlag);
|
||||
mCanvas->resetMatrix();
|
||||
|
||||
@ -466,6 +470,7 @@ DrawTargetSkia::FillRect(const Rect &aRect,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
MarkChanged();
|
||||
SkRect rect = RectToSkRect(aRect);
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
|
||||
|
||||
@ -478,6 +483,7 @@ DrawTargetSkia::Stroke(const Path *aPath,
|
||||
const StrokeOptions &aStrokeOptions,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
MarkChanged();
|
||||
if (aPath->GetBackendType() != BACKEND_SKIA) {
|
||||
return;
|
||||
}
|
||||
@ -497,6 +503,7 @@ DrawTargetSkia::StrokeRect(const Rect &aRect,
|
||||
const StrokeOptions &aStrokeOptions,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
MarkChanged();
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
|
||||
paint.SetStroke(aStrokeOptions);
|
||||
|
||||
@ -510,6 +517,7 @@ DrawTargetSkia::StrokeLine(const Point &aStart,
|
||||
const StrokeOptions &aStrokeOptions,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
MarkChanged();
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
|
||||
paint.SetStroke(aStrokeOptions);
|
||||
|
||||
@ -523,6 +531,7 @@ DrawTargetSkia::Fill(const Path *aPath,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
MarkChanged();
|
||||
if (aPath->GetBackendType() != BACKEND_SKIA) {
|
||||
return;
|
||||
}
|
||||
@ -544,6 +553,8 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
|
||||
return;
|
||||
}
|
||||
|
||||
MarkChanged();
|
||||
|
||||
ScaledFontSkia* skiaFont = static_cast<ScaledFontSkia*>(aFont);
|
||||
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
|
||||
@ -614,6 +625,8 @@ DrawTargetSkia::CopySurface(SourceSurface *aSurface,
|
||||
return;
|
||||
}
|
||||
|
||||
MarkChanged();
|
||||
|
||||
const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap();
|
||||
|
||||
mCanvas->save();
|
||||
@ -664,6 +677,7 @@ DrawTargetSkia::CreatePathBuilder(FillRule aFillRule) const
|
||||
void
|
||||
DrawTargetSkia::ClearRect(const Rect &aRect)
|
||||
{
|
||||
MarkChanged();
|
||||
SkPaint paint;
|
||||
mCanvas->save();
|
||||
mCanvas->clipRect(RectToSkRect(aRect), SkRegion::kIntersect_Op);
|
||||
@ -704,5 +718,33 @@ DrawTargetSkia::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) co
|
||||
return new GradientStopsSkia(stops, aNumStops);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::AppendSnapshot(SourceSurfaceSkia* aSnapshot)
|
||||
{
|
||||
mSnapshots.push_back(aSnapshot);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::RemoveSnapshot(SourceSurfaceSkia* aSnapshot)
|
||||
{
|
||||
std::vector<SourceSurfaceSkia*>::iterator iter = std::find(mSnapshots.begin(), mSnapshots.end(), aSnapshot);
|
||||
if (iter != mSnapshots.end()) {
|
||||
mSnapshots.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::MarkChanged()
|
||||
{
|
||||
if (mSnapshots.size()) {
|
||||
for (std::vector<SourceSurfaceSkia*>::iterator iter = mSnapshots.begin();
|
||||
iter != mSnapshots.end(); iter++) {
|
||||
(*iter)->DrawTargetWillChange();
|
||||
}
|
||||
// All snapshots will now have copied data.
|
||||
mSnapshots.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -42,12 +42,15 @@
|
||||
#include "Rect.h"
|
||||
#include "PathSkia.h"
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class SourceSurfaceSkia;
|
||||
|
||||
class DrawTargetSkia : public DrawTarget
|
||||
{
|
||||
public:
|
||||
@ -119,6 +122,11 @@ public:
|
||||
return stream.str();
|
||||
}
|
||||
private:
|
||||
friend class SourceSurfaceSkia;
|
||||
void AppendSnapshot(SourceSurfaceSkia* aSnapshot);
|
||||
void RemoveSnapshot(SourceSurfaceSkia* aSnapshot);
|
||||
|
||||
void MarkChanged();
|
||||
|
||||
IntSize mSize;
|
||||
SkBitmap mBitmap;
|
||||
@ -126,6 +134,7 @@ private:
|
||||
SkRefPtr<SkDevice> mDevice;
|
||||
nsRefPtr<gfxImageSurface> mImageSurface;
|
||||
SurfaceFormat mFormat;
|
||||
vector<SourceSurfaceSkia*> mSnapshots;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -41,16 +41,19 @@
|
||||
#include "skia/SkBitmap.h"
|
||||
#include "skia/SkDevice.h"
|
||||
#include "HelpersSkia.h"
|
||||
#include "DrawTargetSkia.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
SourceSurfaceSkia::SourceSurfaceSkia()
|
||||
: mDrawTarget(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
SourceSurfaceSkia::~SourceSurfaceSkia()
|
||||
{
|
||||
MarkIndependent();
|
||||
}
|
||||
|
||||
IntSize
|
||||
@ -86,13 +89,20 @@ SourceSurfaceSkia::InitFromData(unsigned char* aData,
|
||||
}
|
||||
|
||||
bool
|
||||
SourceSurfaceSkia::InitWithBitmap(SkCanvas* aBitmap,
|
||||
SurfaceFormat aFormat)
|
||||
SourceSurfaceSkia::InitWithBitmap(const SkBitmap& aBitmap,
|
||||
SurfaceFormat aFormat,
|
||||
DrawTargetSkia* aOwner)
|
||||
{
|
||||
if (aBitmap->readPixels(&mBitmap)) {
|
||||
mStride = mBitmap.rowBytes();
|
||||
mSize = IntSize(mBitmap.width(), mBitmap.height());
|
||||
mFormat = aFormat;
|
||||
mSize = IntSize(aBitmap.width(), aBitmap.height());
|
||||
|
||||
if (aOwner) {
|
||||
mBitmap = aBitmap;
|
||||
mStride = aBitmap.rowBytes();
|
||||
mDrawTarget = aOwner;
|
||||
return true;
|
||||
} else if (aBitmap.copyTo(&mBitmap, aBitmap.getConfig())) {
|
||||
mStride = mBitmap.rowBytes();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -108,6 +118,26 @@ SourceSurfaceSkia::GetData()
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceSkia::DrawTargetWillChange()
|
||||
{
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget = NULL;
|
||||
SkBitmap temp = mBitmap;
|
||||
mBitmap.reset();
|
||||
temp.copyTo(&mBitmap, temp.getConfig());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceSkia::MarkIndependent()
|
||||
{
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->RemoveSnapshot(this);
|
||||
mDrawTarget = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,8 @@
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class DrawTargetSkia;
|
||||
|
||||
class SourceSurfaceSkia : public DataSourceSurface
|
||||
{
|
||||
public:
|
||||
@ -63,8 +65,13 @@ public:
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat);
|
||||
|
||||
bool InitWithBitmap(SkCanvas* aBitmap,
|
||||
SurfaceFormat aFormat);
|
||||
/**
|
||||
* If aOwner is NULL, we make a copy of the pixel data in the bitmap,
|
||||
* otherwise we just reference this data until DrawTargetWillChange is called.
|
||||
*/
|
||||
bool InitWithBitmap(const SkBitmap& aBitmap,
|
||||
SurfaceFormat aFormat,
|
||||
DrawTargetSkia* aOwner);
|
||||
|
||||
|
||||
virtual unsigned char *GetData();
|
||||
@ -74,10 +81,14 @@ public:
|
||||
private:
|
||||
friend class DrawTargetSkia;
|
||||
|
||||
void DrawTargetWillChange();
|
||||
void MarkIndependent();
|
||||
|
||||
SkBitmap mBitmap;
|
||||
SurfaceFormat mFormat;
|
||||
IntSize mSize;
|
||||
int32_t mStride;
|
||||
DrawTargetSkia* mDrawTarget;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user