Backed out 2 changesets (bug 1931901) for causing build bustages in TelemetryScalar...
[gecko.git] / gfx / layers / opengl / TextureHostOGL.h
blob96d898ac0250e10ecf8dabde6d4ac6996ee596a5
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MOZILLA_GFX_TEXTUREOGL_H
8 #define MOZILLA_GFX_TEXTUREOGL_H
10 #include <stddef.h> // for size_t
11 #include <stdint.h> // for uint64_t
12 #include "CompositableHost.h"
13 #include "GLContextTypes.h" // for GLContext
14 #include "GLDefs.h" // for GLenum, LOCAL_GL_CLAMP_TO_EDGE, etc
15 #include "GLTextureImage.h" // for TextureImage
16 #include "gfxTypes.h"
17 #include "mozilla/GfxMessageUtils.h" // for gfxContentType
18 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
19 #include "mozilla/Attributes.h" // for override
20 #include "mozilla/RefPtr.h" // for RefPtr
21 #include "mozilla/gfx/Matrix.h" // for Matrix4x4
22 #include "mozilla/gfx/Point.h" // for IntSize, IntPoint
23 #include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
24 #include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
25 #include "mozilla/layers/CompositorTypes.h" // for TextureFlags
26 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
27 #include "mozilla/layers/TextureHost.h" // for TextureHost, etc
28 #include "mozilla/mozalloc.h" // for operator delete, etc
29 #include "mozilla/webrender/RenderThread.h"
30 #include "nsCOMPtr.h" // for already_AddRefed
31 #include "nsDebug.h" // for NS_WARNING
32 #include "nsISupportsImpl.h" // for TextureImage::Release, etc
33 #include "nsRegionFwd.h" // for nsIntRegion
35 #ifdef MOZ_WIDGET_ANDROID
36 # include "AndroidSurfaceTexture.h"
37 # include "mozilla/java/GeckoSurfaceTextureWrappers.h"
38 #endif
40 namespace mozilla {
41 namespace gfx {
42 class DataSourceSurface;
43 } // namespace gfx
45 namespace layers {
47 class Compositor;
48 class CompositorOGL;
49 class AndroidHardwareBuffer;
50 class SurfaceDescriptorAndroidHardwareBuffer;
51 class TextureImageTextureSourceOGL;
52 class GLTextureSource;
54 void ApplySamplingFilterToBoundTexture(gl::GLContext* aGL,
55 gfx::SamplingFilter aSamplingFilter,
56 GLuint aTarget = LOCAL_GL_TEXTURE_2D);
58 already_AddRefed<TextureHost> CreateTextureHostOGL(
59 const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator,
60 LayersBackend aBackend, TextureFlags aFlags);
63 * TextureHost implementations for the OpenGL backend.
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.
77 /**
78 * TextureSourceOGL provides the necessary API for CompositorOGL to composite
79 * a TextureSource.
81 class TextureSourceOGL {
82 public:
83 TextureSourceOGL()
84 : mCachedSamplingFilter(gfx::SamplingFilter::GOOD),
85 mHasCachedSamplingFilter(false) {}
87 virtual bool IsValid() const = 0;
89 virtual void BindTexture(GLenum aTextureUnit,
90 gfx::SamplingFilter aSamplingFilter) = 0;
92 // To be overridden in textures that need this. This method will be called
93 // when the compositor has used the texture to draw. This allows us to set
94 // a fence with glFenceSync which we can wait on later to ensure the GPU
95 // is done with the draw calls using that texture. We would like to be able
96 // to simply use glFinishObjectAPPLE, but this returns earlier than
97 // expected with nvidia drivers.
98 virtual void MaybeFenceTexture() {}
100 virtual gfx::IntSize GetSize() const = 0;
102 virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_2D; }
104 virtual gfx::SurfaceFormat GetFormat() const = 0;
106 virtual GLenum GetWrapMode() const = 0;
108 virtual gfx::Matrix4x4 GetTextureTransform() { return gfx::Matrix4x4(); }
110 virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() {
111 return nullptr;
114 virtual GLTextureSource* AsGLTextureSource() { return nullptr; }
116 void SetSamplingFilter(gl::GLContext* aGL,
117 gfx::SamplingFilter aSamplingFilter) {
118 if (mHasCachedSamplingFilter && mCachedSamplingFilter == aSamplingFilter) {
119 return;
121 mHasCachedSamplingFilter = true;
122 mCachedSamplingFilter = aSamplingFilter;
123 ApplySamplingFilterToBoundTexture(aGL, aSamplingFilter, GetTextureTarget());
126 void ClearCachedFilter() { mHasCachedSamplingFilter = false; }
128 private:
129 gfx::SamplingFilter mCachedSamplingFilter;
130 bool mHasCachedSamplingFilter;
134 * A TextureSource backed by a TextureImage.
136 * Depending on the underlying TextureImage, may support texture tiling, so
137 * make sure to check AsBigImageIterator() and use the texture accordingly.
139 * This TextureSource can be used without a TextureHost and manage it's own
140 * GL texture(s).
142 class TextureImageTextureSourceOGL final : public DataTextureSource,
143 public TextureSourceOGL,
144 public BigImageIterator {
145 public:
146 explicit TextureImageTextureSourceOGL(
147 CompositorOGL* aCompositor, TextureFlags aFlags = TextureFlags::DEFAULT);
149 const char* Name() const override { return "TextureImageTextureSourceOGL"; }
150 // DataTextureSource
152 bool Update(gfx::DataSourceSurface* aSurface,
153 nsIntRegion* aDestRegion = nullptr,
154 gfx::IntPoint* aSrcOffset = nullptr,
155 gfx::IntPoint* aDstOffset = nullptr) override;
157 void EnsureBuffer(const gfx::IntSize& aSize, gfxContentType aContentType);
159 TextureImageTextureSourceOGL* AsTextureImageTextureSource() override {
160 return this;
163 // TextureSource
165 void DeallocateDeviceData() override;
167 TextureSourceOGL* AsSourceOGL() override { return this; }
169 void BindTexture(GLenum aTextureUnit,
170 gfx::SamplingFilter aSamplingFilter) override;
172 gfx::IntSize GetSize() const override;
174 gfx::SurfaceFormat GetFormat() const override;
176 bool IsValid() const override { return !!mTexImage; }
178 GLenum GetWrapMode() const override { return mTexImage->GetWrapMode(); }
180 // BigImageIterator
182 BigImageIterator* AsBigImageIterator() override { return this; }
184 void BeginBigImageIteration() override {
185 mTexImage->BeginBigImageIteration();
186 mIterating = true;
189 void EndBigImageIteration() override { mIterating = false; }
191 gfx::IntRect GetTileRect() override;
193 size_t GetTileCount() override { return mTexImage->GetTileCount(); }
195 bool NextTile() override { return mTexImage->NextTile(); }
197 gl::GLContext* gl() const { return mGL; }
199 protected:
200 ~TextureImageTextureSourceOGL();
202 RefPtr<gl::TextureImage> mTexImage;
203 RefPtr<gl::GLContext> mGL;
204 RefPtr<CompositorOGL> mCompositor;
205 TextureFlags mFlags;
206 bool mIterating;
210 * A texture source for GL textures.
212 * It does not own any GL texture, and attaches its shared handle to one of
213 * the compositor's temporary textures when binding.
215 * The shared texture handle is owned by the TextureHost.
217 class GLTextureSource : public DataTextureSource, public TextureSourceOGL {
218 public:
219 GLTextureSource(TextureSourceProvider* aProvider, GLuint aTextureHandle,
220 GLenum aTarget, gfx::IntSize aSize,
221 gfx::SurfaceFormat aFormat);
223 GLTextureSource(gl::GLContext* aGL, GLuint aTextureHandle, GLenum aTarget,
224 gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
226 virtual ~GLTextureSource();
228 const char* Name() const override { return "GLTextureSource"; }
230 GLTextureSource* AsGLTextureSource() override { return this; }
232 TextureSourceOGL* AsSourceOGL() override { return this; }
234 void BindTexture(GLenum activetex,
235 gfx::SamplingFilter aSamplingFilter) override;
237 bool IsValid() const override;
239 gfx::IntSize GetSize() const override { return mSize; }
241 gfx::SurfaceFormat GetFormat() const override { return mFormat; }
243 GLenum GetTextureTarget() const override { return mTextureTarget; }
245 GLenum GetWrapMode() const override { return LOCAL_GL_CLAMP_TO_EDGE; }
247 void DeallocateDeviceData() override;
249 void SetSize(gfx::IntSize aSize) { mSize = aSize; }
251 void SetFormat(gfx::SurfaceFormat aFormat) { mFormat = aFormat; }
253 GLuint GetTextureHandle() const { return mTextureHandle; }
255 gl::GLContext* gl() const { return mGL; }
257 bool Update(gfx::DataSourceSurface* aSurface,
258 nsIntRegion* aDestRegion = nullptr,
259 gfx::IntPoint* aSrcOffset = nullptr,
260 gfx::IntPoint* aDstOffset = nullptr) override {
261 return false;
264 protected:
265 void DeleteTextureHandle();
267 RefPtr<gl::GLContext> mGL;
268 RefPtr<CompositorOGL> mCompositor;
269 GLuint mTextureHandle;
270 GLenum mTextureTarget;
271 gfx::IntSize mSize;
272 gfx::SurfaceFormat mFormat;
275 // This texture source try to wrap "aSurface" in ctor for compositor direct
276 // access. Since we can't know the timing for gpu buffer access, the surface
277 // should be alive until the ~ClientStorageTextureSource(). And if we try to
278 // update the surface we mapped before, we need to call Sync() to make sure
279 // the surface is not used by compositor.
280 class DirectMapTextureSource : public GLTextureSource {
281 public:
282 DirectMapTextureSource(gl::GLContext* aContext,
283 gfx::DataSourceSurface* aSurface);
284 DirectMapTextureSource(TextureSourceProvider* aProvider,
285 gfx::DataSourceSurface* aSurface);
286 ~DirectMapTextureSource();
288 bool Update(gfx::DataSourceSurface* aSurface,
289 nsIntRegion* aDestRegion = nullptr,
290 gfx::IntPoint* aSrcOffset = nullptr,
291 gfx::IntPoint* aDstOffset = nullptr) override;
293 // If aBlocking is false, check if this texture is no longer being used
294 // by the GPU - if aBlocking is true, this will block until the GPU is
295 // done with it.
296 bool Sync(bool aBlocking) override;
298 void MaybeFenceTexture() override;
300 private:
301 bool UpdateInternal(gfx::DataSourceSurface* aSurface,
302 nsIntRegion* aDestRegion, gfx::IntPoint* aSrcOffset,
303 bool aInit);
305 GLsync mSync;
308 class GLTextureHost : public TextureHost {
309 public:
310 GLTextureHost(TextureFlags aFlags, GLuint aTextureHandle, GLenum aTarget,
311 GLsync aSync, gfx::IntSize aSize, bool aHasAlpha);
313 virtual ~GLTextureHost();
315 // We don't own anything.
316 void DeallocateDeviceData() override {}
318 gfx::SurfaceFormat GetFormat() const override;
320 already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
321 gfx::DataSourceSurface* aSurface) override {
322 return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
325 gl::GLContext* gl() const;
327 gfx::IntSize GetSize() const override { return mSize; }
329 const char* Name() override { return "GLTextureHost"; }
331 protected:
332 const GLuint mTexture;
333 const GLenum mTarget;
334 GLsync mSync;
335 const gfx::IntSize mSize;
336 const bool mHasAlpha;
337 RefPtr<GLTextureSource> mTextureSource;
340 ////////////////////////////////////////////////////////////////////////
341 // SurfaceTexture
343 #ifdef MOZ_WIDGET_ANDROID
345 class SurfaceTextureSource : public TextureSource, public TextureSourceOGL {
346 public:
347 SurfaceTextureSource(TextureSourceProvider* aProvider,
348 java::GeckoSurfaceTexture::Ref& aSurfTex,
349 gfx::SurfaceFormat aFormat, GLenum aTarget,
350 GLenum aWrapMode, gfx::IntSize aSize,
351 Maybe<gfx::Matrix4x4> aTransformOverride);
353 const char* Name() const override { return "SurfaceTextureSource"; }
355 TextureSourceOGL* AsSourceOGL() override { return this; }
357 void BindTexture(GLenum activetex,
358 gfx::SamplingFilter aSamplingFilter) override;
360 bool IsValid() const override;
362 gfx::IntSize GetSize() const override { return mSize; }
364 gfx::SurfaceFormat GetFormat() const override { return mFormat; }
366 gfx::Matrix4x4 GetTextureTransform() override;
368 GLenum GetTextureTarget() const override { return mTextureTarget; }
370 GLenum GetWrapMode() const override { return mWrapMode; }
372 void DeallocateDeviceData() override;
374 gl::GLContext* gl() const { return mGL; }
376 protected:
377 RefPtr<gl::GLContext> mGL;
378 mozilla::java::GeckoSurfaceTexture::GlobalRef mSurfTex;
379 const gfx::SurfaceFormat mFormat;
380 const GLenum mTextureTarget;
381 const GLenum mWrapMode;
382 const gfx::IntSize mSize;
383 const Maybe<gfx::Matrix4x4> mTransformOverride;
386 class SurfaceTextureHost : public TextureHost {
387 public:
388 SurfaceTextureHost(TextureFlags aFlags,
389 mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
390 gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
391 bool aContinuousUpdate, bool aForceBT709ColorSpace,
392 Maybe<gfx::Matrix4x4> aTransformOverride);
394 virtual ~SurfaceTextureHost();
396 void DeallocateDeviceData() override;
398 gfx::SurfaceFormat GetFormat() const override;
400 already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
401 gfx::DataSourceSurface* aSurface) override {
402 return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
405 gl::GLContext* gl() const;
407 gfx::IntSize GetSize() const override { return mSize; }
409 const char* Name() override { return "SurfaceTextureHost"; }
411 SurfaceTextureHost* AsSurfaceTextureHost() override { return this; }
413 bool IsWrappingSurfaceTextureHost() override { return true; }
415 void CreateRenderTexture(
416 const wr::ExternalImageId& aExternalImageId) override;
418 uint32_t NumSubTextures() override;
420 void PushResourceUpdates(wr::TransactionBuilder& aResources,
421 ResourceUpdateOp aOp,
422 const Range<wr::ImageKey>& aImageKeys,
423 const wr::ExternalImageId& aExtID) override;
425 void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
426 const wr::LayoutRect& aBounds,
427 const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
428 const Range<wr::ImageKey>& aImageKeys,
429 PushDisplayItemFlagSet aFlags) override;
431 bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
433 // gecko does not need deferred deletion with WebRender
434 // GPU/hardware task end could be checked by android fence.
435 // SurfaceTexture uses android fence internally,
436 bool NeedsDeferredDeletion() const override { return false; }
438 protected:
439 mozilla::java::GeckoSurfaceTexture::GlobalRef mSurfTex;
440 const gfx::IntSize mSize;
441 const gfx::SurfaceFormat mFormat;
442 bool mContinuousUpdate;
443 const bool mForceBT709ColorSpace;
444 const Maybe<gfx::Matrix4x4> mTransformOverride;
445 RefPtr<CompositorOGL> mCompositor;
446 RefPtr<SurfaceTextureSource> mTextureSource;
449 class AndroidHardwareBufferTextureSource : public TextureSource,
450 public TextureSourceOGL {
451 public:
452 AndroidHardwareBufferTextureSource(
453 TextureSourceProvider* aProvider,
454 AndroidHardwareBuffer* aAndroidHardwareBuffer, gfx::SurfaceFormat aFormat,
455 GLenum aTarget, GLenum aWrapMode, gfx::IntSize aSize);
457 const char* Name() const override { return "SurfaceTextureSource"; }
459 TextureSourceOGL* AsSourceOGL() override { return this; }
461 void BindTexture(GLenum activetex,
462 gfx::SamplingFilter aSamplingFilter) override;
464 bool IsValid() const override;
466 gfx::IntSize GetSize() const override { return mSize; }
468 gfx::SurfaceFormat GetFormat() const override { return mFormat; }
470 GLenum GetTextureTarget() const override { return mTextureTarget; }
472 GLenum GetWrapMode() const override { return mWrapMode; }
474 void DeallocateDeviceData() override;
476 gl::GLContext* gl() const { return mGL; }
478 protected:
479 virtual ~AndroidHardwareBufferTextureSource();
481 bool EnsureEGLImage();
482 void DestroyEGLImage();
483 void DeleteTextureHandle();
485 RefPtr<gl::GLContext> mGL;
486 RefPtr<AndroidHardwareBuffer> mAndroidHardwareBuffer;
487 const gfx::SurfaceFormat mFormat;
488 const GLenum mTextureTarget;
489 const GLenum mWrapMode;
490 const gfx::IntSize mSize;
492 EGLImage mEGLImage;
493 GLuint mTextureHandle;
496 class AndroidHardwareBufferTextureHost : public TextureHost {
497 public:
498 static already_AddRefed<AndroidHardwareBufferTextureHost> Create(
499 TextureFlags aFlags, const SurfaceDescriptorAndroidHardwareBuffer& aDesc);
501 AndroidHardwareBufferTextureHost(
502 TextureFlags aFlags, AndroidHardwareBuffer* aAndroidHardwareBuffer);
504 virtual ~AndroidHardwareBufferTextureHost();
506 void DeallocateDeviceData() override;
508 gfx::SurfaceFormat GetFormat() const override;
510 gfx::IntSize GetSize() const override;
512 void NotifyNotUsed() override;
514 already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
515 gfx::DataSourceSurface* aSurface) override {
516 return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
519 gl::GLContext* gl() const;
521 const char* Name() override { return "AndroidHardwareBufferTextureHost"; }
523 AndroidHardwareBufferTextureHost* AsAndroidHardwareBufferTextureHost()
524 override {
525 return this;
528 void CreateRenderTexture(
529 const wr::ExternalImageId& aExternalImageId) override;
531 uint32_t NumSubTextures() override;
533 void PushResourceUpdates(wr::TransactionBuilder& aResources,
534 ResourceUpdateOp aOp,
535 const Range<wr::ImageKey>& aImageKeys,
536 const wr::ExternalImageId& aExtID) override;
538 void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
539 const wr::LayoutRect& aBounds,
540 const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
541 const Range<wr::ImageKey>& aImageKeys,
542 PushDisplayItemFlagSet aFlags) override;
544 void SetAcquireFence(mozilla::ipc::FileDescriptor&& aFenceFd) override;
546 void SetReleaseFence(mozilla::ipc::FileDescriptor&& aFenceFd) override;
548 mozilla::ipc::FileDescriptor GetAndResetReleaseFence() override;
550 AndroidHardwareBuffer* GetAndroidHardwareBuffer() const override {
551 return mAndroidHardwareBuffer;
554 bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
556 // gecko does not need deferred deletion with WebRender
557 // GPU/hardware task end could be checked by android fence.
558 bool NeedsDeferredDeletion() const override { return false; }
560 protected:
561 RefPtr<AndroidHardwareBuffer> mAndroidHardwareBuffer;
564 #endif // MOZ_WIDGET_ANDROID
566 ////////////////////////////////////////////////////////////////////////
567 // EGLImage
569 class EGLImageTextureSource : public TextureSource, public TextureSourceOGL {
570 public:
571 EGLImageTextureSource(TextureSourceProvider* aProvider, EGLImage aImage,
572 gfx::SurfaceFormat aFormat, GLenum aTarget,
573 GLenum aWrapMode, gfx::IntSize aSize);
575 const char* Name() const override { return "EGLImageTextureSource"; }
577 TextureSourceOGL* AsSourceOGL() override { return this; }
579 void BindTexture(GLenum activetex,
580 gfx::SamplingFilter aSamplingFilter) override;
582 bool IsValid() const override;
584 gfx::IntSize GetSize() const override { return mSize; }
586 gfx::SurfaceFormat GetFormat() const override { return mFormat; }
588 gfx::Matrix4x4 GetTextureTransform() override;
590 GLenum GetTextureTarget() const override { return mTextureTarget; }
592 GLenum GetWrapMode() const override { return mWrapMode; }
594 // We don't own anything.
595 void DeallocateDeviceData() override {}
597 gl::GLContext* gl() const { return mGL; }
599 protected:
600 RefPtr<gl::GLContext> mGL;
601 RefPtr<CompositorOGL> mCompositor;
602 const EGLImage mImage;
603 const gfx::SurfaceFormat mFormat;
604 const GLenum mTextureTarget;
605 const GLenum mWrapMode;
606 const gfx::IntSize mSize;
609 class EGLImageTextureHost final : public TextureHost {
610 public:
611 EGLImageTextureHost(TextureFlags aFlags, EGLImage aImage, EGLSync aSync,
612 gfx::IntSize aSize, bool hasAlpha);
614 virtual ~EGLImageTextureHost();
616 // We don't own anything.
617 void DeallocateDeviceData() override {}
619 gfx::SurfaceFormat GetFormat() const override;
621 already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
622 gfx::DataSourceSurface* aSurface) override {
623 return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
626 gl::GLContext* gl() const;
628 gfx::IntSize GetSize() const override { return mSize; }
630 const char* Name() override { return "EGLImageTextureHost"; }
632 void CreateRenderTexture(
633 const wr::ExternalImageId& aExternalImageId) override;
635 void PushResourceUpdates(wr::TransactionBuilder& aResources,
636 ResourceUpdateOp aOp,
637 const Range<wr::ImageKey>& aImageKeys,
638 const wr::ExternalImageId& aExtID) override;
640 void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
641 const wr::LayoutRect& aBounds,
642 const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
643 const Range<wr::ImageKey>& aImageKeys,
644 PushDisplayItemFlagSet aFlags) override;
646 bool SupportsExternalCompositing(WebRenderBackend aBackend) override;
648 protected:
649 const EGLImage mImage;
650 const EGLSync mSync;
651 const gfx::IntSize mSize;
652 const bool mHasAlpha;
653 RefPtr<EGLImageTextureSource> mTextureSource;
656 } // namespace layers
657 } // namespace mozilla
659 #endif /* MOZILLA_GFX_TEXTUREOGL_H */