зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1290293 - Part 1. Make assert ensuring RBGX surfaces set alpha to 0xFF only check sampled bytes. r=mchang
This commit is contained in:
Родитель
8607eb6848
Коммит
8407184bc0
|
@ -139,6 +139,29 @@ WriteRGBXFormat(uint8_t* aData, const IntSize &aSize,
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static IntRect
|
||||
CalculateSurfaceBounds(const IntSize &aSize, const Rect* aBounds, const Matrix* aMatrix)
|
||||
{
|
||||
IntRect surfaceBounds(IntPoint(0, 0), aSize);
|
||||
if (!aBounds) {
|
||||
return surfaceBounds;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aMatrix);
|
||||
Matrix inverse(*aMatrix);
|
||||
if (!inverse.Invert()) {
|
||||
return surfaceBounds;
|
||||
}
|
||||
|
||||
IntRect bounds;
|
||||
Rect sampledBounds = inverse.TransformBounds(*aBounds);
|
||||
if (!sampledBounds.ToIntRect(&bounds)) {
|
||||
return surfaceBounds;
|
||||
}
|
||||
|
||||
return surfaceBounds.Intersect(bounds);
|
||||
}
|
||||
|
||||
static bool
|
||||
VerifyRGBXFormat(uint8_t* aData, const IntSize &aSize, const int32_t aStride, SurfaceFormat aFormat)
|
||||
{
|
||||
|
@ -170,27 +193,32 @@ VerifyRGBXFormat(uint8_t* aData, const IntSize &aSize, const int32_t aStride, Su
|
|||
// Since checking every pixel is expensive, this only checks the four corners and center
|
||||
// of a surface that their alpha value is 0xFF.
|
||||
static bool
|
||||
VerifyRGBXCorners(uint8_t* aData, const IntSize &aSize, const int32_t aStride, SurfaceFormat aFormat)
|
||||
VerifyRGBXCorners(uint8_t* aData, const IntSize &aSize, const int32_t aStride, SurfaceFormat aFormat, const Rect* aBounds = nullptr, const Matrix* aMatrix = nullptr)
|
||||
{
|
||||
if (aFormat != SurfaceFormat::B8G8R8X8 || aSize.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int height = aSize.height;
|
||||
int width = aSize.width;
|
||||
const int pixelSize = 4;
|
||||
const int strideDiff = aStride - (width * pixelSize);
|
||||
MOZ_ASSERT(width * pixelSize <= aStride);
|
||||
IntRect bounds = CalculateSurfaceBounds(aSize, aBounds, aMatrix);
|
||||
if (bounds.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const int topLeft = 0;
|
||||
const int topRight = width * pixelSize - pixelSize;
|
||||
const int bottomRight = aStride * height - strideDiff - pixelSize;
|
||||
const int bottomLeft = aStride * height - aStride;
|
||||
const int height = bounds.height;
|
||||
const int width = bounds.width;
|
||||
const int pixelSize = 4;
|
||||
MOZ_ASSERT(aSize.width * pixelSize <= aStride);
|
||||
|
||||
const int translation = bounds.y * aStride + bounds.x * pixelSize;
|
||||
const int topLeft = translation;
|
||||
const int topRight = topLeft + (width - 1) * pixelSize;
|
||||
const int bottomLeft = translation + (height - 1) * aStride;
|
||||
const int bottomRight = bottomLeft + (width - 1) * pixelSize;
|
||||
|
||||
// Lastly the center pixel
|
||||
int middleRowHeight = height / 2;
|
||||
int middleRowWidth = (width / 2) * pixelSize;
|
||||
const int middle = aStride * middleRowHeight + middleRowWidth;
|
||||
const int middleRowHeight = height / 2;
|
||||
const int middleRowWidth = (width / 2) * pixelSize;
|
||||
const int middle = translation + aStride * middleRowHeight + middleRowWidth;
|
||||
|
||||
const int offsets[] = { topLeft, topRight, bottomRight, bottomLeft, middle };
|
||||
for (int offset : offsets) {
|
||||
|
@ -198,7 +226,9 @@ VerifyRGBXCorners(uint8_t* aData, const IntSize &aSize, const int32_t aStride, S
|
|||
int row = offset / aStride;
|
||||
int column = (offset % aStride) / pixelSize;
|
||||
gfxCriticalError() << "RGBX corner pixel at (" << column << "," << row << ") in "
|
||||
<< width << "x" << height << " surface is not opaque: "
|
||||
<< aSize.width << "x" << aSize.height << " surface, bounded by "
|
||||
<< "(" << bounds.x << "," << bounds.y << "," << width << ","
|
||||
<< height << ") is not opaque: "
|
||||
<< int(aData[offset]) << ","
|
||||
<< int(aData[offset+1]) << ","
|
||||
<< int(aData[offset+2]) << ","
|
||||
|
@ -211,7 +241,7 @@ VerifyRGBXCorners(uint8_t* aData, const IntSize &aSize, const int32_t aStride, S
|
|||
#endif
|
||||
|
||||
static sk_sp<SkImage>
|
||||
GetSkImageForSurface(SourceSurface* aSurface)
|
||||
GetSkImageForSurface(SourceSurface* aSurface, const Rect* aBounds = nullptr, const Matrix* aMatrix = nullptr)
|
||||
{
|
||||
if (!aSurface) {
|
||||
gfxDebug() << "Creating null Skia image from null SourceSurface";
|
||||
|
@ -238,7 +268,8 @@ GetSkImageForSurface(SourceSurface* aSurface)
|
|||
|
||||
// Skia doesn't support RGBX surfaces so ensure that the alpha value is opaque white.
|
||||
MOZ_ASSERT(VerifyRGBXCorners(surf->GetData(), surf->GetSize(),
|
||||
surf->Stride(), surf->GetFormat()));
|
||||
surf->Stride(), surf->GetFormat(),
|
||||
aBounds, aMatrix));
|
||||
return image;
|
||||
}
|
||||
|
||||
|
@ -410,7 +441,7 @@ ExtractAlphaForSurface(SourceSurface* aSurface)
|
|||
}
|
||||
|
||||
static void
|
||||
SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Point aOffset = Point(0, 0))
|
||||
SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Point aOffset = Point(0, 0), const Rect* aBounds = nullptr)
|
||||
{
|
||||
switch (aPattern.GetType()) {
|
||||
case PatternType::COLOR: {
|
||||
|
@ -472,7 +503,7 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Po
|
|||
}
|
||||
case PatternType::SURFACE: {
|
||||
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
|
||||
sk_sp<SkImage> image = GetSkImageForSurface(pat.mSurface);
|
||||
sk_sp<SkImage> image = GetSkImageForSurface(pat.mSurface, aBounds, &pat.mMatrix);
|
||||
if (!image) {
|
||||
aPaint.setColor(SK_ColorTRANSPARENT);
|
||||
break;
|
||||
|
@ -520,11 +551,11 @@ GetClipBounds(SkCanvas *aCanvas)
|
|||
}
|
||||
|
||||
struct AutoPaintSetup {
|
||||
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Pattern& aPattern, const Rect* aMaskBounds = nullptr, Point aOffset = Point(0, 0))
|
||||
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Pattern& aPattern, const Rect* aMaskBounds = nullptr, Point aOffset = Point(0, 0), const Rect* aSourceBounds = nullptr)
|
||||
: mNeedsRestore(false), mAlpha(1.0)
|
||||
{
|
||||
Init(aCanvas, aOptions, aMaskBounds, false);
|
||||
SetPaintPattern(mPaint, aPattern, mAlpha, aOffset);
|
||||
SetPaintPattern(mPaint, aPattern, mAlpha, aOffset, aSourceBounds);
|
||||
}
|
||||
|
||||
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Rect* aMaskBounds = nullptr, bool aForceGroup = false)
|
||||
|
@ -753,7 +784,7 @@ DrawTargetSkia::FillRect(const Rect &aRect,
|
|||
|
||||
MarkChanged();
|
||||
SkRect rect = RectToSkRect(aRect);
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern, &aRect);
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern, &aRect, Point(0, 0), &aRect);
|
||||
|
||||
mCanvas->drawRect(rect, paint.mPaint);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче