From 14c6f518cef0f8d69904b8e7a12de51fc4d29254 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 7 Jun 2018 06:21:57 +0200 Subject: [PATCH] Account for offsets when creating buffers for image textures. --- config/milestone.txt | 2 +- gfx/layers/ImageDataSerializer.cpp | 35 ++++++++++++++++++++++++++++ gfx/layers/ImageDataSerializer.h | 6 ++++- gfx/layers/composite/TextureHost.cpp | 6 +++-- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/config/milestone.txt b/config/milestone.txt index b617f64b75..d4c5c3f4bd 100644 --- a/config/milestone.txt +++ b/config/milestone.txt @@ -10,4 +10,4 @@ # hardcoded milestones in the tree from these two files. #-------------------------------------------------------- -4.1.2 +4.1.3 diff --git a/gfx/layers/ImageDataSerializer.cpp b/gfx/layers/ImageDataSerializer.cpp index 08ed83bd99..db11e903c6 100644 --- a/gfx/layers/ImageDataSerializer.cpp +++ b/gfx/layers/ImageDataSerializer.cpp @@ -83,6 +83,41 @@ ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize return ComputeYCbCrBufferSize(aYSize, aYSize.width, aCbCrSize, aCbCrSize.width); } +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 yEnd = aYOffset; + yEnd += yLength; + CheckedInt cbEnd = aCbOffset; + cbEnd += cbCrLength; + CheckedInt 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) { diff --git a/gfx/layers/ImageDataSerializer.h b/gfx/layers/ImageDataSerializer.h index 53a589d21d..4b3194b0c9 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 c930373847..e4a2ffd869 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; }