1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,224 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "SharedPlanarYCbCrImage.h" 1.10 +#include <stddef.h> // for size_t 1.11 +#include <stdio.h> // for printf 1.12 +#include "gfx2DGlue.h" // for Moz2D transition helpers 1.13 +#include "ISurfaceAllocator.h" // for ISurfaceAllocator, etc 1.14 +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 1.15 +#include "mozilla/gfx/Types.h" // for SurfaceFormat::SurfaceFormat::YUV 1.16 +#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc 1.17 +#include "mozilla/layers/ImageClient.h" // for ImageClient 1.18 +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc 1.19 +#include "mozilla/layers/TextureClient.h" // for BufferTextureClient, etc 1.20 +#include "mozilla/layers/YCbCrImageDataSerializer.h" 1.21 +#include "mozilla/layers/ImageBridgeChild.h" // for ImageBridgeChild 1.22 +#include "mozilla/mozalloc.h" // for operator delete 1.23 +#include "nsISupportsImpl.h" // for Image::AddRef 1.24 +#include "mozilla/ipc/Shmem.h" 1.25 + 1.26 +namespace mozilla { 1.27 +namespace layers { 1.28 + 1.29 +using namespace mozilla::ipc; 1.30 + 1.31 +SharedPlanarYCbCrImage::SharedPlanarYCbCrImage(ImageClient* aCompositable) 1.32 +: PlanarYCbCrImage(nullptr) 1.33 +, mCompositable(aCompositable) 1.34 +{ 1.35 + mTextureClient = aCompositable->CreateBufferTextureClient(gfx::SurfaceFormat::YUV); 1.36 + MOZ_COUNT_CTOR(SharedPlanarYCbCrImage); 1.37 +} 1.38 + 1.39 +SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() { 1.40 + MOZ_COUNT_DTOR(SharedPlanarYCbCrImage); 1.41 + 1.42 + if (mCompositable->GetAsyncID() != 0 && 1.43 + !InImageBridgeChildThread()) { 1.44 + ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().drop()); 1.45 + ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().drop()); 1.46 + } 1.47 +} 1.48 + 1.49 +size_t 1.50 +SharedPlanarYCbCrImage::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const 1.51 +{ 1.52 + // NB: Explicitly skipping mTextureClient, the memory is already reported 1.53 + // at time of allocation in GfxMemoryImageReporter. 1.54 + // Not owned: 1.55 + // - mCompositable 1.56 + size_t size = PlanarYCbCrImage::SizeOfExcludingThis(aMallocSizeOf); 1.57 + return size; 1.58 +} 1.59 + 1.60 +TextureClient* 1.61 +SharedPlanarYCbCrImage::GetTextureClient(CompositableClient* aClient) 1.62 +{ 1.63 + return mTextureClient.get(); 1.64 +} 1.65 + 1.66 +uint8_t* 1.67 +SharedPlanarYCbCrImage::GetBuffer() 1.68 +{ 1.69 + return mTextureClient->GetBuffer(); 1.70 +} 1.71 + 1.72 +TemporaryRef<gfx::SourceSurface> 1.73 +SharedPlanarYCbCrImage::GetAsSourceSurface() 1.74 +{ 1.75 + if (!mTextureClient->IsAllocated()) { 1.76 + NS_WARNING("Can't get as surface"); 1.77 + return nullptr; 1.78 + } 1.79 + return PlanarYCbCrImage::GetAsSourceSurface(); 1.80 +} 1.81 + 1.82 +void 1.83 +SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData) 1.84 +{ 1.85 + // If mShmem has not been allocated (through Allocate(aData)), allocate it. 1.86 + // This code path is slower than the one used when Allocate has been called 1.87 + // since it will trigger a full copy. 1.88 + if (!mTextureClient->IsAllocated()) { 1.89 + Data data = aData; 1.90 + if (!Allocate(data)) { 1.91 + NS_WARNING("SharedPlanarYCbCrImage::SetData failed to allocate"); 1.92 + return; 1.93 + } 1.94 + } 1.95 + 1.96 + MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr()); 1.97 + if (!mTextureClient->Lock(OPEN_WRITE_ONLY)) { 1.98 + MOZ_ASSERT(false, "Failed to lock the texture."); 1.99 + return; 1.100 + } 1.101 + TextureClientAutoUnlock unlock(mTextureClient); 1.102 + if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) { 1.103 + MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient"); 1.104 + return; 1.105 + } 1.106 + // do not set mBuffer like in PlanarYCbCrImage because the later 1.107 + // will try to manage this memory without knowing it belongs to a 1.108 + // shmem. 1.109 + mBufferSize = YCbCrImageDataSerializer::ComputeMinBufferSize(mData.mYSize, 1.110 + mData.mCbCrSize); 1.111 + mSize = mData.mPicSize; 1.112 + 1.113 + YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize()); 1.114 + mData.mYChannel = serializer.GetYData(); 1.115 + mData.mCbChannel = serializer.GetCbData(); 1.116 + mData.mCrChannel = serializer.GetCrData(); 1.117 + mTextureClient->MarkImmutable(); 1.118 +} 1.119 + 1.120 +// needs to be overriden because the parent class sets mBuffer which we 1.121 +// do not want to happen. 1.122 +uint8_t* 1.123 +SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize) 1.124 +{ 1.125 + NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(), "This image already has allocated data"); 1.126 + size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aSize); 1.127 + 1.128 + // get new buffer _without_ setting mBuffer. 1.129 + if (!mTextureClient->Allocate(size)) { 1.130 + return nullptr; 1.131 + } 1.132 + 1.133 + // update buffer size 1.134 + mBufferSize = size; 1.135 + 1.136 + YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize()); 1.137 + return serializer.GetData(); 1.138 +} 1.139 + 1.140 +void 1.141 +SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData) 1.142 +{ 1.143 + mData = aData; 1.144 + mSize = aData.mPicSize; 1.145 + /* SetDataNoCopy is used to update YUV plane offsets without (re)allocating 1.146 + * memory previously allocated with AllocateAndGetNewBuffer(). 1.147 + * serializer.GetData() returns the address of the memory previously allocated 1.148 + * with AllocateAndGetNewBuffer(), that we subtract from the Y, Cb, Cr 1.149 + * channels to compute 0-based offsets to pass to InitializeBufferInfo. 1.150 + */ 1.151 + YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize()); 1.152 + uint8_t *base = serializer.GetData(); 1.153 + uint32_t yOffset = aData.mYChannel - base; 1.154 + uint32_t cbOffset = aData.mCbChannel - base; 1.155 + uint32_t crOffset = aData.mCrChannel - base; 1.156 + serializer.InitializeBufferInfo(yOffset, 1.157 + cbOffset, 1.158 + crOffset, 1.159 + aData.mYStride, 1.160 + aData.mCbCrStride, 1.161 + aData.mYSize, 1.162 + aData.mCbCrSize, 1.163 + aData.mStereoMode); 1.164 +} 1.165 + 1.166 +uint8_t* 1.167 +SharedPlanarYCbCrImage::AllocateBuffer(uint32_t aSize) 1.168 +{ 1.169 + NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(), 1.170 + "This image already has allocated data"); 1.171 + if (!mTextureClient->Allocate(aSize)) { 1.172 + return nullptr; 1.173 + } 1.174 + return mTextureClient->GetBuffer(); 1.175 +} 1.176 + 1.177 +bool 1.178 +SharedPlanarYCbCrImage::IsValid() { 1.179 + return mTextureClient->IsAllocated(); 1.180 +} 1.181 + 1.182 +bool 1.183 +SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData) 1.184 +{ 1.185 + NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(), 1.186 + "This image already has allocated data"); 1.187 + 1.188 + size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aData.mYSize, 1.189 + aData.mCbCrSize); 1.190 + 1.191 + if (AllocateBuffer(static_cast<uint32_t>(size)) == nullptr) { 1.192 + return false; 1.193 + } 1.194 + 1.195 + YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize()); 1.196 + serializer.InitializeBufferInfo(aData.mYSize, 1.197 + aData.mCbCrSize, 1.198 + aData.mStereoMode); 1.199 + MOZ_ASSERT(serializer.IsValid()); 1.200 + 1.201 + aData.mYChannel = serializer.GetYData(); 1.202 + aData.mCbChannel = serializer.GetCbData(); 1.203 + aData.mCrChannel = serializer.GetCrData(); 1.204 + 1.205 + // copy some of aData's values in mData (most of them) 1.206 + mData.mYChannel = aData.mYChannel; 1.207 + mData.mCbChannel = aData.mCbChannel; 1.208 + mData.mCrChannel = aData.mCrChannel; 1.209 + mData.mYSize = aData.mYSize; 1.210 + mData.mCbCrSize = aData.mCbCrSize; 1.211 + mData.mPicX = aData.mPicX; 1.212 + mData.mPicY = aData.mPicY; 1.213 + mData.mPicSize = aData.mPicSize; 1.214 + mData.mStereoMode = aData.mStereoMode; 1.215 + // those members are not always equal to aData's, due to potentially different 1.216 + // packing. 1.217 + mData.mYSkip = 0; 1.218 + mData.mCbSkip = 0; 1.219 + mData.mCrSkip = 0; 1.220 + mData.mYStride = mData.mYSize.width; 1.221 + mData.mCbCrStride = mData.mCbCrSize.width; 1.222 + 1.223 + return true; 1.224 +} 1.225 + 1.226 +} // namespace 1.227 +} // namespace