no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / gfx / webrender_bindings / RenderExternalTextureHost.cpp
blobdb8107ff0a380c45407f8966636a7735c7c85494
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/. */
7 #include "RenderExternalTextureHost.h"
9 #include "mozilla/gfx/Logging.h"
10 #include "mozilla/layers/ImageDataSerializer.h"
12 #include "GLContext.h"
14 namespace mozilla {
15 namespace wr {
17 RenderExternalTextureHost::RenderExternalTextureHost(
18 uint8_t* aBuffer, const layers::BufferDescriptor& aDescriptor)
19 : mBuffer(aBuffer),
20 mDescriptor(aDescriptor),
21 mInitialized(false),
22 mTextureUpdateNeeded(true) {
23 MOZ_COUNT_CTOR_INHERITED(RenderExternalTextureHost, RenderTextureHost);
25 switch (mDescriptor.type()) {
26 case layers::BufferDescriptor::TYCbCrDescriptor: {
27 const layers::YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor();
28 mSize = ycbcr.display().Size();
29 mFormat = gfx::SurfaceFormat::YUV;
30 break;
32 case layers::BufferDescriptor::TRGBDescriptor: {
33 const layers::RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
34 mSize = rgb.size();
35 mFormat = rgb.format();
36 break;
38 default:
39 gfxCriticalError() << "Bad buffer host descriptor "
40 << (int)mDescriptor.type();
41 MOZ_CRASH("GFX: Bad descriptor");
45 RenderExternalTextureHost::~RenderExternalTextureHost() {
46 MOZ_COUNT_DTOR_INHERITED(RenderExternalTextureHost, RenderTextureHost);
48 if (NS_WARN_IF(!IsReadyForDeletion())) {
49 gfxCriticalNote << "RenderExternalTextureHost sync failed";
52 DeleteTextures();
55 bool RenderExternalTextureHost::CreateSurfaces() {
56 if (!IsYUV()) {
57 mSurfaces[0] = gfx::Factory::CreateWrappingDataSourceSurface(
58 GetBuffer(),
59 layers::ImageDataSerializer::GetRGBStride(
60 mDescriptor.get_RGBDescriptor()),
61 mSize, mFormat);
62 } else {
63 const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
64 const gfx::SurfaceFormat surfaceFormat =
65 SurfaceFormatForColorDepth(desc.colorDepth());
66 auto cbcrSize = layers::ImageDataSerializer::GetCroppedCbCrSize(desc);
68 mSurfaces[0] = gfx::Factory::CreateWrappingDataSourceSurface(
69 layers::ImageDataSerializer::GetYChannel(GetBuffer(), desc),
70 desc.yStride(), desc.display().Size(), surfaceFormat);
71 mSurfaces[1] = gfx::Factory::CreateWrappingDataSourceSurface(
72 layers::ImageDataSerializer::GetCbChannel(GetBuffer(), desc),
73 desc.cbCrStride(), cbcrSize, surfaceFormat);
74 mSurfaces[2] = gfx::Factory::CreateWrappingDataSourceSurface(
75 layers::ImageDataSerializer::GetCrChannel(GetBuffer(), desc),
76 desc.cbCrStride(), cbcrSize, surfaceFormat);
79 for (size_t i = 0; i < PlaneCount(); ++i) {
80 if (NS_WARN_IF(!mSurfaces[i])) {
81 gfxCriticalNote << "Surface is null";
82 return false;
86 return true;
89 void RenderExternalTextureHost::DeleteSurfaces() {
90 for (size_t i = 0; i < PlaneCount(); ++i) {
91 mSurfaces[i] = nullptr;
95 void RenderExternalTextureHost::DeleteTextures() {
96 for (size_t i = 0; i < PlaneCount(); ++i) {
97 mTextureSources[i] = nullptr;
98 mImages[i] = InvalidToWrExternalImage();
102 bool RenderExternalTextureHost::InitializeIfNeeded() {
103 if (mInitialized) {
104 return true;
107 if (!GetBuffer()) {
108 // We hit some problems to get the shmem.
109 gfxCriticalNote << "GetBuffer Failed";
110 return false;
113 if (!CreateSurfaces()) {
114 DeleteSurfaces();
115 return false;
118 mInitialized = true;
119 return mInitialized;
122 bool RenderExternalTextureHost::IsReadyForDeletion() {
123 if (!mInitialized) {
124 return true;
127 auto& textureSource = mTextureSources[0];
128 if (textureSource) {
129 return textureSource->Sync(false);
132 return true;
135 wr::WrExternalImage RenderExternalTextureHost::Lock(uint8_t aChannelIndex,
136 gl::GLContext* aGL) {
137 if (mGL.get() != aGL) {
138 mGL = aGL;
139 mGL->MakeCurrent();
142 if (!mGL || !mGL->MakeCurrent()) {
143 return InvalidToWrExternalImage();
146 if (!InitializeIfNeeded()) {
147 return InvalidToWrExternalImage();
150 UpdateTextures();
151 return mImages[aChannelIndex];
154 void RenderExternalTextureHost::PrepareForUse() { mTextureUpdateNeeded = true; }
156 void RenderExternalTextureHost::Unlock() {}
158 void RenderExternalTextureHost::UpdateTexture(size_t aIndex) {
159 MOZ_ASSERT(mSurfaces[aIndex]);
161 auto& texture = mTextureSources[aIndex];
163 if (texture) {
164 texture->Update(mSurfaces[aIndex]);
165 } else {
166 texture = new layers::DirectMapTextureSource(mGL, mSurfaces[aIndex]);
168 const GLuint handle = texture->GetTextureHandle();
169 const auto uvs = GetUvCoords(texture->GetSize());
170 mImages[aIndex] = NativeTextureToWrExternalImage(
171 handle, uvs.first.x, uvs.first.y, uvs.second.x, uvs.second.y);
174 MOZ_ASSERT(mGL->GetError() == LOCAL_GL_NO_ERROR);
177 void RenderExternalTextureHost::UpdateTextures() {
178 if (!mTextureUpdateNeeded) {
179 // Nothing to do here.
180 return;
183 for (size_t i = 0; i < PlaneCount(); ++i) {
184 UpdateTexture(i);
187 mTextureSources[0]->MaybeFenceTexture();
188 mTextureUpdateNeeded = false;
191 size_t RenderExternalTextureHost::GetPlaneCount() const { return PlaneCount(); }
193 gfx::SurfaceFormat RenderExternalTextureHost::GetFormat() const {
194 return mFormat;
197 gfx::ColorDepth RenderExternalTextureHost::GetColorDepth() const {
198 switch (mDescriptor.type()) {
199 case layers::BufferDescriptor::TYCbCrDescriptor:
200 return mDescriptor.get_YCbCrDescriptor().colorDepth();
201 default:
202 return gfx::ColorDepth::COLOR_8;
206 gfx::YUVRangedColorSpace RenderExternalTextureHost::GetYUVColorSpace() const {
207 switch (mDescriptor.type()) {
208 case layers::BufferDescriptor::TYCbCrDescriptor:
209 return gfx::GetYUVRangedColorSpace(mDescriptor.get_YCbCrDescriptor());
210 default:
211 return gfx::YUVRangedColorSpace::Default;
215 bool RenderExternalTextureHost::MapPlane(RenderCompositor* aCompositor,
216 uint8_t aChannelIndex,
217 PlaneInfo& aPlaneInfo) {
218 if (!mBuffer) {
219 // We hit some problems to get the shmem.
220 gfxCriticalNote << "GetBuffer Failed";
221 return false;
224 switch (mDescriptor.type()) {
225 case layers::BufferDescriptor::TYCbCrDescriptor: {
226 const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
227 switch (aChannelIndex) {
228 case 0:
229 aPlaneInfo.mData =
230 layers::ImageDataSerializer::GetYChannel(mBuffer, desc);
231 aPlaneInfo.mStride = desc.yStride();
232 aPlaneInfo.mSize = desc.display().Size();
233 break;
234 case 1:
235 aPlaneInfo.mData =
236 layers::ImageDataSerializer::GetCbChannel(mBuffer, desc);
237 aPlaneInfo.mStride = desc.cbCrStride();
238 aPlaneInfo.mSize =
239 layers::ImageDataSerializer::GetCroppedCbCrSize(desc);
240 break;
241 case 2:
242 aPlaneInfo.mData =
243 layers::ImageDataSerializer::GetCrChannel(mBuffer, desc);
244 aPlaneInfo.mStride = desc.cbCrStride();
245 aPlaneInfo.mSize =
246 layers::ImageDataSerializer::GetCroppedCbCrSize(desc);
247 break;
249 break;
251 default: {
252 const layers::RGBDescriptor& desc = mDescriptor.get_RGBDescriptor();
253 aPlaneInfo.mData = mBuffer;
254 aPlaneInfo.mStride = layers::ImageDataSerializer::GetRGBStride(desc);
255 aPlaneInfo.mSize = desc.size();
256 break;
259 return true;
262 void RenderExternalTextureHost::UnmapPlanes() {}
264 } // namespace wr
265 } // namespace mozilla