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"
17 RenderExternalTextureHost::RenderExternalTextureHost(
18 uint8_t* aBuffer
, const layers::BufferDescriptor
& aDescriptor
)
20 mDescriptor(aDescriptor
),
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
;
32 case layers::BufferDescriptor::TRGBDescriptor
: {
33 const layers::RGBDescriptor
& rgb
= mDescriptor
.get_RGBDescriptor();
35 mFormat
= rgb
.format();
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";
55 bool RenderExternalTextureHost::CreateSurfaces() {
57 mSurfaces
[0] = gfx::Factory::CreateWrappingDataSourceSurface(
59 layers::ImageDataSerializer::GetRGBStride(
60 mDescriptor
.get_RGBDescriptor()),
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";
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() {
108 // We hit some problems to get the shmem.
109 gfxCriticalNote
<< "GetBuffer Failed";
113 if (!CreateSurfaces()) {
122 bool RenderExternalTextureHost::IsReadyForDeletion() {
127 auto& textureSource
= mTextureSources
[0];
129 return textureSource
->Sync(false);
135 wr::WrExternalImage
RenderExternalTextureHost::Lock(uint8_t aChannelIndex
,
136 gl::GLContext
* aGL
) {
137 if (mGL
.get() != aGL
) {
142 if (!mGL
|| !mGL
->MakeCurrent()) {
143 return InvalidToWrExternalImage();
146 if (!InitializeIfNeeded()) {
147 return InvalidToWrExternalImage();
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
];
164 texture
->Update(mSurfaces
[aIndex
]);
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.
183 for (size_t i
= 0; i
< PlaneCount(); ++i
) {
187 mTextureSources
[0]->MaybeFenceTexture();
188 mTextureUpdateNeeded
= false;
191 size_t RenderExternalTextureHost::GetPlaneCount() const { return PlaneCount(); }
193 gfx::SurfaceFormat
RenderExternalTextureHost::GetFormat() const {
197 gfx::ColorDepth
RenderExternalTextureHost::GetColorDepth() const {
198 switch (mDescriptor
.type()) {
199 case layers::BufferDescriptor::TYCbCrDescriptor
:
200 return mDescriptor
.get_YCbCrDescriptor().colorDepth();
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());
211 return gfx::YUVRangedColorSpace::Default
;
215 bool RenderExternalTextureHost::MapPlane(RenderCompositor
* aCompositor
,
216 uint8_t aChannelIndex
,
217 PlaneInfo
& aPlaneInfo
) {
219 // We hit some problems to get the shmem.
220 gfxCriticalNote
<< "GetBuffer Failed";
224 switch (mDescriptor
.type()) {
225 case layers::BufferDescriptor::TYCbCrDescriptor
: {
226 const layers::YCbCrDescriptor
& desc
= mDescriptor
.get_YCbCrDescriptor();
227 switch (aChannelIndex
) {
230 layers::ImageDataSerializer::GetYChannel(mBuffer
, desc
);
231 aPlaneInfo
.mStride
= desc
.yStride();
232 aPlaneInfo
.mSize
= desc
.display().Size();
236 layers::ImageDataSerializer::GetCbChannel(mBuffer
, desc
);
237 aPlaneInfo
.mStride
= desc
.cbCrStride();
239 layers::ImageDataSerializer::GetCroppedCbCrSize(desc
);
243 layers::ImageDataSerializer::GetCrChannel(mBuffer
, desc
);
244 aPlaneInfo
.mStride
= desc
.cbCrStride();
246 layers::ImageDataSerializer::GetCroppedCbCrSize(desc
);
252 const layers::RGBDescriptor
& desc
= mDescriptor
.get_RGBDescriptor();
253 aPlaneInfo
.mData
= mBuffer
;
254 aPlaneInfo
.mStride
= layers::ImageDataSerializer::GetRGBStride(desc
);
255 aPlaneInfo
.mSize
= desc
.size();
262 void RenderExternalTextureHost::UnmapPlanes() {}
265 } // namespace mozilla