Line data Source code
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_TEXTUREOGL_H
7 : #define MOZILLA_GFX_TEXTUREOGL_H
8 :
9 : #include <stddef.h> // for size_t
10 : #include <stdint.h> // for uint64_t
11 : #include "CompositableHost.h"
12 : #include "GLContextTypes.h" // for GLContext
13 : #include "GLDefs.h" // for GLenum, LOCAL_GL_CLAMP_TO_EDGE, etc
14 : #include "GLTextureImage.h" // for TextureImage
15 : #include "gfxTypes.h"
16 : #include "mozilla/GfxMessageUtils.h" // for gfxContentType
17 : #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
18 : #include "mozilla/Attributes.h" // for override
19 : #include "mozilla/RefPtr.h" // for RefPtr
20 : #include "mozilla/gfx/Matrix.h" // for Matrix4x4
21 : #include "mozilla/gfx/Point.h" // for IntSize, IntPoint
22 : #include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
23 : #include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
24 : #include "mozilla/layers/CompositorTypes.h" // for TextureFlags
25 : #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
26 : #include "mozilla/layers/TextureHost.h" // for TextureHost, etc
27 : #include "mozilla/mozalloc.h" // for operator delete, etc
28 : #include "nsCOMPtr.h" // for already_AddRefed
29 : #include "nsDebug.h" // for NS_WARNING
30 : #include "nsISupportsImpl.h" // for TextureImage::Release, etc
31 : #include "nsRegionFwd.h" // for nsIntRegion
32 : #include "OGLShaderProgram.h" // for ShaderProgramType, etc
33 :
34 : #ifdef MOZ_WIDGET_ANDROID
35 : #include "GeneratedJNIWrappers.h"
36 : #include "AndroidSurfaceTexture.h"
37 : #endif
38 :
39 : namespace mozilla {
40 : namespace gfx {
41 : class DataSourceSurface;
42 : } // namespace gfx
43 :
44 : namespace layers {
45 :
46 : class Compositor;
47 : class CompositorOGL;
48 : class TextureImageTextureSourceOGL;
49 : class GLTextureSource;
50 :
51 0 : inline void ApplySamplingFilterToBoundTexture(gl::GLContext* aGL,
52 : gfx::SamplingFilter aSamplingFilter,
53 : GLuint aTarget = LOCAL_GL_TEXTURE_2D)
54 : {
55 : GLenum filter =
56 0 : (aSamplingFilter == gfx::SamplingFilter::POINT ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR);
57 :
58 0 : aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, filter);
59 0 : aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, filter);
60 0 : }
61 :
62 : /*
63 : * TextureHost implementations for the OpenGL backend.
64 : *
65 : * Note that it is important to be careful about the ownership model with
66 : * the OpenGL backend, due to some widget limitation on Linux: before
67 : * the nsBaseWidget associated with our OpenGL context has been completely
68 : * deleted, every resource belonging to the OpenGL context MUST have been
69 : * released. At the moment the teardown sequence happens in the middle of
70 : * the nsBaseWidget's destructor, meaning that at a given moment we must be
71 : * able to easily find and release all the GL resources.
72 : * The point is: be careful about the ownership model and limit the number
73 : * of objects sharing references to GL resources to make the tear down
74 : * sequence as simple as possible.
75 : */
76 :
77 : /**
78 : * TextureSourceOGL provides the necessary API for CompositorOGL to composite
79 : * a TextureSource.
80 : */
81 : class TextureSourceOGL
82 : {
83 : public:
84 0 : TextureSourceOGL()
85 0 : : mHasCachedSamplingFilter(false)
86 0 : {}
87 :
88 : virtual bool IsValid() const = 0;
89 :
90 : virtual void BindTexture(GLenum aTextureUnit,
91 : gfx::SamplingFilter aSamplingFilter) = 0;
92 :
93 : virtual gfx::IntSize GetSize() const = 0;
94 :
95 0 : virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_2D; }
96 :
97 : virtual gfx::SurfaceFormat GetFormat() const = 0;
98 :
99 : virtual GLenum GetWrapMode() const = 0;
100 :
101 0 : virtual gfx::Matrix4x4 GetTextureTransform() { return gfx::Matrix4x4(); }
102 :
103 0 : virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() { return nullptr; }
104 :
105 0 : virtual GLTextureSource* AsGLTextureSource() { return nullptr; }
106 :
107 0 : void SetSamplingFilter(gl::GLContext* aGL, gfx::SamplingFilter aSamplingFilter)
108 : {
109 0 : if (mHasCachedSamplingFilter &&
110 0 : mCachedSamplingFilter == aSamplingFilter) {
111 0 : return;
112 : }
113 0 : mHasCachedSamplingFilter = true;
114 0 : mCachedSamplingFilter = aSamplingFilter;
115 0 : ApplySamplingFilterToBoundTexture(aGL, aSamplingFilter, GetTextureTarget());
116 : }
117 :
118 0 : void ClearCachedFilter() { mHasCachedSamplingFilter = false; }
119 :
120 : private:
121 : gfx::SamplingFilter mCachedSamplingFilter;
122 : bool mHasCachedSamplingFilter;
123 : };
124 :
125 : /**
126 : * A TextureSource backed by a TextureImage.
127 : *
128 : * Depending on the underlying TextureImage, may support texture tiling, so
129 : * make sure to check AsBigImageIterator() and use the texture accordingly.
130 : *
131 : * This TextureSource can be used without a TextureHost and manage it's own
132 : * GL texture(s).
133 : */
134 0 : class TextureImageTextureSourceOGL final : public DataTextureSource
135 : , public TextureSourceOGL
136 : , public BigImageIterator
137 : {
138 : public:
139 0 : explicit TextureImageTextureSourceOGL(CompositorOGL *aCompositor,
140 : TextureFlags aFlags = TextureFlags::DEFAULT)
141 0 : : mGL(aCompositor->gl())
142 : , mFlags(aFlags)
143 0 : , mIterating(false)
144 0 : {}
145 :
146 0 : virtual const char* Name() const override { return "TextureImageTextureSourceOGL"; }
147 : // DataTextureSource
148 :
149 : virtual bool Update(gfx::DataSourceSurface* aSurface,
150 : nsIntRegion* aDestRegion = nullptr,
151 : gfx::IntPoint* aSrcOffset = nullptr) override;
152 :
153 : void EnsureBuffer(const gfx::IntSize& aSize,
154 : gfxContentType aContentType);
155 :
156 0 : virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() override { return this; }
157 :
158 : // TextureSource
159 :
160 0 : virtual void DeallocateDeviceData() override
161 : {
162 0 : mTexImage = nullptr;
163 0 : SetUpdateSerial(0);
164 0 : }
165 :
166 0 : virtual TextureSourceOGL* AsSourceOGL() override { return this; }
167 :
168 : virtual void BindTexture(GLenum aTextureUnit,
169 : gfx::SamplingFilter aSamplingFilter) override;
170 :
171 : virtual gfx::IntSize GetSize() const override;
172 :
173 : virtual gfx::SurfaceFormat GetFormat() const override;
174 :
175 0 : virtual bool IsValid() const override { return !!mTexImage; }
176 :
177 : virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
178 :
179 0 : virtual GLenum GetWrapMode() const override
180 : {
181 0 : return mTexImage->GetWrapMode();
182 : }
183 :
184 : // BigImageIterator
185 :
186 0 : virtual BigImageIterator* AsBigImageIterator() override { return this; }
187 :
188 0 : virtual void BeginBigImageIteration() override
189 : {
190 0 : mTexImage->BeginBigImageIteration();
191 0 : mIterating = true;
192 0 : }
193 :
194 0 : virtual void EndBigImageIteration() override
195 : {
196 0 : mIterating = false;
197 0 : }
198 :
199 : virtual gfx::IntRect GetTileRect() override;
200 :
201 0 : virtual size_t GetTileCount() override
202 : {
203 0 : return mTexImage->GetTileCount();
204 : }
205 :
206 0 : virtual bool NextTile() override
207 : {
208 0 : return mTexImage->NextTile();
209 : }
210 :
211 : protected:
212 : RefPtr<gl::TextureImage> mTexImage;
213 : RefPtr<gl::GLContext> mGL;
214 : TextureFlags mFlags;
215 : bool mIterating;
216 : };
217 :
218 : /**
219 : * A texture source for GL textures.
220 : *
221 : * It does not own any GL texture, and attaches its shared handle to one of
222 : * the compositor's temporary textures when binding.
223 : *
224 : * The shared texture handle is owned by the TextureHost.
225 : */
226 : class GLTextureSource : public TextureSource
227 : , public TextureSourceOGL
228 : {
229 : public:
230 : GLTextureSource(TextureSourceProvider* aProvider,
231 : GLuint aTextureHandle,
232 : GLenum aTarget,
233 : gfx::IntSize aSize,
234 : gfx::SurfaceFormat aFormat,
235 : bool aExternallyOwned = false);
236 :
237 : ~GLTextureSource();
238 :
239 0 : virtual const char* Name() const override { return "GLTextureSource"; }
240 :
241 0 : virtual GLTextureSource* AsGLTextureSource() override { return this; }
242 :
243 0 : virtual TextureSourceOGL* AsSourceOGL() override { return this; }
244 :
245 : virtual void BindTexture(GLenum activetex,
246 : gfx::SamplingFilter aSamplingFilter) override;
247 :
248 : virtual bool IsValid() const override;
249 :
250 0 : virtual gfx::IntSize GetSize() const override { return mSize; }
251 :
252 0 : virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
253 :
254 0 : virtual GLenum GetTextureTarget() const override { return mTextureTarget; }
255 :
256 0 : virtual GLenum GetWrapMode() const override { return LOCAL_GL_CLAMP_TO_EDGE; }
257 :
258 : virtual void DeallocateDeviceData() override;
259 :
260 : virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
261 :
262 : void SetSize(gfx::IntSize aSize) { mSize = aSize; }
263 :
264 : void SetFormat(gfx::SurfaceFormat aFormat) { mFormat = aFormat; }
265 :
266 : GLuint GetTextureHandle() const { return mTextureHandle; }
267 :
268 0 : gl::GLContext* gl() const {
269 0 : return mGL;
270 : }
271 :
272 : protected:
273 : void DeleteTextureHandle();
274 :
275 : RefPtr<gl::GLContext> mGL;
276 : RefPtr<CompositorOGL> mCompositor;
277 : GLuint mTextureHandle;
278 : GLenum mTextureTarget;
279 : gfx::IntSize mSize;
280 : gfx::SurfaceFormat mFormat;
281 : // If the texture is externally owned, the gl handle will not be deleted
282 : // in the destructor.
283 : bool mExternallyOwned;
284 : };
285 :
286 : class GLTextureHost : public TextureHost
287 : {
288 : public:
289 : GLTextureHost(TextureFlags aFlags,
290 : GLuint aTextureHandle,
291 : GLenum aTarget,
292 : GLsync aSync,
293 : gfx::IntSize aSize,
294 : bool aHasAlpha);
295 :
296 : virtual ~GLTextureHost();
297 :
298 : // We don't own anything.
299 0 : virtual void DeallocateDeviceData() override {}
300 :
301 : virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
302 :
303 : virtual bool Lock() override;
304 :
305 0 : virtual void Unlock() override {}
306 :
307 : virtual gfx::SurfaceFormat GetFormat() const override;
308 :
309 0 : virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
310 : {
311 0 : aTexture = mTextureSource;
312 0 : return !!aTexture;
313 : }
314 :
315 0 : virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
316 : {
317 0 : return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
318 : }
319 :
320 : gl::GLContext* gl() const;
321 :
322 0 : virtual gfx::IntSize GetSize() const override { return mSize; }
323 :
324 0 : virtual const char* Name() override { return "GLTextureHost"; }
325 :
326 : protected:
327 : const GLuint mTexture;
328 : const GLenum mTarget;
329 : GLsync mSync;
330 : const gfx::IntSize mSize;
331 : const bool mHasAlpha;
332 : RefPtr<GLTextureSource> mTextureSource;
333 : };
334 :
335 : ////////////////////////////////////////////////////////////////////////
336 : // SurfaceTexture
337 :
338 : #ifdef MOZ_WIDGET_ANDROID
339 :
340 : class SurfaceTextureSource : public TextureSource
341 : , public TextureSourceOGL
342 : {
343 : public:
344 : SurfaceTextureSource(TextureSourceProvider* aProvider,
345 : java::GeckoSurfaceTexture::Ref& aSurfTex,
346 : gfx::SurfaceFormat aFormat,
347 : GLenum aTarget,
348 : GLenum aWrapMode,
349 : gfx::IntSize aSize);
350 :
351 : virtual const char* Name() const override { return "SurfaceTextureSource"; }
352 :
353 : virtual TextureSourceOGL* AsSourceOGL() override { return this; }
354 :
355 : virtual void BindTexture(GLenum activetex,
356 : gfx::SamplingFilter aSamplingFilter) override;
357 :
358 : virtual bool IsValid() const override;
359 :
360 : virtual gfx::IntSize GetSize() const override { return mSize; }
361 :
362 : virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
363 :
364 : virtual gfx::Matrix4x4 GetTextureTransform() override;
365 :
366 : virtual GLenum GetTextureTarget() const override { return mTextureTarget; }
367 :
368 : virtual GLenum GetWrapMode() const override { return mWrapMode; }
369 :
370 : virtual void DeallocateDeviceData() override;
371 :
372 : virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
373 :
374 : gl::GLContext* gl() const {
375 : return mGL;
376 : }
377 :
378 : protected:
379 : RefPtr<gl::GLContext> mGL;
380 : mozilla::java::GeckoSurfaceTexture::GlobalRef mSurfTex;
381 : const gfx::SurfaceFormat mFormat;
382 : const GLenum mTextureTarget;
383 : const GLenum mWrapMode;
384 : const gfx::IntSize mSize;
385 : };
386 :
387 : class SurfaceTextureHost : public TextureHost
388 : {
389 : public:
390 : SurfaceTextureHost(TextureFlags aFlags,
391 : mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
392 : gfx::IntSize aSize,
393 : bool aContinuousUpdate);
394 :
395 : virtual ~SurfaceTextureHost();
396 :
397 : virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) override;
398 :
399 : virtual void DeallocateDeviceData() override;
400 :
401 : virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
402 :
403 : virtual bool Lock() override;
404 :
405 : virtual gfx::SurfaceFormat GetFormat() const override;
406 :
407 : virtual void NotifyNotUsed() override;
408 :
409 : virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
410 : {
411 : aTexture = mTextureSource;
412 : return !!aTexture;
413 : }
414 :
415 : virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
416 : {
417 : return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
418 : }
419 :
420 : gl::GLContext* gl() const;
421 :
422 : virtual gfx::IntSize GetSize() const override { return mSize; }
423 :
424 : virtual const char* Name() override { return "SurfaceTextureHost"; }
425 :
426 : protected:
427 : mozilla::java::GeckoSurfaceTexture::GlobalRef mSurfTex;
428 : const gfx::IntSize mSize;
429 : bool mContinuousUpdate;
430 : RefPtr<CompositorOGL> mCompositor;
431 : RefPtr<SurfaceTextureSource> mTextureSource;
432 : };
433 :
434 : #endif // MOZ_WIDGET_ANDROID
435 :
436 : ////////////////////////////////////////////////////////////////////////
437 : // EGLImage
438 :
439 0 : class EGLImageTextureSource : public TextureSource
440 : , public TextureSourceOGL
441 : {
442 : public:
443 : EGLImageTextureSource(TextureSourceProvider* aProvider,
444 : EGLImage aImage,
445 : gfx::SurfaceFormat aFormat,
446 : GLenum aTarget,
447 : GLenum aWrapMode,
448 : gfx::IntSize aSize);
449 :
450 0 : virtual const char* Name() const override { return "EGLImageTextureSource"; }
451 :
452 0 : virtual TextureSourceOGL* AsSourceOGL() override { return this; }
453 :
454 : virtual void BindTexture(GLenum activetex,
455 : gfx::SamplingFilter aSamplingFilter) override;
456 :
457 : virtual bool IsValid() const override;
458 :
459 0 : virtual gfx::IntSize GetSize() const override { return mSize; }
460 :
461 0 : virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
462 :
463 : virtual gfx::Matrix4x4 GetTextureTransform() override;
464 :
465 0 : virtual GLenum GetTextureTarget() const override { return mTextureTarget; }
466 :
467 0 : virtual GLenum GetWrapMode() const override { return mWrapMode; }
468 :
469 : // We don't own anything.
470 0 : virtual void DeallocateDeviceData() override {}
471 :
472 : virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
473 :
474 0 : gl::GLContext* gl() const {
475 0 : return mGL;
476 : }
477 :
478 : protected:
479 : RefPtr<gl::GLContext> mGL;
480 : RefPtr<CompositorOGL> mCompositor;
481 : const EGLImage mImage;
482 : const gfx::SurfaceFormat mFormat;
483 : const GLenum mTextureTarget;
484 : const GLenum mWrapMode;
485 : const gfx::IntSize mSize;
486 : };
487 :
488 : class EGLImageTextureHost final : public TextureHost
489 : {
490 : public:
491 : EGLImageTextureHost(TextureFlags aFlags,
492 : EGLImage aImage,
493 : EGLSync aSync,
494 : gfx::IntSize aSize,
495 : bool hasAlpha);
496 :
497 : virtual ~EGLImageTextureHost();
498 :
499 : // We don't own anything.
500 0 : virtual void DeallocateDeviceData() override {}
501 :
502 : void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
503 :
504 : virtual bool Lock() override;
505 :
506 : virtual void Unlock() override;
507 :
508 : virtual gfx::SurfaceFormat GetFormat() const override;
509 :
510 0 : virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
511 : {
512 0 : aTexture = mTextureSource;
513 0 : return !!aTexture;
514 : }
515 :
516 0 : virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
517 : {
518 0 : return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
519 : }
520 :
521 : gl::GLContext* gl() const;
522 :
523 0 : virtual gfx::IntSize GetSize() const override { return mSize; }
524 :
525 0 : virtual const char* Name() override { return "EGLImageTextureHost"; }
526 :
527 : protected:
528 : const EGLImage mImage;
529 : const EGLSync mSync;
530 : const gfx::IntSize mSize;
531 : const bool mHasAlpha;
532 : RefPtr<EGLImageTextureSource> mTextureSource;
533 : };
534 :
535 : } // namespace layers
536 : } // namespace mozilla
537 :
538 : #endif /* MOZILLA_GFX_TEXTUREOGL_H */
|