gfx/gl/SharedSurfaceIO.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:a84a1930ec5d
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 "SharedSurfaceIO.h"
7 #include "GLContextCGL.h"
8 #include "mozilla/gfx/MacIOSurface.h"
9 #include "mozilla/DebugOnly.h"
10 #include "ScopedGLHelpers.h"
11
12 namespace mozilla {
13 namespace gl {
14
15 using namespace gfx;
16
17 /* static */ SharedSurface_IOSurface*
18 SharedSurface_IOSurface::Create(MacIOSurface* surface, GLContext *gl, bool hasAlpha)
19 {
20 MOZ_ASSERT(surface);
21 MOZ_ASSERT(gl);
22
23 gfx::IntSize size(surface->GetWidth(), surface->GetHeight());
24 return new SharedSurface_IOSurface(surface, gl, size, hasAlpha);
25 }
26
27 void
28 SharedSurface_IOSurface::Fence()
29 {
30 mGL->MakeCurrent();
31 mGL->fFlush();
32 }
33
34 bool
35 SharedSurface_IOSurface::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
36 GLenum format, GLenum type, GLvoid *pixels)
37 {
38 // Calling glReadPixels when an IOSurface is bound to the current framebuffer
39 // can cause corruption in following glReadPixel calls (even if they aren't
40 // reading from an IOSurface).
41 // We workaround this by copying to a temporary texture, and doing the readback
42 // from that.
43 MOZ_ASSERT(mGL->IsCurrent());
44
45
46 ScopedTexture destTex(mGL);
47 {
48 ScopedFramebufferForTexture srcFB(mGL, ProdTexture(), ProdTextureTarget());
49
50 ScopedBindFramebuffer bindFB(mGL, srcFB.FB());
51 ScopedBindTexture bindTex(mGL, destTex.Texture());
52 mGL->fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0,
53 HasAlpha() ? LOCAL_GL_RGBA : LOCAL_GL_RGB,
54 x, y,
55 width, height, 0);
56 }
57
58 ScopedFramebufferForTexture destFB(mGL, destTex.Texture());
59
60 ScopedBindFramebuffer bindFB(mGL, destFB.FB());
61 mGL->fReadPixels(0, 0, width, height, format, type, pixels);
62 return true;
63 }
64
65 static void
66 BackTextureWithIOSurf(GLContext* gl, GLuint tex, MacIOSurface* ioSurf)
67 {
68 MOZ_ASSERT(gl->IsCurrent());
69
70 ScopedBindTexture texture(gl, tex, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
71
72 gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
73 LOCAL_GL_TEXTURE_MIN_FILTER,
74 LOCAL_GL_LINEAR);
75 gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
76 LOCAL_GL_TEXTURE_MAG_FILTER,
77 LOCAL_GL_LINEAR);
78 gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
79 LOCAL_GL_TEXTURE_WRAP_S,
80 LOCAL_GL_CLAMP_TO_EDGE);
81 gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
82 LOCAL_GL_TEXTURE_WRAP_T,
83 LOCAL_GL_CLAMP_TO_EDGE);
84
85 CGLContextObj cgl = GLContextCGL::Cast(gl)->GetCGLContext();
86 MOZ_ASSERT(cgl);
87
88 ioSurf->CGLTexImageIOSurface2D(cgl);
89 }
90
91 SharedSurface_IOSurface::SharedSurface_IOSurface(MacIOSurface* surface,
92 GLContext* gl,
93 const gfx::IntSize& size,
94 bool hasAlpha)
95 : SharedSurface_GL(SharedSurfaceType::IOSurface, AttachmentType::GLTexture, gl, size, hasAlpha)
96 , mSurface(surface)
97 , mCurConsGL(nullptr)
98 , mConsTex(0)
99 {
100 gl->MakeCurrent();
101 mProdTex = 0;
102 gl->fGenTextures(1, &mProdTex);
103 BackTextureWithIOSurf(gl, mProdTex, surface);
104 }
105
106 GLuint
107 SharedSurface_IOSurface::ConsTexture(GLContext* consGL)
108 {
109 if (!mCurConsGL) {
110 mCurConsGL = consGL;
111 }
112 MOZ_ASSERT(consGL == mCurConsGL);
113
114 if (!mConsTex) {
115 consGL->MakeCurrent();
116 mConsTex = 0;
117 consGL->fGenTextures(1, &mConsTex);
118 BackTextureWithIOSurf(consGL, mConsTex, mSurface);
119 }
120
121 return mConsTex;
122 }
123
124 SharedSurface_IOSurface::~SharedSurface_IOSurface()
125 {
126 if (mProdTex) {
127 DebugOnly<bool> success = mGL->MakeCurrent();
128 MOZ_ASSERT(success);
129 mGL->fDeleteTextures(1, &mProdTex);
130 mGL->fDeleteTextures(1, &mConsTex); // This will work if we're shared.
131 }
132 }
133
134 SharedSurface*
135 SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size)
136 {
137 bool hasAlpha = mReadCaps.alpha;
138 RefPtr<MacIOSurface> surf =
139 MacIOSurface::CreateIOSurface(size.width, size.height, 1.0, hasAlpha);
140
141 if (!surf) {
142 NS_WARNING("Failed to create MacIOSurface.");
143 return nullptr;
144 }
145
146 return SharedSurface_IOSurface::Create(surf, mGL, hasAlpha);
147 }
148
149 }
150 }

mercurial