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
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"
42 class DataSourceSurface
;
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.
78 * TextureSourceOGL provides the necessary API for CompositorOGL to composite
81 class 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() {
114 virtual GLTextureSource
* AsGLTextureSource() { return nullptr; }
116 void SetSamplingFilter(gl::GLContext
* aGL
,
117 gfx::SamplingFilter aSamplingFilter
) {
118 if (mHasCachedSamplingFilter
&& mCachedSamplingFilter
== aSamplingFilter
) {
121 mHasCachedSamplingFilter
= true;
122 mCachedSamplingFilter
= aSamplingFilter
;
123 ApplySamplingFilterToBoundTexture(aGL
, aSamplingFilter
, GetTextureTarget());
126 void ClearCachedFilter() { mHasCachedSamplingFilter
= false; }
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
142 class TextureImageTextureSourceOGL final
: public DataTextureSource
,
143 public TextureSourceOGL
,
144 public BigImageIterator
{
146 explicit TextureImageTextureSourceOGL(
147 CompositorOGL
* aCompositor
, TextureFlags aFlags
= TextureFlags::DEFAULT
);
149 const char* Name() const override
{ return "TextureImageTextureSourceOGL"; }
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
{
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(); }
182 BigImageIterator
* AsBigImageIterator() override
{ return this; }
184 void BeginBigImageIteration() override
{
185 mTexImage
->BeginBigImageIteration();
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
; }
200 ~TextureImageTextureSourceOGL();
202 RefPtr
<gl::TextureImage
> mTexImage
;
203 RefPtr
<gl::GLContext
> mGL
;
204 RefPtr
<CompositorOGL
> mCompositor
;
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
{
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
{
265 void DeleteTextureHandle();
267 RefPtr
<gl::GLContext
> mGL
;
268 RefPtr
<CompositorOGL
> mCompositor
;
269 GLuint mTextureHandle
;
270 GLenum mTextureTarget
;
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
{
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
296 bool Sync(bool aBlocking
) override
;
298 void MaybeFenceTexture() override
;
301 bool UpdateInternal(gfx::DataSourceSurface
* aSurface
,
302 nsIntRegion
* aDestRegion
, gfx::IntPoint
* aSrcOffset
,
308 class GLTextureHost
: public TextureHost
{
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"; }
332 const GLuint mTexture
;
333 const GLenum mTarget
;
335 const gfx::IntSize mSize
;
336 const bool mHasAlpha
;
337 RefPtr
<GLTextureSource
> mTextureSource
;
340 ////////////////////////////////////////////////////////////////////////
343 #ifdef MOZ_WIDGET_ANDROID
345 class SurfaceTextureSource
: public TextureSource
, public TextureSourceOGL
{
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
; }
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
{
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; }
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
{
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
; }
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
;
493 GLuint mTextureHandle
;
496 class AndroidHardwareBufferTextureHost
: public TextureHost
{
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()
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; }
561 RefPtr
<AndroidHardwareBuffer
> mAndroidHardwareBuffer
;
564 #endif // MOZ_WIDGET_ANDROID
566 ////////////////////////////////////////////////////////////////////////
569 class EGLImageTextureSource
: public TextureSource
, public TextureSourceOGL
{
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
; }
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
{
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
;
649 const EGLImage mImage
;
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 */