RenderBufferTextureHost.cpp (8608B)
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 "RenderBufferTextureHost.h" 8 9 #include "mozilla/gfx/Logging.h" 10 #include "mozilla/layers/ImageDataSerializer.h" 11 12 namespace mozilla { 13 namespace wr { 14 15 RenderBufferTextureHost::RenderBufferTextureHost( 16 uint8_t* aBuffer, const layers::BufferDescriptor& aDescriptor) 17 : mBuffer(aBuffer), 18 mDescriptor(aDescriptor), 19 mMap(), 20 mYMap(), 21 mCbMap(), 22 mCrMap(), 23 mLocked(false) { 24 MOZ_COUNT_CTOR_INHERITED(RenderBufferTextureHost, RenderTextureHost); 25 26 switch (mDescriptor.type()) { 27 case layers::BufferDescriptor::TYCbCrDescriptor: { 28 const layers::YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor(); 29 mSize = ycbcr.display().Size(); 30 mFormat = gfx::SurfaceFormat::YUV420; 31 break; 32 } 33 case layers::BufferDescriptor::TRGBDescriptor: { 34 const layers::RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor(); 35 mSize = rgb.size(); 36 mFormat = rgb.format(); 37 break; 38 } 39 default: 40 gfxCriticalError() << "Bad buffer host descriptor " 41 << (int)mDescriptor.type(); 42 MOZ_CRASH("GFX: Bad descriptor"); 43 } 44 } 45 46 RenderBufferTextureHost::~RenderBufferTextureHost() { 47 MOZ_COUNT_DTOR_INHERITED(RenderBufferTextureHost, RenderTextureHost); 48 } 49 50 wr::WrExternalImage RenderBufferTextureHost::Lock(uint8_t aChannelIndex, 51 gl::GLContext* aGL) { 52 if (!mLocked) { 53 if (!GetBuffer()) { 54 if (!mDestroyed) { 55 // We hit some problems to get the shmem. 56 gfxCriticalNote << "GetBuffer Failed"; 57 } 58 return InvalidToWrExternalImage(); 59 } 60 if (mFormat != gfx::SurfaceFormat::YUV420) { 61 mSurface = gfx::Factory::CreateWrappingDataSourceSurface( 62 GetBuffer(), 63 layers::ImageDataSerializer::GetRGBStride( 64 mDescriptor.get_RGBDescriptor()), 65 mSize, mFormat); 66 if (NS_WARN_IF(!mSurface)) { 67 gfxCriticalNote << "DataSourceSurface is null"; 68 return InvalidToWrExternalImage(); 69 } 70 if (NS_WARN_IF( 71 !mSurface->Map(gfx::DataSourceSurface::MapType::READ, &mMap))) { 72 mSurface = nullptr; 73 gfxCriticalNote << "Failed to map Surface"; 74 return InvalidToWrExternalImage(); 75 } 76 } else { 77 const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor(); 78 auto cbcrSize = layers::ImageDataSerializer::GetCroppedCbCrSize(desc); 79 80 mYSurface = gfx::Factory::CreateWrappingDataSourceSurface( 81 layers::ImageDataSerializer::GetYChannel(GetBuffer(), desc), 82 desc.yStride(), desc.display().Size(), gfx::SurfaceFormat::A8); 83 mCbSurface = gfx::Factory::CreateWrappingDataSourceSurface( 84 layers::ImageDataSerializer::GetCbChannel(GetBuffer(), desc), 85 desc.cbCrStride(), cbcrSize, gfx::SurfaceFormat::A8); 86 mCrSurface = gfx::Factory::CreateWrappingDataSourceSurface( 87 layers::ImageDataSerializer::GetCrChannel(GetBuffer(), desc), 88 desc.cbCrStride(), cbcrSize, gfx::SurfaceFormat::A8); 89 if (NS_WARN_IF(!mYSurface || !mCbSurface || !mCrSurface)) { 90 mYSurface = mCbSurface = mCrSurface = nullptr; 91 gfxCriticalNote << "YCbCr Surface is null"; 92 return InvalidToWrExternalImage(); 93 } 94 if (NS_WARN_IF( 95 !mYSurface->Map(gfx::DataSourceSurface::MapType::READ, &mYMap) || 96 !mCbSurface->Map(gfx::DataSourceSurface::MapType::READ, 97 &mCbMap) || 98 !mCrSurface->Map(gfx::DataSourceSurface::MapType::READ, 99 &mCrMap))) { 100 mYSurface = mCbSurface = mCrSurface = nullptr; 101 gfxCriticalNote << "Failed to map YCbCr Surface"; 102 return InvalidToWrExternalImage(); 103 } 104 } 105 mLocked = true; 106 } 107 108 RenderBufferData data = GetBufferDataForRender(aChannelIndex); 109 return RawDataToWrExternalImage(data.mData, data.mBufferSize); 110 } 111 112 void RenderBufferTextureHost::Unlock() { 113 if (mLocked) { 114 if (mSurface) { 115 mSurface->Unmap(); 116 mSurface = nullptr; 117 } else if (mYSurface) { 118 mYSurface->Unmap(); 119 mCbSurface->Unmap(); 120 mCrSurface->Unmap(); 121 mYSurface = mCbSurface = mCrSurface = nullptr; 122 } 123 mLocked = false; 124 } 125 } 126 127 RenderBufferTextureHost::RenderBufferData 128 RenderBufferTextureHost::GetBufferDataForRender(uint8_t aChannelIndex) { 129 MOZ_ASSERT(mFormat != gfx::SurfaceFormat::YUV420 || aChannelIndex < 3); 130 MOZ_ASSERT(mFormat == gfx::SurfaceFormat::YUV420 || aChannelIndex < 1); 131 MOZ_ASSERT(mLocked); 132 133 if (mFormat != gfx::SurfaceFormat::YUV420) { 134 MOZ_ASSERT(mSurface); 135 136 return RenderBufferData(mMap.mData, 137 mMap.mStride * mSurface->GetSize().height); 138 } else { 139 MOZ_ASSERT(mYSurface && mCbSurface && mCrSurface); 140 141 switch (aChannelIndex) { 142 case 0: 143 return RenderBufferData(mYMap.mData, 144 mYMap.mStride * mYSurface->GetSize().height); 145 break; 146 case 1: 147 return RenderBufferData(mCbMap.mData, 148 mCbMap.mStride * mCbSurface->GetSize().height); 149 break; 150 case 2: 151 return RenderBufferData(mCrMap.mData, 152 mCrMap.mStride * mCrSurface->GetSize().height); 153 break; 154 default: 155 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 156 return RenderBufferData(nullptr, 0); 157 } 158 } 159 } 160 161 size_t RenderBufferTextureHost::GetPlaneCount() const { 162 switch (mDescriptor.type()) { 163 case layers::BufferDescriptor::TYCbCrDescriptor: 164 return 3; 165 default: 166 return 1; 167 } 168 } 169 170 gfx::SurfaceFormat RenderBufferTextureHost::GetFormat() const { 171 switch (mDescriptor.type()) { 172 case layers::BufferDescriptor::TYCbCrDescriptor: 173 return gfx::SurfaceFormat::YUV420; 174 default: 175 return mDescriptor.get_RGBDescriptor().format(); 176 } 177 } 178 179 gfx::ColorDepth RenderBufferTextureHost::GetColorDepth() const { 180 switch (mDescriptor.type()) { 181 case layers::BufferDescriptor::TYCbCrDescriptor: 182 return mDescriptor.get_YCbCrDescriptor().colorDepth(); 183 default: 184 return gfx::ColorDepth::COLOR_8; 185 } 186 } 187 188 gfx::YUVRangedColorSpace RenderBufferTextureHost::GetYUVColorSpace() const { 189 switch (mDescriptor.type()) { 190 case layers::BufferDescriptor::TYCbCrDescriptor: 191 return gfx::GetYUVRangedColorSpace(mDescriptor.get_YCbCrDescriptor()); 192 default: 193 return gfx::YUVRangedColorSpace::Default; 194 } 195 } 196 197 bool RenderBufferTextureHost::MapPlane(RenderCompositor* aCompositor, 198 uint8_t aChannelIndex, 199 PlaneInfo& aPlaneInfo) { 200 if (!mBuffer) { 201 if (!mDestroyed) { 202 // We hit some problems to get the shmem. 203 gfxCriticalNote << "GetBuffer Failed"; 204 } 205 return false; 206 } 207 208 switch (mDescriptor.type()) { 209 case layers::BufferDescriptor::TYCbCrDescriptor: { 210 const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor(); 211 switch (aChannelIndex) { 212 case 0: 213 aPlaneInfo.mData = 214 layers::ImageDataSerializer::GetYChannel(mBuffer, desc); 215 aPlaneInfo.mStride = desc.yStride(); 216 aPlaneInfo.mSize = desc.display().Size(); 217 break; 218 case 1: 219 aPlaneInfo.mData = 220 layers::ImageDataSerializer::GetCbChannel(mBuffer, desc); 221 aPlaneInfo.mStride = desc.cbCrStride(); 222 aPlaneInfo.mSize = 223 layers::ImageDataSerializer::GetCroppedCbCrSize(desc); 224 break; 225 case 2: 226 aPlaneInfo.mData = 227 layers::ImageDataSerializer::GetCrChannel(mBuffer, desc); 228 aPlaneInfo.mStride = desc.cbCrStride(); 229 aPlaneInfo.mSize = 230 layers::ImageDataSerializer::GetCroppedCbCrSize(desc); 231 break; 232 } 233 break; 234 } 235 default: { 236 const layers::RGBDescriptor& desc = mDescriptor.get_RGBDescriptor(); 237 aPlaneInfo.mData = mBuffer; 238 aPlaneInfo.mStride = layers::ImageDataSerializer::GetRGBStride(desc); 239 aPlaneInfo.mSize = desc.size(); 240 break; 241 } 242 } 243 return true; 244 } 245 246 void RenderBufferTextureHost::UnmapPlanes() {} 247 248 void RenderBufferTextureHost::Destroy() { 249 mBuffer = nullptr; 250 mDestroyed = true; 251 } 252 253 } // namespace wr 254 } // namespace mozilla