[gfx][Skia] Hold mutex while accessing shared SkImage data.
parent
5136ec6010
commit
983728fddc
|
@ -212,7 +212,7 @@ VerifyRGBXCorners(uint8_t* aData, const IntSize &aSize, const int32_t aStride, S
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static sk_sp<SkImage>
|
static sk_sp<SkImage>
|
||||||
GetSkImageForSurface(SourceSurface* aSurface)
|
GetSkImageForSurface(SourceSurface* aSurface, Maybe<MutexAutoLock>* aLock)
|
||||||
{
|
{
|
||||||
if (!aSurface) {
|
if (!aSurface) {
|
||||||
gfxDebug() << "Creating null Skia image from null SourceSurface";
|
gfxDebug() << "Creating null Skia image from null SourceSurface";
|
||||||
|
@ -220,7 +220,7 @@ GetSkImageForSurface(SourceSurface* aSurface)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aSurface->GetType() == SurfaceType::SKIA) {
|
if (aSurface->GetType() == SurfaceType::SKIA) {
|
||||||
return static_cast<SourceSurfaceSkia*>(aSurface)->GetImage();
|
return static_cast<SourceSurfaceSkia*>(aSurface)->GetImage(aLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
DataSourceSurface* surf = aSurface->GetDataSurface().take();
|
DataSourceSurface* surf = aSurface->GetDataSurface().take();
|
||||||
|
@ -390,9 +390,9 @@ ExtractAlphaBitmap(sk_sp<SkImage> aImage, SkBitmap* aResultBitmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
static sk_sp<SkImage>
|
static sk_sp<SkImage>
|
||||||
ExtractAlphaForSurface(SourceSurface* aSurface)
|
ExtractAlphaForSurface(SourceSurface* aSurface, Maybe<MutexAutoLock>& aLock)
|
||||||
{
|
{
|
||||||
sk_sp<SkImage> image = GetSkImageForSurface(aSurface);
|
sk_sp<SkImage> image = GetSkImageForSurface(aSurface, &aLock);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,11 @@ ExtractAlphaForSurface(SourceSurface* aSurface)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Point aOffset = Point(0, 0))
|
SetPaintPattern(SkPaint& aPaint,
|
||||||
|
const Pattern& aPattern,
|
||||||
|
Maybe<MutexAutoLock>& aLock,
|
||||||
|
Float aAlpha = 1.0,
|
||||||
|
Point aOffset = Point(0, 0))
|
||||||
{
|
{
|
||||||
switch (aPattern.GetType()) {
|
switch (aPattern.GetType()) {
|
||||||
case PatternType::COLOR: {
|
case PatternType::COLOR: {
|
||||||
|
@ -473,7 +477,7 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Po
|
||||||
}
|
}
|
||||||
case PatternType::SURFACE: {
|
case PatternType::SURFACE: {
|
||||||
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
|
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
|
||||||
sk_sp<SkImage> image = GetSkImageForSurface(pat.mSurface);
|
sk_sp<SkImage> image = GetSkImageForSurface(pat.mSurface, &aLock);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
aPaint.setColor(SK_ColorTRANSPARENT);
|
aPaint.setColor(SK_ColorTRANSPARENT);
|
||||||
break;
|
break;
|
||||||
|
@ -525,7 +529,7 @@ struct AutoPaintSetup {
|
||||||
: mNeedsRestore(false), mAlpha(1.0)
|
: mNeedsRestore(false), mAlpha(1.0)
|
||||||
{
|
{
|
||||||
Init(aCanvas, aOptions, aMaskBounds, false);
|
Init(aCanvas, aOptions, aMaskBounds, false);
|
||||||
SetPaintPattern(mPaint, aPattern, mAlpha, aOffset);
|
SetPaintPattern(mPaint, aPattern, mLock, mAlpha, aOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Rect* aMaskBounds = nullptr, bool aForceGroup = false)
|
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Rect* aMaskBounds = nullptr, bool aForceGroup = false)
|
||||||
|
@ -579,6 +583,7 @@ struct AutoPaintSetup {
|
||||||
SkPaint mPaint;
|
SkPaint mPaint;
|
||||||
bool mNeedsRestore;
|
bool mNeedsRestore;
|
||||||
SkCanvas* mCanvas;
|
SkCanvas* mCanvas;
|
||||||
|
Maybe<MutexAutoLock> mLock;
|
||||||
Float mAlpha;
|
Float mAlpha;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -601,7 +606,8 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
|
||||||
|
|
||||||
MarkChanged();
|
MarkChanged();
|
||||||
|
|
||||||
sk_sp<SkImage> image = GetSkImageForSurface(aSurface);
|
Maybe<MutexAutoLock> lock;
|
||||||
|
sk_sp<SkImage> image = GetSkImageForSurface(aSurface, &lock);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -654,7 +660,8 @@ DrawTargetSkia::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
||||||
|
|
||||||
MarkChanged();
|
MarkChanged();
|
||||||
|
|
||||||
sk_sp<SkImage> image = GetSkImageForSurface(aSurface);
|
Maybe<MutexAutoLock> lock;
|
||||||
|
sk_sp<SkImage> image = GetSkImageForSurface(aSurface, &lock);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1407,8 +1414,9 @@ DrawTargetSkia::Mask(const Pattern &aSource,
|
||||||
MarkChanged();
|
MarkChanged();
|
||||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aSource);
|
AutoPaintSetup paint(mCanvas.get(), aOptions, aSource);
|
||||||
|
|
||||||
|
Maybe<MutexAutoLock> lock;
|
||||||
SkPaint maskPaint;
|
SkPaint maskPaint;
|
||||||
SetPaintPattern(maskPaint, aMask);
|
SetPaintPattern(maskPaint, aMask, lock);
|
||||||
|
|
||||||
SkLayerRasterizer::Builder builder;
|
SkLayerRasterizer::Builder builder;
|
||||||
builder.addLayer(maskPaint);
|
builder.addLayer(maskPaint);
|
||||||
|
@ -1427,7 +1435,8 @@ DrawTargetSkia::MaskSurface(const Pattern &aSource,
|
||||||
MarkChanged();
|
MarkChanged();
|
||||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aSource, nullptr, -aOffset);
|
AutoPaintSetup paint(mCanvas.get(), aOptions, aSource, nullptr, -aOffset);
|
||||||
|
|
||||||
sk_sp<SkImage> alphaMask = ExtractAlphaForSurface(aMask);
|
Maybe<MutexAutoLock> lock;
|
||||||
|
sk_sp<SkImage> alphaMask = ExtractAlphaForSurface(aMask, lock);
|
||||||
if (!alphaMask) {
|
if (!alphaMask) {
|
||||||
gfxDebug() << *this << ": MaskSurface() failed to extract alpha for mask";
|
gfxDebug() << *this << ": MaskSurface() failed to extract alpha for mask";
|
||||||
return;
|
return;
|
||||||
|
@ -1456,7 +1465,8 @@ DrawTarget::Draw3DTransformedSurface(SourceSurface* aSurface, const Matrix4x4& a
|
||||||
fullMat.PostTranslate(-xformBounds.x, -xformBounds.y, 0);
|
fullMat.PostTranslate(-xformBounds.x, -xformBounds.y, 0);
|
||||||
|
|
||||||
// Read in the source data.
|
// Read in the source data.
|
||||||
sk_sp<SkImage> srcImage = GetSkImageForSurface(aSurface);
|
Maybe<MutexAutoLock> lock;
|
||||||
|
sk_sp<SkImage> srcImage = GetSkImageForSurface(aSurface, &lock);
|
||||||
if (!srcImage) {
|
if (!srcImage) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1515,7 +1525,8 @@ DrawTargetSkia::Draw3DTransformedSurface(SourceSurface* aSurface, const Matrix4x
|
||||||
|
|
||||||
MarkChanged();
|
MarkChanged();
|
||||||
|
|
||||||
sk_sp<SkImage> image = GetSkImageForSurface(aSurface);
|
Maybe<MutexAutoLock> lock;
|
||||||
|
sk_sp<SkImage> image = GetSkImageForSurface(aSurface, &lock);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1599,7 +1610,8 @@ already_AddRefed<SourceSurface>
|
||||||
DrawTargetSkia::OptimizeGPUSourceSurface(SourceSurface *aSurface) const
|
DrawTargetSkia::OptimizeGPUSourceSurface(SourceSurface *aSurface) const
|
||||||
{
|
{
|
||||||
// Check if the underlying SkImage already has an associated GrTexture.
|
// Check if the underlying SkImage already has an associated GrTexture.
|
||||||
sk_sp<SkImage> image = GetSkImageForSurface(aSurface);
|
Maybe<MutexAutoLock> lock;
|
||||||
|
sk_sp<SkImage> image = GetSkImageForSurface(aSurface, &lock);
|
||||||
if (!image || image->isTextureBacked()) {
|
if (!image || image->isTextureBacked()) {
|
||||||
RefPtr<SourceSurface> surface(aSurface);
|
RefPtr<SourceSurface> surface(aSurface);
|
||||||
return surface.forget();
|
return surface.forget();
|
||||||
|
@ -1716,7 +1728,8 @@ DrawTargetSkia::CopySurface(SourceSurface *aSurface,
|
||||||
{
|
{
|
||||||
MarkChanged();
|
MarkChanged();
|
||||||
|
|
||||||
sk_sp<SkImage> image = GetSkImageForSurface(aSurface);
|
Maybe<MutexAutoLock> lock;
|
||||||
|
sk_sp<SkImage> image = GetSkImageForSurface(aSurface, &lock);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2061,7 +2074,8 @@ DrawTargetSkia::PopLayer()
|
||||||
paint.setColor(SK_ColorTRANSPARENT);
|
paint.setColor(SK_ColorTRANSPARENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<SkImage> alphaMask = ExtractAlphaForSurface(layer.mMask);
|
Maybe<MutexAutoLock> lock;
|
||||||
|
sk_sp<SkImage> alphaMask = ExtractAlphaForSurface(layer.mMask, lock);
|
||||||
if (!alphaMask) {
|
if (!alphaMask) {
|
||||||
gfxDebug() << *this << ": PopLayer() failed to extract alpha for mask";
|
gfxDebug() << *this << ": PopLayer() failed to extract alpha for mask";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -40,6 +40,25 @@ SourceSurfaceSkia::GetFormat() const
|
||||||
return mFormat;
|
return mFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sk_sp<SkImage>
|
||||||
|
SourceSurfaceSkia::GetImage(Maybe<MutexAutoLock>* aLock) {
|
||||||
|
// If we were provided a lock object, we can let the caller access
|
||||||
|
// a shared SkImage and we know it won't go away while the lock is held.
|
||||||
|
if (aLock) {
|
||||||
|
// We are locked, so now we can check mDrawTarget.
|
||||||
|
// If it's null, then we're not shared and we can unlock eagerly.
|
||||||
|
if (!mDrawTarget) {
|
||||||
|
aLock->reset();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Otherwise we need to call DrawTargetWillChange to ensure we have our
|
||||||
|
// own copy of the SkImage.
|
||||||
|
DrawTargetWillChange();
|
||||||
|
}
|
||||||
|
sk_sp<SkImage> image = mImage;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
static sk_sp<SkData>
|
static sk_sp<SkData>
|
||||||
MakeSkData(unsigned char* aData, const IntSize& aSize, int32_t aStride)
|
MakeSkData(unsigned char* aData, const IntSize& aSize, int32_t aStride)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "skia/include/core/SkCanvas.h"
|
#include "skia/include/core/SkCanvas.h"
|
||||||
#include "skia/include/core/SkImage.h"
|
#include "skia/include/core/SkImage.h"
|
||||||
|
#include "mozilla/Maybe.h"
|
||||||
|
#include "mozilla/Mutex.h"
|
||||||
|
|
||||||
|
typedef mozilla::MutexAutoLock MutexAutoLock;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
@ -28,7 +32,7 @@ public:
|
||||||
virtual IntSize GetSize() const;
|
virtual IntSize GetSize() const;
|
||||||
virtual SurfaceFormat GetFormat() const;
|
virtual SurfaceFormat GetFormat() const;
|
||||||
|
|
||||||
sk_sp<SkImage>& GetImage() { return mImage; }
|
sk_sp<SkImage> GetImage(Maybe<MutexAutoLock>* aLock);
|
||||||
|
|
||||||
bool InitFromData(unsigned char* aData,
|
bool InitFromData(unsigned char* aData,
|
||||||
const IntSize &aSize,
|
const IntSize &aSize,
|
||||||
|
|
Loading…
Reference in New Issue