diff options
Diffstat (limited to 'gfx')
-rw-r--r-- | gfx/layers/ImageDataSerializer.cpp | 35 | ||||
-rw-r--r-- | gfx/layers/ImageDataSerializer.h | 6 | ||||
-rw-r--r-- | gfx/layers/composite/TextureHost.cpp | 6 | ||||
-rw-r--r-- | gfx/skia/skia/src/core/SkScan_Path.cpp | 22 |
4 files changed, 52 insertions, 17 deletions
diff --git a/gfx/layers/ImageDataSerializer.cpp b/gfx/layers/ImageDataSerializer.cpp index 08ed83bd9..db11e903c 100644 --- a/gfx/layers/ImageDataSerializer.cpp +++ b/gfx/layers/ImageDataSerializer.cpp @@ -84,6 +84,41 @@ ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize } uint32_t +ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize, + uint32_t aYOffset, uint32_t aCbOffset, uint32_t aCrOffset) +{ + MOZ_ASSERT(aYSize.height >= 0 && aYSize.width >= 0); + + int32_t yStride = aYSize.width; + int32_t cbCrStride = aCbCrSize.width; + if (aYSize.height < 0 || aYSize.width < 0 || aCbCrSize.height < 0 || aCbCrSize.width < 0 || + !gfx::Factory::AllowedSurfaceSize(IntSize(yStride, aYSize.height)) || + !gfx::Factory::AllowedSurfaceSize(IntSize(cbCrStride, aCbCrSize.height))) { + return 0; + } + + uint32_t yLength = GetAlignedStride<4>(yStride, aYSize.height); + uint32_t cbCrLength = GetAlignedStride<4>(cbCrStride, aCbCrSize.height); + if (yLength == 0 || cbCrLength == 0) { + return 0; + } + + CheckedInt<uint32_t> yEnd = aYOffset; + yEnd += yLength; + CheckedInt<uint32_t> cbEnd = aCbOffset; + cbEnd += cbCrLength; + CheckedInt<uint32_t> crEnd = aCrOffset; + crEnd += cbCrLength; + + if (!yEnd.isValid() || !cbEnd.isValid() || !crEnd.isValid() || + yEnd.value() > aCbOffset || cbEnd.value() > aCrOffset) { + return 0; + } + + return crEnd.value(); +} + +uint32_t ComputeYCbCrBufferSize(uint32_t aBufferSize) { return GetAlignedStride<4>(aBufferSize, 1); diff --git a/gfx/layers/ImageDataSerializer.h b/gfx/layers/ImageDataSerializer.h index 53a589d21..4b3194b0c 100644 --- a/gfx/layers/ImageDataSerializer.h +++ b/gfx/layers/ImageDataSerializer.h @@ -47,7 +47,11 @@ uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, int32_t aCbCrStride); uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize); - +uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, + const gfx::IntSize& aCbCrSize, + uint32_t aYOffset, + uint32_t aCbOffset, + uint32_t aCrOffset); uint32_t ComputeYCbCrBufferSize(uint32_t aBufferSize); void ComputeYCbCrOffsets(int32_t yStride, int32_t yHeight, diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index c93037384..e4a2ffd86 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -259,7 +259,9 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc, case BufferDescriptor::TYCbCrDescriptor: { const YCbCrDescriptor& ycbcr = desc.get_YCbCrDescriptor(); reqSize = - ImageDataSerializer::ComputeYCbCrBufferSize(ycbcr.ySize(), ycbcr.cbCrSize()); + ImageDataSerializer::ComputeYCbCrBufferSize(ycbcr.ySize(), ycbcr.cbCrSize(), + ycbcr.yOffset(), ycbcr.cbOffset(), + ycbcr.crOffset()); break; } case BufferDescriptor::TRGBDescriptor: { @@ -272,7 +274,7 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc, MOZ_CRASH("GFX: Bad descriptor"); } - if (bufSize < reqSize) { + if (reqSize == 0 || bufSize < reqSize) { NS_ERROR("A client process gave a shmem too small to fit for its descriptor!"); return nullptr; } diff --git a/gfx/skia/skia/src/core/SkScan_Path.cpp b/gfx/skia/skia/src/core/SkScan_Path.cpp index 5b80492cf..d15d2d54b 100644 --- a/gfx/skia/skia/src/core/SkScan_Path.cpp +++ b/gfx/skia/skia/src/core/SkScan_Path.cpp @@ -591,16 +591,10 @@ static bool clip_to_limit(const SkRegion& orig, SkRegion* reduced) { return true; } -/** - * Variants of SkScalarRoundToInt, identical to SkDScalarRoundToInt except when the input fraction - * is 0.5. When SK_RASTERIZE_EVEN_ROUNDING is enabled, we must bias the result before rounding to - * account for potential FDot6 rounding edge-cases. - */ -#ifdef SK_RASTERIZE_EVEN_ROUNDING -static const double kRoundBias = 0.5 / SK_FDot6One; -#else -static const double kRoundBias = 0.0; -#endif +// Bias used for conservative rounding of float rects to int rects, to nudge the irects a little +// larger, so we don't "think" a path's bounds are inside a clip, when (due to numeric drift in +// the scan-converter) we might walk beyond the predicted limits. +static const double kConservativeRoundBias = 0.5 + 1.5 / SK_FDot6One; /** * Round the value down. This is used to round the top and left of a rectangle, @@ -608,8 +602,8 @@ static const double kRoundBias = 0.0; */ static inline int round_down_to_int(SkScalar x) { double xx = x; - xx -= 0.5 + kRoundBias; - return (int)ceil(xx); + xx -= kConservativeRoundBias; + return pin_double_to_int(ceil(xx)); } /** @@ -618,8 +612,8 @@ static inline int round_down_to_int(SkScalar x) { */ static inline int round_up_to_int(SkScalar x) { double xx = x; - xx += 0.5 + kRoundBias; - return (int)floor(xx); + xx += kConservativeRoundBias; + return pin_double_to_int(floor(xx)); } /** |