author | Markus Stange <mstange.moz@gmail.com> |
Thu, 14 Oct 2021 20:17:02 +0000 | |
changeset 595982 | 5b05c21bd9199c4e2cab2fac67b582123e644043 |
parent 595981 | 5bc725606c819815fe8e56465023fc24ecc28ffb |
child 595983 | bdfd88ac24907afcc06de7b0fd170d5a81ce8458 |
push id | 151530 |
push user | mwoodrow@mozilla.com |
push date | Thu, 14 Oct 2021 20:19:24 +0000 |
treeherder | autoland@5b05c21bd919 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bradwerth |
bugs | 1735893 |
milestone | 95.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
gfx/layers/MacIOSurfaceImage.cpp | file | annotate | diff | comparison | revisions | |
modules/libpref/init/StaticPrefList.yaml | file | annotate | diff | comparison | revisions |
--- a/gfx/layers/MacIOSurfaceImage.cpp +++ b/gfx/layers/MacIOSurfaceImage.cpp @@ -59,57 +59,87 @@ bool MacIOSurfaceImage::SetData(ImageCon RefPtr<MacIOSurfaceRecycleAllocator> allocator = aContainer->GetMacIOSurfaceRecycleAllocator(); RefPtr<MacIOSurface> surf = allocator->Allocate( aData.mYSize, aData.mCbCrSize, aData.mYUVColorSpace, aData.mColorRange); surf->Lock(false); - // If the CbCrSize's height is half of the YSize's height, then we'll - // need to duplicate the CbCr data on every second row. - size_t heightScale = aData.mYSize.height / aData.mCbCrSize.height; + if (surf->GetFormat() == SurfaceFormat::YUV422) { + // If the CbCrSize's height is half of the YSize's height, then we'll + // need to duplicate the CbCr data on every second row. + size_t heightScale = aData.mYSize.height / aData.mCbCrSize.height; - MOZ_ASSERT(surf->GetFormat() == SurfaceFormat::YUV422); + // The underlying IOSurface has format + // kCVPixelFormatType_422YpCbCr8FullRange or + // kCVPixelFormatType_422YpCbCr8_yuvs, which uses a 4:2:2 Y`0 Cb Y`1 Cr + // layout. See CVPixelBuffer.h for the full list of format descriptions. + MOZ_ASSERT(aData.mYSize.height > 0); + uint8_t* dst = (uint8_t*)surf->GetBaseAddressOfPlane(0); + size_t stride = surf->GetBytesPerRow(0); + for (size_t i = 0; i < (size_t)aData.mYSize.height; i++) { + // Compute the row addresses. If the input was 4:2:0, then + // we divide i by 2, so that each source row of CbCr maps to + // two dest rows. + uint8_t* rowYSrc = aData.mYChannel + aData.mYStride * i; + uint8_t* rowCbSrc = + aData.mCbChannel + aData.mCbCrStride * (i / heightScale); + uint8_t* rowCrSrc = + aData.mCrChannel + aData.mCbCrStride * (i / heightScale); + uint8_t* rowDst = dst + stride * i; + + // Iterate across the CbCr width (which we have guaranteed to be half of + // the surface width), and write two 16bit pixels each time. + for (size_t j = 0; j < (size_t)aData.mCbCrSize.width; j++) { + *rowDst = *rowYSrc; + rowDst++; + rowYSrc++; + + *rowDst = *rowCbSrc; + rowDst++; + rowCbSrc++; - // The underlying IOSurface has format kCVPixelFormatType_422YpCbCr8FullRange - // or kCVPixelFormatType_422YpCbCr8_yuvs, which uses a 4:2:2 Y`0 Cb Y`1 Cr - // layout. See CVPixelBuffer.h for the full list of format descriptions. - MOZ_ASSERT(aData.mYSize.height > 0); - uint8_t* dst = (uint8_t*)surf->GetBaseAddressOfPlane(0); - size_t stride = surf->GetBytesPerRow(0); - for (size_t i = 0; i < (size_t)aData.mYSize.height; i++) { - // Compute the row addresses. If the input was 4:2:0, then - // we divide i by 2, so that each source row of CbCr maps to - // two dest rows. - uint8_t* rowYSrc = aData.mYChannel + aData.mYStride * i; - uint8_t* rowCbSrc = - aData.mCbChannel + aData.mCbCrStride * (i / heightScale); - uint8_t* rowCrSrc = - aData.mCrChannel + aData.mCbCrStride * (i / heightScale); - uint8_t* rowDst = dst + stride * i; + *rowDst = *rowYSrc; + rowDst++; + rowYSrc++; + + *rowDst = *rowCrSrc; + rowDst++; + rowCrSrc++; + } + } + } else if (surf->GetFormat() == SurfaceFormat::NV12) { + MOZ_ASSERT(aData.mYSize.height > 0); + uint8_t* dst = (uint8_t*)surf->GetBaseAddressOfPlane(0); + size_t stride = surf->GetBytesPerRow(0); + for (size_t i = 0; i < (size_t)aData.mYSize.height; i++) { + uint8_t* rowSrc = aData.mYChannel + aData.mYStride * i; + uint8_t* rowDst = dst + stride * i; + memcpy(rowDst, rowSrc, aData.mYSize.width); + } - // Iterate across the CbCr width (which we have guaranteed to be half of - // the surface width), and write two 16bit pixels each time. - for (size_t j = 0; j < (size_t)aData.mCbCrSize.width; j++) { - *rowDst = *rowYSrc; - rowDst++; - rowYSrc++; + // Copy and interleave the Cb and Cr channels. + MOZ_ASSERT(aData.mCbCrSize.height > 0); + dst = (uint8_t*)surf->GetBaseAddressOfPlane(1); + stride = surf->GetBytesPerRow(1); + for (size_t i = 0; i < (size_t)aData.mCbCrSize.height; i++) { + uint8_t* rowCbSrc = aData.mCbChannel + aData.mCbCrStride * i; + uint8_t* rowCrSrc = aData.mCrChannel + aData.mCbCrStride * i; + uint8_t* rowDst = dst + stride * i; - *rowDst = *rowCbSrc; - rowDst++; - rowCbSrc++; + for (size_t j = 0; j < (size_t)aData.mCbCrSize.width; j++) { + *rowDst = *rowCbSrc; + rowDst++; + rowCbSrc++; - *rowDst = *rowYSrc; - rowDst++; - rowYSrc++; - - *rowDst = *rowCrSrc; - rowDst++; - rowCrSrc++; + *rowDst = *rowCrSrc; + rowDst++; + rowCrSrc++; + } } } surf->Unlock(false); mSurface = surf; mPictureRect = aData.GetPictureRect(); return true; } @@ -132,18 +162,23 @@ already_AddRefed<MacIOSurface> MacIOSurf if (!result && !::IOSurfaceIsInUse(surf.get())) { result = new MacIOSurface(surf, false, aYUVColorSpace); } mSurfaces.AppendElement(surf); } if (!result) { - result = - MacIOSurface::CreateYUV422Surface(aYSize, aYUVColorSpace, aColorRange); + if (StaticPrefs::layers_iosurfaceimage_use_nv12_AtStartup()) { + result = MacIOSurface::CreateNV12Surface(aYSize, aCbCrSize, + aYUVColorSpace, aColorRange); + } else { + result = MacIOSurface::CreateYUV422Surface(aYSize, aYUVColorSpace, + aColorRange); + } if (mSurfaces.Length() < StaticPrefs::layers_iosurfaceimage_recycle_limit()) { mSurfaces.AppendElement(result->GetIOSurfaceRef()); } } return result.forget();
--- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -6527,16 +6527,21 @@ value: true mirror: once - name: layers.iosurfaceimage.recycle-limit type: RelaxedAtomicUint32 value: 15 mirror: always +- name: layers.iosurfaceimage.use-nv12 + type: bool + value: false + mirror: once + #--------------------------------------------------------------------------- # Prefs starting with "layout." #--------------------------------------------------------------------------- # Debug-only pref to force enable the AccessibleCaret. If you want to # control AccessibleCaret by mouse, you'll need to set # "layout.accessiblecaret.hide_carets_for_mouse_input" to false. - name: layout.accessiblecaret.enabled