1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "MacIOSurfaceTextureHostOGL.h"
7 #include "mozilla/gfx/MacIOSurface.h"
8 #include "GLContextCGL.h"
9
10 namespace mozilla {
11 namespace layers {
12
MacIOSurfaceTextureHostOGL(TextureFlags aFlags,const SurfaceDescriptorMacIOSurface & aDescriptor)13 MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(TextureFlags aFlags,
14 const SurfaceDescriptorMacIOSurface& aDescriptor)
15 : TextureHost(aFlags)
16 {
17 MOZ_COUNT_CTOR(MacIOSurfaceTextureHostOGL);
18 mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(),
19 aDescriptor.scaleFactor(),
20 !aDescriptor.isOpaque());
21 }
22
~MacIOSurfaceTextureHostOGL()23 MacIOSurfaceTextureHostOGL::~MacIOSurfaceTextureHostOGL()
24 {
25 MOZ_COUNT_DTOR(MacIOSurfaceTextureHostOGL);
26 }
27
28 GLTextureSource*
CreateTextureSourceForPlane(size_t aPlane)29 MacIOSurfaceTextureHostOGL::CreateTextureSourceForPlane(size_t aPlane)
30 {
31 MOZ_ASSERT(mSurface);
32
33 GLuint textureHandle;
34 gl::GLContext* gl = mCompositor->gl();
35 gl->fGenTextures(1, &textureHandle);
36 gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textureHandle);
37 gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
38 gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
39
40 mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(gl)->GetCGLContext(), aPlane);
41
42 return new GLTextureSource(mCompositor, textureHandle, LOCAL_GL_TEXTURE_RECTANGLE_ARB,
43 gfx::IntSize(mSurface->GetDevicePixelWidth(aPlane),
44 mSurface->GetDevicePixelHeight(aPlane)),
45 // XXX: This isn't really correct (but isn't used), we should be using the
46 // format of the individual plane, not of the whole buffer.
47 mSurface->GetFormat());
48 }
49
50 bool
Lock()51 MacIOSurfaceTextureHostOGL::Lock()
52 {
53 if (!gl() || !gl()->MakeCurrent() || !mSurface) {
54 return false;
55 }
56
57 if (!mTextureSource) {
58 mTextureSource = CreateTextureSourceForPlane(0);
59
60 RefPtr<TextureSource> prev = mTextureSource;
61 for (size_t i = 1; i < mSurface->GetPlaneCount(); i++) {
62 RefPtr<TextureSource> next = CreateTextureSourceForPlane(i);
63 prev->SetNextSibling(next);
64 prev = next;
65 }
66 }
67 return true;
68 }
69
70 void
SetCompositor(Compositor * aCompositor)71 MacIOSurfaceTextureHostOGL::SetCompositor(Compositor* aCompositor)
72 {
73 CompositorOGL* glCompositor = AssertGLCompositor(aCompositor);
74 if (!glCompositor) {
75 mTextureSource = nullptr;
76 mCompositor = nullptr;
77 return;
78 }
79
80 if (mCompositor != glCompositor) {
81 // Cannot share GL texture identifiers across compositors.
82 mTextureSource = nullptr;
83 }
84 mCompositor = glCompositor;
85 }
86
87 gfx::SurfaceFormat
GetFormat() const88 MacIOSurfaceTextureHostOGL::GetFormat() const {
89 if (!mSurface) {
90 return gfx::SurfaceFormat::UNKNOWN;
91 }
92 return mSurface->GetFormat();
93 }
94
95 gfx::SurfaceFormat
GetReadFormat() const96 MacIOSurfaceTextureHostOGL::GetReadFormat() const {
97 if (!mSurface) {
98 return gfx::SurfaceFormat::UNKNOWN;
99 }
100 return mSurface->GetReadFormat();
101 }
102
103 gfx::IntSize
GetSize() const104 MacIOSurfaceTextureHostOGL::GetSize() const {
105 if (!mSurface) {
106 return gfx::IntSize();
107 }
108 return gfx::IntSize(mSurface->GetDevicePixelWidth(),
109 mSurface->GetDevicePixelHeight());
110 }
111
112 gl::GLContext*
gl() const113 MacIOSurfaceTextureHostOGL::gl() const
114 {
115 return mCompositor ? mCompositor->gl() : nullptr;
116 }
117
MacIOSurfaceTextureSourceOGL(CompositorOGL * aCompositor,MacIOSurface * aSurface)118 MacIOSurfaceTextureSourceOGL::MacIOSurfaceTextureSourceOGL(
119 CompositorOGL* aCompositor,
120 MacIOSurface* aSurface)
121 : mCompositor(aCompositor)
122 , mSurface(aSurface)
123 {
124 MOZ_ASSERT(aCompositor);
125 MOZ_COUNT_CTOR(MacIOSurfaceTextureSourceOGL);
126 }
127
~MacIOSurfaceTextureSourceOGL()128 MacIOSurfaceTextureSourceOGL::~MacIOSurfaceTextureSourceOGL()
129 {
130 MOZ_COUNT_DTOR(MacIOSurfaceTextureSourceOGL);
131 }
132
133 gfx::IntSize
GetSize() const134 MacIOSurfaceTextureSourceOGL::GetSize() const
135 {
136 return gfx::IntSize(mSurface->GetDevicePixelWidth(),
137 mSurface->GetDevicePixelHeight());
138 }
139
140 gfx::SurfaceFormat
GetFormat() const141 MacIOSurfaceTextureSourceOGL::GetFormat() const
142 {
143 return mSurface->HasAlpha() ? gfx::SurfaceFormat::R8G8B8A8
144 : gfx::SurfaceFormat::R8G8B8X8;
145 }
146
147 void
BindTexture(GLenum aTextureUnit,gfx::SamplingFilter aSamplingFilter)148 MacIOSurfaceTextureSourceOGL::BindTexture(GLenum aTextureUnit,
149 gfx::SamplingFilter aSamplingFilter)
150 {
151 gl::GLContext* gl = this->gl();
152 if (!gl || !gl->MakeCurrent()) {
153 NS_WARNING("Trying to bind a texture without a working GLContext");
154 return;
155 }
156 GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit);
157
158 gl->fActiveTexture(aTextureUnit);
159 gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, tex);
160 mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(gl)->GetCGLContext());
161 ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
162 }
163
164 void
SetCompositor(Compositor * aCompositor)165 MacIOSurfaceTextureSourceOGL::SetCompositor(Compositor* aCompositor)
166 {
167 mCompositor = AssertGLCompositor(aCompositor);
168 if (mCompositor && mNextSibling) {
169 mNextSibling->SetCompositor(aCompositor);
170 }
171 }
172
173 gl::GLContext*
gl() const174 MacIOSurfaceTextureSourceOGL::gl() const
175 {
176 return mCompositor ? mCompositor->gl() : nullptr;
177 }
178
179 } // namespace layers
180 } // namespace mozilla
181