tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SharedPlanarYCbCrImage.cpp (6849B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "SharedPlanarYCbCrImage.h"
      8 #include <stddef.h>              // for size_t
      9 #include <stdio.h>               // for printf
     10 #include "gfx2DGlue.h"           // for Moz2D transition helpers
     11 #include "ISurfaceAllocator.h"   // for ISurfaceAllocator, etc
     12 #include "mozilla/Assertions.h"  // for MOZ_ASSERT, etc
     13 #include "mozilla/gfx/Types.h"   // for SurfaceFormat::SurfaceFormat::YUV
     14 #include "mozilla/layers/ImageClient.h"     // for ImageClient
     15 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
     16 #include "mozilla/layers/TextureClient.h"
     17 #include "mozilla/layers/TextureClientRecycleAllocator.h"
     18 #include "mozilla/layers/BufferTexture.h"
     19 #include "mozilla/layers/ImageDataSerializer.h"
     20 #include "mozilla/layers/ImageBridgeChild.h"  // for ImageBridgeChild
     21 #include "mozilla/mozalloc.h"                 // for operator delete
     22 #include "nsISupportsImpl.h"                  // for Image::AddRef
     23 #include "mozilla/ipc/Shmem.h"
     24 
     25 namespace mozilla {
     26 namespace layers {
     27 
     28 using namespace mozilla::ipc;
     29 
     30 SharedPlanarYCbCrImage::SharedPlanarYCbCrImage(ImageClient* aCompositable)
     31    : mCompositable(aCompositable) {
     32  MOZ_COUNT_CTOR(SharedPlanarYCbCrImage);
     33 }
     34 
     35 SharedPlanarYCbCrImage::SharedPlanarYCbCrImage(
     36    TextureClientRecycleAllocator* aRecycleAllocator)
     37    : mRecycleAllocator(aRecycleAllocator) {
     38  MOZ_COUNT_CTOR(SharedPlanarYCbCrImage);
     39 }
     40 
     41 SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
     42  MOZ_COUNT_DTOR(SharedPlanarYCbCrImage);
     43 }
     44 
     45 TextureClientRecycleAllocator* SharedPlanarYCbCrImage::RecycleAllocator() {
     46  static const uint32_t MAX_POOLED_VIDEO_COUNT = 5;
     47 
     48  if (!mRecycleAllocator && mCompositable) {
     49    if (!mCompositable->HasTextureClientRecycler()) {
     50      // Initialize TextureClientRecycler
     51      mCompositable->GetTextureClientRecycler()->SetMaxPoolSize(
     52          MAX_POOLED_VIDEO_COUNT);
     53    }
     54    mRecycleAllocator = mCompositable->GetTextureClientRecycler();
     55  }
     56  return mRecycleAllocator;
     57 }
     58 
     59 size_t SharedPlanarYCbCrImage::SizeOfExcludingThis(
     60    MallocSizeOf aMallocSizeOf) const {
     61  // NB: Explicitly skipping mTextureClient, the memory is already reported
     62  //     at time of allocation in GfxMemoryImageReporter.
     63  // Not owned:
     64  // - mCompositable
     65  return 0;
     66 }
     67 
     68 TextureClient* SharedPlanarYCbCrImage::GetTextureClient(
     69    KnowsCompositor* aKnowsCompositor) {
     70  return mTextureClient.get();
     71 }
     72 
     73 already_AddRefed<gfx::SourceSurface>
     74 SharedPlanarYCbCrImage::GetAsSourceSurface() {
     75  if (!IsValid()) {
     76    NS_WARNING("Can't get as surface");
     77    return nullptr;
     78  }
     79  return PlanarYCbCrImage::GetAsSourceSurface();
     80 }
     81 
     82 nsresult SharedPlanarYCbCrImage::CopyData(const PlanarYCbCrData& aData) {
     83  // If mTextureClient has not already been allocated by CreateEmptyBuffer,
     84  // allocate it. This code path is slower than the one used when
     85  // CreateEmptyBuffer has been called since it will trigger a full copy.
     86  if (!mTextureClient) {
     87    nsresult r =
     88        CreateEmptyBuffer(aData, aData.YDataSize(), aData.CbCrDataSize());
     89    if (NS_FAILED(r)) {
     90      return r;
     91    }
     92  }
     93 
     94  TextureClientAutoLock autoLock(mTextureClient, OpenMode::OPEN_WRITE_ONLY);
     95  if (!autoLock.Succeeded()) {
     96    MOZ_ASSERT(false, "Failed to lock the texture.");
     97    return NS_ERROR_UNEXPECTED;
     98  }
     99 
    100  if (!UpdateYCbCrTextureClient(mTextureClient, aData)) {
    101    MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
    102    return NS_ERROR_UNEXPECTED;
    103  }
    104  mTextureClient->MarkImmutable();
    105  return NS_OK;
    106 }
    107 
    108 nsresult SharedPlanarYCbCrImage::AdoptData(const Data& aData) {
    109  MOZ_ASSERT(false, "This shouldn't be used.");
    110  return NS_ERROR_NOT_IMPLEMENTED;
    111 }
    112 
    113 bool SharedPlanarYCbCrImage::IsValid() const {
    114  return mTextureClient && mTextureClient->IsValid();
    115 }
    116 
    117 nsresult SharedPlanarYCbCrImage::CreateEmptyBuffer(
    118    const PlanarYCbCrData& aData, const gfx::IntSize& aYSize,
    119    const gfx::IntSize& aCbCrSize) {
    120  MOZ_ASSERT(!mTextureClient, "This image already has allocated data");
    121 
    122  TextureFlags flags =
    123      mCompositable ? mCompositable->GetTextureFlags() : TextureFlags::DEFAULT;
    124  {
    125    YCbCrTextureClientAllocationHelper helper(aData, aYSize, aCbCrSize, flags);
    126    Result<already_AddRefed<TextureClient>, nsresult> result =
    127        RecycleAllocator()->CreateOrRecycle(helper);
    128    if (result.isErr()) {
    129      return Err(result.unwrapErr());
    130    }
    131    mTextureClient = result.unwrap();
    132  }
    133 
    134  if (!mTextureClient) {
    135    NS_WARNING("SharedPlanarYCbCrImage::Allocate failed.");
    136    // TODO: TextureClientRecycleAllocator::CreateOrRecycle may return NULL on
    137    // non out-of-memory failures.
    138    return NS_ERROR_OUT_OF_MEMORY;
    139  }
    140 
    141  MappedYCbCrTextureData mapped;
    142  // The locking here is sort of a lie. The SharedPlanarYCbCrImage just pulls
    143  // pointers out of the TextureClient and keeps them around, which works only
    144  // because the underlyin BufferTextureData is always mapped in memory even
    145  // outside of the lock/unlock interval. That's sad and new code should follow
    146  // this example.
    147  if (!mTextureClient->Lock(OpenMode::OPEN_READ) ||
    148      !mTextureClient->BorrowMappedYCbCrData(mapped)) {
    149    MOZ_CRASH("GFX: Cannot lock or borrow mapped YCbCr");
    150  }
    151 
    152  // copy some of aData's values in mData (most of them)
    153  mData.mYChannel = mapped.y.data;
    154  mData.mCbChannel = mapped.cb.data;
    155  mData.mCrChannel = mapped.cr.data;
    156  mData.mPictureRect = aData.mPictureRect;
    157  mData.mStereoMode = aData.mStereoMode;
    158  mData.mYUVColorSpace = aData.mYUVColorSpace;
    159  mData.mColorDepth = aData.mColorDepth;
    160  mData.mChromaSubsampling = aData.mChromaSubsampling;
    161  // those members are not always equal to aData's, due to potentially different
    162  // packing.
    163  mData.mYSkip = 0;
    164  mData.mCbSkip = 0;
    165  mData.mCrSkip = 0;
    166  mData.mYStride = aData.mYStride;
    167  mData.mCbCrStride = aData.mCbCrStride;
    168 
    169  // do not set mBuffer like in PlanarYCbCrImage because the later
    170  // will try to manage this memory without knowing it belongs to a
    171  // shmem.
    172  mBufferSize = ImageDataSerializer::ComputeYCbCrBufferSize(
    173      aYSize, mData.mYStride, aCbCrSize, mData.mCbCrStride);
    174  mSize = mData.mPictureRect.Size();
    175  mOrigin = mData.mPictureRect.TopLeft();
    176 
    177  mTextureClient->Unlock();
    178 
    179  // ImageDataSerializer::ComputeYCbCrBufferSize may return zero when the size
    180  // requested is out of the limit.
    181  return mBufferSize > 0 ? NS_OK : NS_ERROR_INVALID_ARG;
    182 }
    183 
    184 void SharedPlanarYCbCrImage::SetIsDRM(bool aIsDRM) {
    185  Image::SetIsDRM(aIsDRM);
    186  if (mTextureClient) {
    187    mTextureClient->AddFlags(TextureFlags::DRM_SOURCE);
    188  }
    189 }
    190 
    191 }  // namespace layers
    192 }  // namespace mozilla