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 "RenderMacIOSurfaceTextureHost.h"
10 # include "GLContextCGL.h"
12 # include "GLContextEAGL.h"
15 #include "mozilla/gfx/Logging.h"
16 #include "mozilla/layers/GpuFence.h"
17 #include "ScopedGLHelpers.h"
22 static bool CreateTextureForPlane(uint8_t aPlaneID
, gl::GLContext
* aGL
,
23 MacIOSurface
* aSurface
, GLuint
* aTexture
) {
24 MOZ_ASSERT(aGL
&& aSurface
&& aTexture
);
26 aGL
->fGenTextures(1, aTexture
);
27 ActivateBindAndTexParameteri(aGL
, LOCAL_GL_TEXTURE0
,
28 LOCAL_GL_TEXTURE_RECTANGLE_ARB
, *aTexture
);
29 aGL
->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB
, LOCAL_GL_TEXTURE_WRAP_T
,
30 LOCAL_GL_CLAMP_TO_EDGE
);
31 aGL
->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB
, LOCAL_GL_TEXTURE_WRAP_S
,
32 LOCAL_GL_CLAMP_TO_EDGE
);
34 gfx::SurfaceFormat readFormat
= gfx::SurfaceFormat::UNKNOWN
;
35 bool result
= aSurface
->BindTexImage(aGL
, aPlaneID
, &readFormat
);
36 // If this is a yuv format, the Webrender only supports YUY2 interleaving
38 MOZ_ASSERT(aSurface
->GetFormat() != gfx::SurfaceFormat::YUY2
||
39 readFormat
== gfx::SurfaceFormat::YUY2
);
44 RenderMacIOSurfaceTextureHost::RenderMacIOSurfaceTextureHost(
45 MacIOSurface
* aSurface
, layers::GpuFence
* aGpuFence
)
46 : mSurface(aSurface
), mGpuFence(aGpuFence
), mTextureHandles
{0, 0, 0} {
47 MOZ_COUNT_CTOR_INHERITED(RenderMacIOSurfaceTextureHost
, RenderTextureHost
);
50 RenderMacIOSurfaceTextureHost::~RenderMacIOSurfaceTextureHost() {
51 MOZ_COUNT_DTOR_INHERITED(RenderMacIOSurfaceTextureHost
, RenderTextureHost
);
52 DeleteTextureHandle();
55 GLuint
RenderMacIOSurfaceTextureHost::GetGLHandle(uint8_t aChannelIndex
) const {
57 MOZ_ASSERT((mSurface
->GetPlaneCount() == 0)
58 ? (aChannelIndex
== mSurface
->GetPlaneCount())
59 : (aChannelIndex
< mSurface
->GetPlaneCount()));
60 return mTextureHandles
[aChannelIndex
];
63 gfx::IntSize
RenderMacIOSurfaceTextureHost::GetSize(
64 uint8_t aChannelIndex
) const {
66 MOZ_ASSERT((mSurface
->GetPlaneCount() == 0)
67 ? (aChannelIndex
== mSurface
->GetPlaneCount())
68 : (aChannelIndex
< mSurface
->GetPlaneCount()));
71 return gfx::IntSize();
73 return gfx::IntSize(mSurface
->GetDevicePixelWidth(aChannelIndex
),
74 mSurface
->GetDevicePixelHeight(aChannelIndex
));
77 size_t RenderMacIOSurfaceTextureHost::Bytes() {
78 return mSurface
->GetAllocSize();
81 wr::WrExternalImage
RenderMacIOSurfaceTextureHost::Lock(uint8_t aChannelIndex
,
83 if (mGL
.get() != aGL
) {
84 // release the texture handle in the previous gl context
85 DeleteTextureHandle();
90 if (!mSurface
|| !mGL
|| !mGL
->MakeCurrent()) {
91 return InvalidToWrExternalImage();
94 if (!mTextureHandles
[0]) {
96 MOZ_ASSERT(gl::GLContextCGL::Cast(mGL
.get())->GetCGLContext());
98 MOZ_ASSERT(gl::GLContextEAGL::Cast(mGL
.get())->GetEAGLContext());
101 // The result of GetPlaneCount() is 0 for single plane format, but it will
102 // be 2 if the format has 2 planar data.
103 CreateTextureForPlane(0, mGL
, mSurface
, &(mTextureHandles
[0]));
104 for (size_t i
= 1; i
< mSurface
->GetPlaneCount(); ++i
) {
105 CreateTextureForPlane(i
, mGL
, mSurface
, &(mTextureHandles
[i
]));
109 const auto size
= GetSize(aChannelIndex
);
110 return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex
), 0.0, 0.0,
111 static_cast<float>(size
.width
),
112 static_cast<float>(size
.height
));
115 void RenderMacIOSurfaceTextureHost::Unlock() {}
117 void RenderMacIOSurfaceTextureHost::DeleteTextureHandle() {
118 if (mTextureHandles
[0] != 0 && mGL
&& mGL
->MakeCurrent()) {
119 // Calling glDeleteTextures on 0 isn't an error. So, just make them a single
121 mGL
->fDeleteTextures(3, mTextureHandles
);
122 for (size_t i
= 0; i
< 3; ++i
) {
123 mTextureHandles
[i
] = 0;
128 size_t RenderMacIOSurfaceTextureHost::GetPlaneCount() const {
129 size_t planeCount
= mSurface
->GetPlaneCount();
130 return planeCount
> 0 ? planeCount
: 1;
133 gfx::SurfaceFormat
RenderMacIOSurfaceTextureHost::GetFormat() const {
134 return mSurface
->GetFormat();
137 gfx::ColorDepth
RenderMacIOSurfaceTextureHost::GetColorDepth() const {
138 return mSurface
->GetColorDepth();
141 gfx::YUVRangedColorSpace
RenderMacIOSurfaceTextureHost::GetYUVColorSpace()
143 return ToYUVRangedColorSpace(mSurface
->GetYUVColorSpace(),
144 mSurface
->GetColorRange());
147 bool RenderMacIOSurfaceTextureHost::MapPlane(RenderCompositor
* aCompositor
,
148 uint8_t aChannelIndex
,
149 PlaneInfo
& aPlaneInfo
) {
150 if (!aChannelIndex
) {
151 if (NS_WARN_IF(!mSurface
->Lock())) {
155 aPlaneInfo
.mData
= mSurface
->GetBaseAddressOfPlane(aChannelIndex
);
156 aPlaneInfo
.mStride
= mSurface
->GetBytesPerRow(aChannelIndex
);
158 gfx::IntSize(mSurface
->GetDevicePixelWidth(aChannelIndex
),
159 mSurface
->GetDevicePixelHeight(aChannelIndex
));
163 void RenderMacIOSurfaceTextureHost::UnmapPlanes() { mSurface
->Unlock(); }
166 } // namespace mozilla