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"
9 #include "GLContextCGL.h"
10 #include "mozilla/gfx/Logging.h"
11 #include "ScopedGLHelpers.h"
16 static CGLError
CreateTextureForPlane(uint8_t aPlaneID
, gl::GLContext
* aGL
,
17 MacIOSurface
* aSurface
,
19 MOZ_ASSERT(aGL
&& aSurface
&& aTexture
);
21 aGL
->fGenTextures(1, aTexture
);
22 ActivateBindAndTexParameteri(aGL
, LOCAL_GL_TEXTURE0
,
23 LOCAL_GL_TEXTURE_RECTANGLE_ARB
, *aTexture
);
24 aGL
->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB
, LOCAL_GL_TEXTURE_WRAP_T
,
25 LOCAL_GL_CLAMP_TO_EDGE
);
26 aGL
->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB
, LOCAL_GL_TEXTURE_WRAP_S
,
27 LOCAL_GL_CLAMP_TO_EDGE
);
29 CGLError result
= kCGLNoError
;
30 gfx::SurfaceFormat readFormat
= gfx::SurfaceFormat::UNKNOWN
;
31 result
= aSurface
->CGLTexImageIOSurface2D(
32 aGL
, gl::GLContextCGL::Cast(aGL
)->GetCGLContext(), aPlaneID
, &readFormat
);
33 // If this is a yuv format, the Webrender only supports YUV422 interleaving
35 MOZ_ASSERT(aSurface
->GetFormat() != gfx::SurfaceFormat::YUV422
||
36 readFormat
== gfx::SurfaceFormat::YUV422
);
41 RenderMacIOSurfaceTextureHost::RenderMacIOSurfaceTextureHost(
42 MacIOSurface
* aSurface
)
43 : mSurface(aSurface
), mTextureHandles
{0, 0, 0} {
44 MOZ_COUNT_CTOR_INHERITED(RenderMacIOSurfaceTextureHost
, RenderTextureHost
);
47 RenderMacIOSurfaceTextureHost::~RenderMacIOSurfaceTextureHost() {
48 MOZ_COUNT_DTOR_INHERITED(RenderMacIOSurfaceTextureHost
, RenderTextureHost
);
49 DeleteTextureHandle();
52 GLuint
RenderMacIOSurfaceTextureHost::GetGLHandle(uint8_t aChannelIndex
) const {
54 MOZ_ASSERT((mSurface
->GetPlaneCount() == 0)
55 ? (aChannelIndex
== mSurface
->GetPlaneCount())
56 : (aChannelIndex
< mSurface
->GetPlaneCount()));
57 return mTextureHandles
[aChannelIndex
];
60 gfx::IntSize
RenderMacIOSurfaceTextureHost::GetSize(
61 uint8_t aChannelIndex
) const {
63 MOZ_ASSERT((mSurface
->GetPlaneCount() == 0)
64 ? (aChannelIndex
== mSurface
->GetPlaneCount())
65 : (aChannelIndex
< mSurface
->GetPlaneCount()));
68 return gfx::IntSize();
70 return gfx::IntSize(mSurface
->GetDevicePixelWidth(aChannelIndex
),
71 mSurface
->GetDevicePixelHeight(aChannelIndex
));
74 size_t RenderMacIOSurfaceTextureHost::Bytes() {
75 return mSurface
->GetAllocSize();
78 wr::WrExternalImage
RenderMacIOSurfaceTextureHost::Lock(uint8_t aChannelIndex
,
80 if (mGL
.get() != aGL
) {
81 // release the texture handle in the previous gl context
82 DeleteTextureHandle();
87 if (!mSurface
|| !mGL
|| !mGL
->MakeCurrent()) {
88 return InvalidToWrExternalImage();
91 if (!mTextureHandles
[0]) {
92 MOZ_ASSERT(gl::GLContextCGL::Cast(mGL
.get())->GetCGLContext());
94 // The result of GetPlaneCount() is 0 for single plane format, but it will
95 // be 2 if the format has 2 planar data.
96 CreateTextureForPlane(0, mGL
, mSurface
, &(mTextureHandles
[0]));
97 for (size_t i
= 1; i
< mSurface
->GetPlaneCount(); ++i
) {
98 CreateTextureForPlane(i
, mGL
, mSurface
, &(mTextureHandles
[i
]));
102 const auto uvs
= GetUvCoords(GetSize(aChannelIndex
));
103 return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex
), uvs
.first
.x
,
104 uvs
.first
.y
, uvs
.second
.x
,
108 void RenderMacIOSurfaceTextureHost::Unlock() {}
110 void RenderMacIOSurfaceTextureHost::DeleteTextureHandle() {
111 if (mTextureHandles
[0] != 0 && mGL
&& mGL
->MakeCurrent()) {
112 // Calling glDeleteTextures on 0 isn't an error. So, just make them a single
114 mGL
->fDeleteTextures(3, mTextureHandles
);
115 for (size_t i
= 0; i
< 3; ++i
) {
116 mTextureHandles
[i
] = 0;
121 size_t RenderMacIOSurfaceTextureHost::GetPlaneCount() const {
122 size_t planeCount
= mSurface
->GetPlaneCount();
123 return planeCount
> 0 ? planeCount
: 1;
126 gfx::SurfaceFormat
RenderMacIOSurfaceTextureHost::GetFormat() const {
127 return mSurface
->GetFormat();
130 gfx::ColorDepth
RenderMacIOSurfaceTextureHost::GetColorDepth() const {
131 return mSurface
->GetColorDepth();
134 gfx::YUVRangedColorSpace
RenderMacIOSurfaceTextureHost::GetYUVColorSpace()
136 return ToYUVRangedColorSpace(mSurface
->GetYUVColorSpace(),
137 mSurface
->GetColorRange());
140 bool RenderMacIOSurfaceTextureHost::MapPlane(RenderCompositor
* aCompositor
,
141 uint8_t aChannelIndex
,
142 PlaneInfo
& aPlaneInfo
) {
143 if (!aChannelIndex
) {
146 aPlaneInfo
.mData
= mSurface
->GetBaseAddressOfPlane(aChannelIndex
);
147 aPlaneInfo
.mStride
= mSurface
->GetBytesPerRow(aChannelIndex
);
149 gfx::IntSize(mSurface
->GetDevicePixelWidth(aChannelIndex
),
150 mSurface
->GetDevicePixelHeight(aChannelIndex
));
154 void RenderMacIOSurfaceTextureHost::UnmapPlanes() { mSurface
->Unlock(); }
157 } // namespace mozilla