Line data Source code
1 : /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
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 "SharedSurfaceGL.h"
7 :
8 : #include "GLBlitHelper.h"
9 : #include "GLContext.h"
10 : #include "GLReadTexImageHelper.h"
11 : #include "mozilla/gfx/2D.h"
12 : #include "ScopedGLHelpers.h"
13 :
14 : namespace mozilla {
15 : namespace gl {
16 :
17 : using gfx::IntSize;
18 : using gfx::SurfaceFormat;
19 :
20 : /*static*/ UniquePtr<SharedSurface_Basic>
21 0 : SharedSurface_Basic::Create(GLContext* gl,
22 : const GLFormats& formats,
23 : const IntSize& size,
24 : bool hasAlpha)
25 : {
26 0 : UniquePtr<SharedSurface_Basic> ret;
27 0 : gl->MakeCurrent();
28 :
29 0 : GLContext::LocalErrorScope localError(*gl);
30 0 : GLuint tex = CreateTextureForOffscreen(gl, formats, size);
31 :
32 0 : GLenum err = localError.GetError();
33 0 : MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
34 0 : if (err) {
35 0 : gl->fDeleteTextures(1, &tex);
36 0 : return Move(ret);
37 : }
38 :
39 0 : bool ownsTex = true;
40 0 : ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, tex, ownsTex) );
41 0 : return Move(ret);
42 : }
43 :
44 :
45 : /*static*/ UniquePtr<SharedSurface_Basic>
46 0 : SharedSurface_Basic::Wrap(GLContext* gl,
47 : const IntSize& size,
48 : bool hasAlpha,
49 : GLuint tex)
50 : {
51 0 : bool ownsTex = false;
52 : UniquePtr<SharedSurface_Basic> ret( new SharedSurface_Basic(gl, size, hasAlpha, tex,
53 0 : ownsTex) );
54 0 : return Move(ret);
55 : }
56 :
57 0 : SharedSurface_Basic::SharedSurface_Basic(GLContext* gl,
58 : const IntSize& size,
59 : bool hasAlpha,
60 : GLuint tex,
61 0 : bool ownsTex)
62 : : SharedSurface(SharedSurfaceType::Basic,
63 : AttachmentType::GLTexture,
64 : gl,
65 : size,
66 : hasAlpha,
67 : true)
68 : , mTex(tex)
69 : , mOwnsTex(ownsTex)
70 0 : , mFB(0)
71 : {
72 0 : mGL->MakeCurrent();
73 0 : mGL->fGenFramebuffers(1, &mFB);
74 :
75 0 : ScopedBindFramebuffer autoFB(mGL, mFB);
76 0 : mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
77 : LOCAL_GL_COLOR_ATTACHMENT0,
78 : LOCAL_GL_TEXTURE_2D,
79 0 : mTex,
80 0 : 0);
81 :
82 0 : DebugOnly<GLenum> status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
83 0 : MOZ_ASSERT(status == LOCAL_GL_FRAMEBUFFER_COMPLETE);
84 0 : }
85 :
86 0 : SharedSurface_Basic::~SharedSurface_Basic()
87 : {
88 0 : if (!mGL || !mGL->MakeCurrent())
89 0 : return;
90 :
91 0 : if (mFB)
92 0 : mGL->fDeleteFramebuffers(1, &mFB);
93 :
94 0 : if (mOwnsTex)
95 0 : mGL->fDeleteTextures(1, &mTex);
96 0 : }
97 :
98 :
99 : ////////////////////////////////////////////////////////////////////////
100 :
101 0 : SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
102 0 : const layers::TextureFlags& flags)
103 0 : : SurfaceFactory(SharedSurfaceType::Basic, gl, caps, nullptr, flags)
104 0 : { }
105 :
106 :
107 : ////////////////////////////////////////////////////////////////////////
108 : // SharedSurface_GLTexture
109 :
110 : /*static*/ UniquePtr<SharedSurface_GLTexture>
111 0 : SharedSurface_GLTexture::Create(GLContext* prodGL,
112 : const GLFormats& formats,
113 : const IntSize& size,
114 : bool hasAlpha)
115 : {
116 0 : MOZ_ASSERT(prodGL);
117 :
118 0 : prodGL->MakeCurrent();
119 :
120 0 : UniquePtr<SharedSurface_GLTexture> ret;
121 0 : GLContext::LocalErrorScope localError(*prodGL);
122 :
123 0 : GLuint tex = CreateTextureForOffscreen(prodGL, formats, size);
124 :
125 0 : GLenum err = localError.GetError();
126 0 : MOZ_ASSERT_IF(err, err == LOCAL_GL_OUT_OF_MEMORY);
127 0 : if (err) {
128 0 : prodGL->fDeleteTextures(1, &tex);
129 0 : return Move(ret);
130 : }
131 :
132 : ret.reset(new SharedSurface_GLTexture(prodGL, size,
133 0 : hasAlpha, tex));
134 0 : return Move(ret);
135 : }
136 :
137 0 : SharedSurface_GLTexture::~SharedSurface_GLTexture()
138 : {
139 0 : if (!mGL->MakeCurrent())
140 0 : return;
141 :
142 0 : if (mTex) {
143 0 : mGL->fDeleteTextures(1, &mTex);
144 : }
145 :
146 0 : if (mSync) {
147 0 : mGL->fDeleteSync(mSync);
148 : }
149 0 : }
150 :
151 : void
152 0 : SharedSurface_GLTexture::ProducerReleaseImpl()
153 : {
154 0 : mGL->MakeCurrent();
155 :
156 0 : if (mGL->IsSupported(GLFeature::sync)) {
157 0 : if (mSync) {
158 0 : mGL->fDeleteSync(mSync);
159 0 : mSync = 0;
160 : }
161 :
162 0 : mSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
163 0 : if (mSync) {
164 0 : mGL->fFlush();
165 0 : return;
166 : }
167 : }
168 0 : MOZ_ASSERT(!mSync);
169 :
170 0 : mGL->fFinish();
171 : }
172 :
173 : bool
174 0 : SharedSurface_GLTexture::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
175 : {
176 0 : *out_descriptor = layers::SurfaceDescriptorSharedGLTexture(ProdTexture(),
177 0 : ProdTextureTarget(),
178 0 : (uintptr_t)mSync,
179 : mSize,
180 0 : mHasAlpha);
181 :
182 : // Transfer ownership of the fence to the host
183 0 : mSync = nullptr;
184 0 : return true;
185 : }
186 :
187 :
188 : } // namespace gl
189 :
190 : } /* namespace mozilla */
|