gfx/layers/opengl/CompositorOGL.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:317c2e0f0cb9
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 #ifndef MOZILLA_GFX_COMPOSITOROGL_H
7 #define MOZILLA_GFX_COMPOSITOROGL_H
8
9 #include "gfx2DGlue.h"
10 #include "GLContextTypes.h" // for GLContext, etc
11 #include "GLDefs.h" // for GLuint, LOCAL_GL_TEXTURE_2D, etc
12 #include "OGLShaderProgram.h" // for ShaderProgramOGL, etc
13 #include "Units.h" // for ScreenPoint
14 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
15 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE, MOZ_FINAL
16 #include "mozilla/RefPtr.h" // for TemporaryRef, RefPtr
17 #include "mozilla/gfx/2D.h" // for DrawTarget
18 #include "mozilla/gfx/BaseSize.h" // for BaseSize
19 #include "mozilla/gfx/Point.h" // for IntSize, Point
20 #include "mozilla/gfx/Rect.h" // for Rect, IntRect
21 #include "mozilla/gfx/Types.h" // for Float, SurfaceFormat, etc
22 #include "mozilla/layers/Compositor.h" // for SurfaceInitMode, Compositor, etc
23 #include "mozilla/layers/CompositorTypes.h" // for MaskType::NumMaskTypes, etc
24 #include "mozilla/layers/LayersTypes.h"
25 #include "nsAutoPtr.h" // for nsRefPtr, nsAutoPtr
26 #include "nsCOMPtr.h" // for already_AddRefed
27 #include "nsDebug.h" // for NS_ASSERTION, NS_WARNING
28 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
29 #include "nsSize.h" // for nsIntSize
30 #include "nsTArray.h" // for nsAutoTArray, nsTArray, etc
31 #include "nsThreadUtils.h" // for nsRunnable
32 #include "nsXULAppAPI.h" // for XRE_GetProcessType
33 #include "nscore.h" // for NS_IMETHOD
34 #include "VBOArena.h" // for gl::VBOArena
35 #ifdef MOZ_WIDGET_GONK
36 #include <ui/GraphicBuffer.h>
37 #endif
38
39 class gfx3DMatrix;
40 class nsIWidget;
41
42 namespace mozilla {
43 class TimeStamp;
44
45 namespace gfx {
46 class Matrix4x4;
47 }
48
49 namespace layers {
50
51 class CompositingRenderTarget;
52 class CompositingRenderTargetOGL;
53 class DataTextureSource;
54 class GLManagerCompositor;
55 class TextureSource;
56 struct Effect;
57 struct EffectChain;
58
59 /**
60 * Interface for pools of temporary gl textures for the compositor.
61 * The textures are fully owned by the pool, so the latter is responsible
62 * calling fDeleteTextures accordingly.
63 * Users of GetTexture receive a texture that is only valid for the duration
64 * of the current frame.
65 * This is primarily intended for direct texturing APIs that need to attach
66 * shared objects (such as an EGLImage) to a gl texture.
67 */
68 class CompositorTexturePoolOGL
69 {
70 protected:
71 virtual ~CompositorTexturePoolOGL() {}
72
73 public:
74 NS_INLINE_DECL_REFCOUNTING(CompositorTexturePoolOGL)
75
76 virtual void Clear() = 0;
77
78 virtual GLuint GetTexture(GLenum aTarget, GLenum aEnum) = 0;
79
80 virtual void EndFrame() = 0;
81 };
82
83 /**
84 * Agressively reuses textures. One gl texture per texture unit in total.
85 * So far this hasn't shown the best results on b2g.
86 */
87 class PerUnitTexturePoolOGL : public CompositorTexturePoolOGL
88 {
89 public:
90 PerUnitTexturePoolOGL(gl::GLContext* aGL)
91 : mTextureTarget(0) // zero is never a valid texture target
92 , mGL(aGL)
93 {}
94
95 virtual ~PerUnitTexturePoolOGL()
96 {
97 DestroyTextures();
98 }
99
100 virtual void Clear() MOZ_OVERRIDE
101 {
102 DestroyTextures();
103 }
104
105 virtual GLuint GetTexture(GLenum aTarget, GLenum aUnit) MOZ_OVERRIDE;
106
107 virtual void EndFrame() MOZ_OVERRIDE {}
108
109 protected:
110 void DestroyTextures();
111
112 GLenum mTextureTarget;
113 nsTArray<GLuint> mTextures;
114 RefPtr<gl::GLContext> mGL;
115 };
116
117 /**
118 * Reuse gl textures from a pool of textures that haven't yet been
119 * used during the current frame.
120 * All the textures that are not used at the end of a frame are
121 * deleted.
122 * This strategy seems to work well with gralloc textures because destroying
123 * unused textures which are bound to gralloc buffers let drivers know that it
124 * can unlock the gralloc buffers.
125 */
126 class PerFrameTexturePoolOGL : public CompositorTexturePoolOGL
127 {
128 public:
129 PerFrameTexturePoolOGL(gl::GLContext* aGL)
130 : mTextureTarget(0) // zero is never a valid texture target
131 , mGL(aGL)
132 {}
133
134 virtual ~PerFrameTexturePoolOGL()
135 {
136 DestroyTextures();
137 }
138
139 virtual void Clear() MOZ_OVERRIDE
140 {
141 DestroyTextures();
142 }
143
144 virtual GLuint GetTexture(GLenum aTarget, GLenum aUnit) MOZ_OVERRIDE;
145
146 virtual void EndFrame() MOZ_OVERRIDE;
147
148 protected:
149 void DestroyTextures();
150
151 GLenum mTextureTarget;
152 RefPtr<gl::GLContext> mGL;
153 nsTArray<GLuint> mCreatedTextures;
154 nsTArray<GLuint> mUnusedTextures;
155 };
156
157 class CompositorOGL : public Compositor
158 {
159 typedef mozilla::gl::GLContext GLContext;
160
161 friend class GLManagerCompositor;
162
163 std::map<ShaderConfigOGL, ShaderProgramOGL*> mPrograms;
164 public:
165 CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth = -1, int aSurfaceHeight = -1,
166 bool aUseExternalSurfaceSize = false);
167
168 virtual ~CompositorOGL();
169
170 virtual TemporaryRef<DataTextureSource>
171 CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE;
172
173 virtual bool Initialize() MOZ_OVERRIDE;
174
175 virtual void Destroy() MOZ_OVERRIDE;
176
177 virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
178 {
179 return TextureFactoryIdentifier(LayersBackend::LAYERS_OPENGL,
180 XRE_GetProcessType(),
181 GetMaxTextureSize(),
182 mFBOTextureTarget == LOCAL_GL_TEXTURE_2D,
183 SupportsPartialTextureUpdate());
184 }
185
186 virtual TemporaryRef<CompositingRenderTarget>
187 CreateRenderTarget(const gfx::IntRect &aRect, SurfaceInitMode aInit) MOZ_OVERRIDE;
188
189 virtual TemporaryRef<CompositingRenderTarget>
190 CreateRenderTargetFromSource(const gfx::IntRect &aRect,
191 const CompositingRenderTarget *aSource,
192 const gfx::IntPoint &aSourcePoint) MOZ_OVERRIDE;
193
194 virtual void SetRenderTarget(CompositingRenderTarget *aSurface) MOZ_OVERRIDE;
195 virtual CompositingRenderTarget* GetCurrentRenderTarget() const MOZ_OVERRIDE;
196
197 virtual void DrawQuad(const gfx::Rect& aRect,
198 const gfx::Rect& aClipRect,
199 const EffectChain &aEffectChain,
200 gfx::Float aOpacity,
201 const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE
202 {
203 DrawQuadInternal(aRect, aClipRect, aEffectChain,
204 aOpacity, aTransform, LOCAL_GL_TRIANGLE_STRIP);
205 }
206
207 virtual void DrawLines(const std::vector<gfx::Point>& aLines,
208 const gfx::Rect& aClipRect,
209 const gfx::Color& aColor,
210 gfx::Float aOpacity,
211 const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE;
212
213
214 virtual void EndFrame() MOZ_OVERRIDE;
215 virtual void SetFBAcquireFence(Layer* aLayer) MOZ_OVERRIDE;
216 virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) MOZ_OVERRIDE;
217 virtual void AbortFrame() MOZ_OVERRIDE;
218
219 virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE;
220
221 virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE
222 {
223 if (!mGLContext)
224 return false;
225 int32_t maxSize = GetMaxTextureSize();
226 return aSize <= gfx::IntSize(maxSize, maxSize);
227 }
228
229 virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE;
230
231 /**
232 * Set the size of the EGL surface we're rendering to, if we're rendering to
233 * an EGL surface.
234 */
235 virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) MOZ_OVERRIDE;
236
237 virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) MOZ_OVERRIDE {
238 mRenderOffset = aOffset;
239 }
240
241 virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) MOZ_OVERRIDE;
242
243 virtual void SetTargetContext(gfx::DrawTarget* aTarget) MOZ_OVERRIDE
244 {
245 mTarget = aTarget;
246 }
247
248 virtual void PrepareViewport(const gfx::IntSize& aSize,
249 const gfx::Matrix& aWorldTransform) MOZ_OVERRIDE;
250
251
252 #ifdef MOZ_DUMP_PAINTING
253 virtual const char* Name() const MOZ_OVERRIDE { return "OGL"; }
254 #endif // MOZ_DUMP_PAINTING
255
256 virtual LayersBackend GetBackendType() const MOZ_OVERRIDE {
257 return LayersBackend::LAYERS_OPENGL;
258 }
259
260 virtual void Pause() MOZ_OVERRIDE;
261 virtual bool Resume() MOZ_OVERRIDE;
262
263 virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
264
265 GLContext* gl() const { return mGLContext; }
266 gfx::SurfaceFormat GetFBOFormat() const {
267 return gfx::SurfaceFormat::R8G8B8A8;
268 }
269
270 /**
271 * The compositor provides with temporary textures for use with direct
272 * textruing like gralloc texture.
273 * Doing so lets us use gralloc the way it has been designed to be used
274 * (see https://wiki.mozilla.org/Platform/GFX/Gralloc)
275 */
276 GLuint GetTemporaryTexture(GLenum aTarget, GLenum aUnit);
277
278 const gfx::Matrix4x4& GetProjMatrix() const {
279 return mProjMatrix;
280 }
281 private:
282 virtual void DrawQuadInternal(const gfx::Rect& aRect,
283 const gfx::Rect& aClipRect,
284 const EffectChain &aEffectChain,
285 gfx::Float aOpacity,
286 const gfx::Matrix4x4 &aTransformi,
287 GLuint aDrawMode);
288
289 virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE
290 {
291 return gfx::ToIntSize(mWidgetSize);
292 }
293
294 /**
295 * Context target, nullptr when drawing directly to our swap chain.
296 */
297 RefPtr<gfx::DrawTarget> mTarget;
298
299 /** Widget associated with this compositor */
300 nsIWidget *mWidget;
301 nsIntSize mWidgetSize;
302 nsRefPtr<GLContext> mGLContext;
303 gfx::Matrix4x4 mProjMatrix;
304
305 /** The size of the surface we are rendering to */
306 nsIntSize mSurfaceSize;
307
308 ScreenPoint mRenderOffset;
309
310 already_AddRefed<mozilla::gl::GLContext> CreateContext();
311
312 /** Texture target to use for FBOs */
313 GLenum mFBOTextureTarget;
314
315 /** Currently bound render target */
316 RefPtr<CompositingRenderTargetOGL> mCurrentRenderTarget;
317 #ifdef DEBUG
318 CompositingRenderTargetOGL* mWindowRenderTarget;
319 #endif
320
321 /**
322 * VBO that has some basics in it for a textured quad, including vertex
323 * coords and texcoords.
324 */
325 GLuint mQuadVBO;
326
327 /**
328 * When we can't use mQuadVBO, we allocate VBOs from this arena instead.
329 */
330 gl::VBOArena mVBOs;
331
332 bool mHasBGRA;
333
334 /**
335 * When rendering to some EGL surfaces (e.g. on Android), we rely on being told
336 * about size changes (via SetSurfaceSize) rather than pulling this information
337 * from the widget.
338 */
339 bool mUseExternalSurfaceSize;
340
341 /**
342 * Have we had DrawQuad calls since the last frame was rendered?
343 */
344 bool mFrameInProgress;
345
346 /*
347 * Clear aRect on current render target.
348 */
349 virtual void ClearRect(const gfx::Rect& aRect) MOZ_OVERRIDE;
350
351 /* Start a new frame. If aClipRectIn is null and aClipRectOut is non-null,
352 * sets *aClipRectOut to the screen dimensions.
353 */
354 virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
355 const gfx::Rect *aClipRectIn,
356 const gfx::Matrix& aTransform,
357 const gfx::Rect& aRenderBounds,
358 gfx::Rect *aClipRectOut = nullptr,
359 gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
360
361 ShaderConfigOGL GetShaderConfigFor(Effect *aEffect, MaskType aMask = MaskNone) const;
362 ShaderProgramOGL* GetShaderProgramFor(const ShaderConfigOGL &aConfig);
363
364 /**
365 * Create a FBO backed by a texture.
366 * Note that the texture target type will be
367 * of the type returned by FBOTextureTarget; different
368 * shaders are required to sample from the different
369 * texture types.
370 */
371 void CreateFBOWithTexture(const gfx::IntRect& aRect, bool aCopyFromSource,
372 GLuint aSourceFrameBuffer,
373 GLuint *aFBO, GLuint *aTexture);
374
375 GLintptr QuadVBOVertexOffset() { return 0; }
376 GLintptr QuadVBOTexCoordOffset() { return sizeof(float)*4*2; }
377
378 void BindQuadVBO();
379 void QuadVBOVerticesAttrib(GLuint aAttribIndex);
380 void QuadVBOTexCoordsAttrib(GLuint aAttribIndex);
381 void BindAndDrawQuad(GLuint aVertAttribIndex,
382 GLuint aTexCoordAttribIndex,
383 GLuint aDrawMode = LOCAL_GL_TRIANGLE_STRIP);
384 void BindAndDrawQuad(ShaderProgramOGL *aProg,
385 GLuint aDrawMode = LOCAL_GL_TRIANGLE_STRIP);
386 void BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
387 const gfx3DMatrix& aTextureTransform,
388 const gfx::Rect& aTexCoordRect,
389 TextureSource *aTexture);
390
391 void CleanupResources();
392
393 /**
394 * Copies the content of our backbuffer to the set transaction target.
395 * Does not restore the target FBO, so only call from EndFrame.
396 */
397 void CopyToTarget(gfx::DrawTarget* aTarget, const gfx::Matrix& aWorldMatrix);
398
399 /**
400 * Implements the flipping of the y-axis to convert from layers/compositor
401 * coordinates to OpenGL coordinates.
402 *
403 * Indeed, the only coordinate system that OpenGL knows has the y-axis
404 * pointing upwards, but the layers/compositor coordinate system has the
405 * y-axis pointing downwards, for good reason as Web pages are typically
406 * scrolled downwards. So, some flipping has to take place; FlippedY does it.
407 */
408 GLint FlipY(GLint y) const { return mHeight - y; }
409
410 RefPtr<CompositorTexturePoolOGL> mTexturePool;
411
412 bool mDestroyed;
413
414 /**
415 * Height of the OpenGL context's primary framebuffer in pixels. Used by
416 * FlipY for the y-flipping calculation.
417 */
418 GLint mHeight;
419 };
420
421 }
422 }
423
424 #endif /* MOZILLA_GFX_COMPOSITOROGL_H */

mercurial