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