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 : #include "TextureHostOGL.h"
7 :
8 : #include "EGLUtils.h"
9 : #include "GLContext.h" // for GLContext, etc
10 : #include "GLLibraryEGL.h" // for GLLibraryEGL
11 : #include "GLUploadHelpers.h"
12 : #include "GLReadTexImageHelper.h"
13 : #include "gfx2DGlue.h" // for ContentForFormat, etc
14 : #include "mozilla/gfx/2D.h" // for DataSourceSurface
15 : #include "mozilla/gfx/BaseSize.h" // for BaseSize
16 : #include "mozilla/gfx/Logging.h" // for gfxCriticalError
17 : #include "mozilla/layers/ISurfaceAllocator.h"
18 : #include "nsRegion.h" // for nsIntRegion
19 : #include "AndroidSurfaceTexture.h"
20 : #include "GfxTexturesReporter.h" // for GfxTexturesReporter
21 : #include "GLBlitTextureImageHelper.h"
22 : #include "GeckoProfiler.h"
23 :
24 : #ifdef XP_MACOSX
25 : #include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
26 : #endif
27 :
28 : #ifdef GL_PROVIDER_GLX
29 : #include "mozilla/layers/X11TextureHost.h"
30 : #endif
31 :
32 : using namespace mozilla::gl;
33 : using namespace mozilla::gfx;
34 :
35 : namespace mozilla {
36 : namespace layers {
37 :
38 : class Compositor;
39 :
40 : already_AddRefed<TextureHost>
41 0 : CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
42 : ISurfaceAllocator* aDeallocator,
43 : LayersBackend aBackend,
44 : TextureFlags aFlags)
45 : {
46 0 : RefPtr<TextureHost> result;
47 0 : switch (aDesc.type()) {
48 : case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
49 0 : result = CreateBackendIndependentTextureHost(aDesc,
50 : aDeallocator,
51 : aBackend,
52 0 : aFlags);
53 0 : break;
54 : }
55 :
56 : #ifdef MOZ_WIDGET_ANDROID
57 : case SurfaceDescriptor::TSurfaceTextureDescriptor: {
58 : const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor();
59 : java::GeckoSurfaceTexture::LocalRef surfaceTexture = java::GeckoSurfaceTexture::Lookup(desc.handle());
60 :
61 : result = new SurfaceTextureHost(aFlags,
62 : surfaceTexture,
63 : desc.size(),
64 : desc.continuous());
65 : break;
66 : }
67 : #endif
68 :
69 : case SurfaceDescriptor::TEGLImageDescriptor: {
70 0 : const EGLImageDescriptor& desc = aDesc.get_EGLImageDescriptor();
71 : result = new EGLImageTextureHost(aFlags,
72 0 : (EGLImage)desc.image(),
73 0 : (EGLSync)desc.fence(),
74 0 : desc.size(),
75 0 : desc.hasAlpha());
76 0 : break;
77 : }
78 :
79 : #ifdef XP_MACOSX
80 : case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
81 : const SurfaceDescriptorMacIOSurface& desc =
82 : aDesc.get_SurfaceDescriptorMacIOSurface();
83 : result = new MacIOSurfaceTextureHostOGL(aFlags, desc);
84 : break;
85 : }
86 : #endif
87 :
88 : #ifdef GL_PROVIDER_GLX
89 : case SurfaceDescriptor::TSurfaceDescriptorX11: {
90 0 : const auto& desc = aDesc.get_SurfaceDescriptorX11();
91 0 : result = new X11TextureHost(aFlags, desc);
92 0 : break;
93 : }
94 : #endif
95 :
96 : case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: {
97 0 : const auto& desc = aDesc.get_SurfaceDescriptorSharedGLTexture();
98 0 : result = new GLTextureHost(aFlags, desc.texture(),
99 0 : desc.target(),
100 0 : (GLsync)desc.fence(),
101 0 : desc.size(),
102 0 : desc.hasAlpha());
103 0 : break;
104 : }
105 0 : default: return nullptr;
106 : }
107 0 : return result.forget();
108 : }
109 :
110 : static gl::TextureImage::Flags
111 0 : FlagsToGLFlags(TextureFlags aFlags)
112 : {
113 0 : uint32_t result = TextureImage::NoFlags;
114 :
115 0 : if (aFlags & TextureFlags::USE_NEAREST_FILTER)
116 0 : result |= TextureImage::UseNearestFilter;
117 0 : if (aFlags & TextureFlags::ORIGIN_BOTTOM_LEFT)
118 0 : result |= TextureImage::OriginBottomLeft;
119 0 : if (aFlags & TextureFlags::DISALLOW_BIGIMAGE)
120 0 : result |= TextureImage::DisallowBigImage;
121 :
122 0 : return static_cast<gl::TextureImage::Flags>(result);
123 : }
124 :
125 : bool
126 0 : TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
127 : nsIntRegion* aDestRegion,
128 : gfx::IntPoint* aSrcOffset)
129 : {
130 0 : GLContext *gl = mGL;
131 0 : MOZ_ASSERT(gl);
132 0 : if (!gl || !gl->MakeCurrent()) {
133 0 : NS_WARNING("trying to update TextureImageTextureSourceOGL without a GLContext");
134 0 : return false;
135 : }
136 0 : if (!aSurface) {
137 0 : gfxCriticalError() << "Invalid surface for OGL update";
138 0 : return false;
139 : }
140 0 : MOZ_ASSERT(aSurface);
141 :
142 0 : IntSize size = aSurface->GetSize();
143 0 : if (!mTexImage ||
144 0 : (mTexImage->GetSize() != size && !aSrcOffset) ||
145 0 : mTexImage->GetContentType() != gfx::ContentForFormat(aSurface->GetFormat())) {
146 0 : if (mFlags & TextureFlags::DISALLOW_BIGIMAGE) {
147 : GLint maxTextureSize;
148 0 : gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTextureSize);
149 0 : if (size.width > maxTextureSize || size.height > maxTextureSize) {
150 0 : NS_WARNING("Texture exceeds maximum texture size, refusing upload");
151 0 : return false;
152 : }
153 : // Explicitly use CreateBasicTextureImage instead of CreateTextureImage,
154 : // because CreateTextureImage might still choose to create a tiled
155 : // texture image.
156 0 : mTexImage = CreateBasicTextureImage(gl, size,
157 0 : gfx::ContentForFormat(aSurface->GetFormat()),
158 : LOCAL_GL_CLAMP_TO_EDGE,
159 0 : FlagsToGLFlags(mFlags));
160 : } else {
161 : // XXX - clarify which size we want to use. IncrementalContentHost will
162 : // require the size of the destination surface to be different from
163 : // the size of aSurface.
164 : // See bug 893300 (tracks the implementation of ContentHost for new textures).
165 0 : mTexImage = CreateTextureImage(gl,
166 : size,
167 0 : gfx::ContentForFormat(aSurface->GetFormat()),
168 : LOCAL_GL_CLAMP_TO_EDGE,
169 : FlagsToGLFlags(mFlags),
170 0 : SurfaceFormatToImageFormat(aSurface->GetFormat()));
171 : }
172 0 : ClearCachedFilter();
173 :
174 0 : if (aDestRegion &&
175 0 : !aSrcOffset &&
176 0 : !aDestRegion->IsEqual(gfx::IntRect(0, 0, size.width, size.height))) {
177 : // UpdateFromDataSource will ignore our specified aDestRegion since the texture
178 : // hasn't been allocated with glTexImage2D yet. Call Resize() to force the
179 : // allocation (full size, but no upload), and then we'll only upload the pixels
180 : // we care about below.
181 0 : mTexImage->Resize(size);
182 : }
183 : }
184 :
185 0 : mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset);
186 :
187 0 : return true;
188 : }
189 :
190 : void
191 0 : TextureImageTextureSourceOGL::EnsureBuffer(const IntSize& aSize,
192 : gfxContentType aContentType)
193 : {
194 0 : if (!mTexImage ||
195 0 : mTexImage->GetSize() != aSize ||
196 0 : mTexImage->GetContentType() != aContentType) {
197 0 : mTexImage = CreateTextureImage(mGL,
198 : aSize,
199 : aContentType,
200 : LOCAL_GL_CLAMP_TO_EDGE,
201 0 : FlagsToGLFlags(mFlags));
202 : }
203 0 : mTexImage->Resize(aSize);
204 0 : }
205 :
206 : void
207 0 : TextureImageTextureSourceOGL::SetTextureSourceProvider(TextureSourceProvider* aProvider)
208 : {
209 0 : GLContext* newGL = aProvider ? aProvider->GetGLContext() : nullptr;
210 0 : if (!newGL || mGL != newGL) {
211 0 : DeallocateDeviceData();
212 : }
213 0 : mGL = newGL;
214 0 : }
215 :
216 : gfx::IntSize
217 0 : TextureImageTextureSourceOGL::GetSize() const
218 : {
219 0 : if (mTexImage) {
220 0 : if (mIterating) {
221 0 : return mTexImage->GetTileRect().Size();
222 : }
223 0 : return mTexImage->GetSize();
224 : }
225 0 : NS_WARNING("Trying to query the size of an empty TextureSource.");
226 0 : return gfx::IntSize(0, 0);
227 : }
228 :
229 : gfx::SurfaceFormat
230 0 : TextureImageTextureSourceOGL::GetFormat() const
231 : {
232 0 : if (mTexImage) {
233 0 : return mTexImage->GetTextureFormat();
234 : }
235 0 : NS_WARNING("Trying to query the format of an empty TextureSource.");
236 0 : return gfx::SurfaceFormat::UNKNOWN;
237 : }
238 :
239 0 : gfx::IntRect TextureImageTextureSourceOGL::GetTileRect()
240 : {
241 0 : return mTexImage->GetTileRect();
242 : }
243 :
244 : void
245 0 : TextureImageTextureSourceOGL::BindTexture(GLenum aTextureUnit,
246 : gfx::SamplingFilter aSamplingFilter)
247 : {
248 0 : MOZ_ASSERT(mTexImage,
249 : "Trying to bind a TextureSource that does not have an underlying GL texture.");
250 0 : mTexImage->BindTexture(aTextureUnit);
251 0 : SetSamplingFilter(mGL, aSamplingFilter);
252 0 : }
253 :
254 : ////////////////////////////////////////////////////////////////////////
255 : // GLTextureSource
256 :
257 0 : GLTextureSource::GLTextureSource(TextureSourceProvider* aProvider,
258 : GLuint aTextureHandle,
259 : GLenum aTarget,
260 : gfx::IntSize aSize,
261 : gfx::SurfaceFormat aFormat,
262 0 : bool aExternallyOwned)
263 0 : : mGL(aProvider->GetGLContext())
264 : , mTextureHandle(aTextureHandle)
265 : , mTextureTarget(aTarget)
266 : , mSize(aSize)
267 : , mFormat(aFormat)
268 0 : , mExternallyOwned(aExternallyOwned)
269 : {
270 0 : MOZ_COUNT_CTOR(GLTextureSource);
271 0 : }
272 :
273 0 : GLTextureSource::~GLTextureSource()
274 : {
275 0 : MOZ_COUNT_DTOR(GLTextureSource);
276 0 : if (!mExternallyOwned) {
277 0 : DeleteTextureHandle();
278 : }
279 0 : }
280 :
281 : void
282 0 : GLTextureSource::DeallocateDeviceData()
283 : {
284 0 : if (!mExternallyOwned) {
285 0 : DeleteTextureHandle();
286 : }
287 0 : }
288 :
289 : void
290 0 : GLTextureSource::DeleteTextureHandle()
291 : {
292 0 : GLContext* gl = this->gl();
293 0 : if (mTextureHandle != 0 && gl && gl->MakeCurrent()) {
294 0 : gl->fDeleteTextures(1, &mTextureHandle);
295 : }
296 0 : mTextureHandle = 0;
297 0 : }
298 :
299 : void
300 0 : GLTextureSource::BindTexture(GLenum aTextureUnit,
301 : gfx::SamplingFilter aSamplingFilter)
302 : {
303 0 : MOZ_ASSERT(mTextureHandle != 0);
304 0 : GLContext* gl = this->gl();
305 0 : if (!gl || !gl->MakeCurrent()) {
306 0 : return;
307 : }
308 0 : gl->fActiveTexture(aTextureUnit);
309 0 : gl->fBindTexture(mTextureTarget, mTextureHandle);
310 0 : ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
311 : }
312 :
313 : void
314 0 : GLTextureSource::SetTextureSourceProvider(TextureSourceProvider* aProvider)
315 : {
316 0 : GLContext* newGL = aProvider ? aProvider->GetGLContext() : nullptr;
317 0 : if (!newGL) {
318 0 : mGL = newGL;
319 0 : } else if (mGL != newGL) {
320 0 : gfxCriticalError() << "GLTextureSource does not support changing compositors";
321 : }
322 :
323 0 : if (mNextSibling) {
324 0 : mNextSibling->SetTextureSourceProvider(aProvider);
325 : }
326 0 : }
327 :
328 : bool
329 0 : GLTextureSource::IsValid() const
330 : {
331 0 : return !!gl() && mTextureHandle != 0;
332 : }
333 :
334 : ////////////////////////////////////////////////////////////////////////
335 : ////////////////////////////////////////////////////////////////////////
336 : // SurfaceTextureHost
337 :
338 : #ifdef MOZ_WIDGET_ANDROID
339 :
340 : SurfaceTextureSource::SurfaceTextureSource(TextureSourceProvider* aProvider,
341 : mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
342 : gfx::SurfaceFormat aFormat,
343 : GLenum aTarget,
344 : GLenum aWrapMode,
345 : gfx::IntSize aSize)
346 : : mGL(aProvider->GetGLContext())
347 : , mSurfTex(aSurfTex)
348 : , mFormat(aFormat)
349 : , mTextureTarget(aTarget)
350 : , mWrapMode(aWrapMode)
351 : , mSize(aSize)
352 : {
353 : }
354 :
355 : void
356 : SurfaceTextureSource::BindTexture(GLenum aTextureUnit,
357 : gfx::SamplingFilter aSamplingFilter)
358 : {
359 : MOZ_ASSERT(mSurfTex);
360 : GLContext* gl = this->gl();
361 : if (!gl || !gl->MakeCurrent()) {
362 : NS_WARNING("Trying to bind a texture without a GLContext");
363 : return;
364 : }
365 :
366 : gl->fActiveTexture(aTextureUnit);
367 : gl->fBindTexture(mTextureTarget, mSurfTex->GetTexName());
368 :
369 : ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
370 : }
371 :
372 : void
373 : SurfaceTextureSource::SetTextureSourceProvider(TextureSourceProvider* aProvider)
374 : {
375 : GLContext* newGL = aProvider->GetGLContext();
376 : if (!newGL || mGL != newGL) {
377 : DeallocateDeviceData();
378 : return;
379 : }
380 :
381 : mGL = newGL;
382 : }
383 :
384 : bool
385 : SurfaceTextureSource::IsValid() const
386 : {
387 : return !!gl();
388 : }
389 :
390 : gfx::Matrix4x4
391 : SurfaceTextureSource::GetTextureTransform()
392 : {
393 : MOZ_ASSERT(mSurfTex);
394 :
395 : gfx::Matrix4x4 ret;
396 :
397 : const auto& surf = java::sdk::SurfaceTexture::LocalRef(java::sdk::SurfaceTexture::Ref::From(mSurfTex));
398 : AndroidSurfaceTexture::GetTransformMatrix(surf, ret);
399 :
400 : return ret;
401 : }
402 :
403 : void
404 : SurfaceTextureSource::DeallocateDeviceData()
405 : {
406 : mSurfTex = nullptr;
407 : }
408 :
409 : ////////////////////////////////////////////////////////////////////////
410 :
411 : SurfaceTextureHost::SurfaceTextureHost(TextureFlags aFlags,
412 : mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
413 : gfx::IntSize aSize,
414 : bool aContinuousUpdate)
415 : : TextureHost(aFlags)
416 : , mSurfTex(aSurfTex)
417 : , mSize(aSize)
418 : , mContinuousUpdate(aContinuousUpdate)
419 : {
420 : if (!mSurfTex) {
421 : return;
422 : }
423 :
424 : // Continuous update makes no sense with single buffer mode
425 : MOZ_ASSERT(!mSurfTex->IsSingleBuffer() || !mContinuousUpdate);
426 :
427 : mSurfTex->IncrementUse();
428 : }
429 :
430 : SurfaceTextureHost::~SurfaceTextureHost()
431 : {
432 : if (mSurfTex) {
433 : mSurfTex->DecrementUse();
434 : mSurfTex = nullptr;
435 : }
436 : }
437 :
438 : void
439 : SurfaceTextureHost::PrepareTextureSource(CompositableTextureSourceRef& aTexture)
440 : {
441 : GLContext* gl = this->gl();
442 : if (!gl || !gl->MakeCurrent()) {
443 : return;
444 : }
445 :
446 : if (!mContinuousUpdate && mSurfTex) {
447 : // UpdateTexImage() advances the internal buffer queue, so we only want to call this
448 : // once per transactionwhen we are not in continuous mode (as we are here). Otherwise,
449 : // the SurfaceTexture content will be de-synced from the rest of the page in subsequent
450 : // compositor passes.
451 : mSurfTex->UpdateTexImage();
452 : }
453 : }
454 :
455 : gl::GLContext*
456 : SurfaceTextureHost::gl() const
457 : {
458 : return mProvider ? mProvider->GetGLContext() : nullptr;
459 : }
460 :
461 : bool
462 : SurfaceTextureHost::Lock()
463 : {
464 : if (!mSurfTex) {
465 : return false;
466 : }
467 :
468 : GLContext* gl = this->gl();
469 : if (!gl || !gl->MakeCurrent()) {
470 : return false;
471 : }
472 :
473 : if (mContinuousUpdate) {
474 : mSurfTex->UpdateTexImage();
475 : }
476 :
477 : if (!mTextureSource) {
478 : gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
479 : GLenum target = LOCAL_GL_TEXTURE_EXTERNAL; // This is required by SurfaceTexture
480 : GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
481 : mTextureSource = new SurfaceTextureSource(mProvider,
482 : mSurfTex,
483 : format,
484 : target,
485 : wrapMode,
486 : mSize);
487 : }
488 :
489 : return true;
490 : }
491 :
492 : void
493 : SurfaceTextureHost::SetTextureSourceProvider(TextureSourceProvider* aProvider)
494 : {
495 : if (mProvider != aProvider) {
496 : if (!aProvider || !aProvider->GetGLContext()) {
497 : DeallocateDeviceData();
498 : return;
499 : }
500 : mProvider = aProvider;
501 : }
502 :
503 : if (mTextureSource) {
504 : mTextureSource->SetTextureSourceProvider(aProvider);
505 : }
506 : }
507 :
508 : void
509 : SurfaceTextureHost::NotifyNotUsed()
510 : {
511 : if (mSurfTex && mSurfTex->IsSingleBuffer()) {
512 : mSurfTex->ReleaseTexImage();
513 : }
514 :
515 : TextureHost::NotifyNotUsed();
516 : }
517 :
518 : gfx::SurfaceFormat
519 : SurfaceTextureHost::GetFormat() const
520 : {
521 : return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN;
522 : }
523 :
524 : void
525 : SurfaceTextureHost::DeallocateDeviceData()
526 : {
527 : if (mTextureSource) {
528 : mTextureSource->DeallocateDeviceData();
529 : }
530 :
531 : if (mSurfTex) {
532 : mSurfTex->DecrementUse();
533 : mSurfTex = nullptr;
534 : }
535 : }
536 :
537 : #endif // MOZ_WIDGET_ANDROID
538 :
539 : ////////////////////////////////////////////////////////////////////////
540 : ////////////////////////////////////////////////////////////////////////
541 : // EGLImage
542 :
543 0 : EGLImageTextureSource::EGLImageTextureSource(TextureSourceProvider* aProvider,
544 : EGLImage aImage,
545 : gfx::SurfaceFormat aFormat,
546 : GLenum aTarget,
547 : GLenum aWrapMode,
548 0 : gfx::IntSize aSize)
549 : : mImage(aImage)
550 : , mFormat(aFormat)
551 : , mTextureTarget(aTarget)
552 : , mWrapMode(aWrapMode)
553 0 : , mSize(aSize)
554 : {
555 0 : MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D ||
556 : mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL);
557 0 : SetTextureSourceProvider(aProvider);
558 0 : }
559 :
560 : void
561 0 : EGLImageTextureSource::BindTexture(GLenum aTextureUnit,
562 : gfx::SamplingFilter aSamplingFilter)
563 : {
564 0 : GLContext* gl = this->gl();
565 0 : if (!gl || !gl->MakeCurrent()) {
566 0 : NS_WARNING("Trying to bind a texture without a GLContext");
567 0 : return;
568 : }
569 :
570 0 : MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl),
571 : "EGLImage not supported or disabled in runtime");
572 :
573 0 : GLuint tex = mCompositor->GetTemporaryTexture(mTextureTarget, aTextureUnit);
574 :
575 0 : gl->fActiveTexture(aTextureUnit);
576 0 : gl->fBindTexture(mTextureTarget, tex);
577 :
578 0 : gl->fEGLImageTargetTexture2D(mTextureTarget, mImage);
579 :
580 0 : ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
581 : }
582 :
583 : void
584 0 : EGLImageTextureSource::SetTextureSourceProvider(TextureSourceProvider* aProvider)
585 : {
586 0 : if (mCompositor == aProvider) {
587 0 : return;
588 : }
589 :
590 0 : if (!aProvider) {
591 0 : mGL = nullptr;
592 0 : mCompositor = nullptr;
593 0 : return;
594 : }
595 :
596 0 : mGL = aProvider->GetGLContext();
597 0 : if (Compositor* compositor = aProvider->AsCompositor()) {
598 0 : mCompositor = compositor->AsCompositorOGL();
599 : }
600 : }
601 :
602 : bool
603 0 : EGLImageTextureSource::IsValid() const
604 : {
605 0 : return !!gl();
606 : }
607 :
608 : gfx::Matrix4x4
609 0 : EGLImageTextureSource::GetTextureTransform()
610 : {
611 0 : gfx::Matrix4x4 ret;
612 0 : return ret;
613 : }
614 :
615 : ////////////////////////////////////////////////////////////////////////
616 :
617 0 : EGLImageTextureHost::EGLImageTextureHost(TextureFlags aFlags,
618 : EGLImage aImage,
619 : EGLSync aSync,
620 : gfx::IntSize aSize,
621 0 : bool hasAlpha)
622 : : TextureHost(aFlags)
623 : , mImage(aImage)
624 : , mSync(aSync)
625 : , mSize(aSize)
626 0 : , mHasAlpha(hasAlpha)
627 0 : {}
628 :
629 0 : EGLImageTextureHost::~EGLImageTextureHost()
630 0 : {}
631 :
632 : gl::GLContext*
633 0 : EGLImageTextureHost::gl() const
634 : {
635 0 : return mProvider ? mProvider ->GetGLContext() : nullptr;
636 : }
637 :
638 : bool
639 0 : EGLImageTextureHost::Lock()
640 : {
641 0 : GLContext* gl = this->gl();
642 0 : if (!gl || !gl->MakeCurrent()) {
643 0 : return false;
644 : }
645 :
646 0 : EGLint status = LOCAL_EGL_CONDITION_SATISFIED;
647 :
648 0 : if (mSync) {
649 0 : MOZ_ASSERT(sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
650 0 : status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
651 : }
652 :
653 0 : if (status != LOCAL_EGL_CONDITION_SATISFIED) {
654 0 : MOZ_ASSERT(status != 0,
655 : "ClientWaitSync generated an error. Has mSync already been destroyed?");
656 0 : return false;
657 : }
658 :
659 0 : if (!mTextureSource) {
660 0 : gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
661 0 : : gfx::SurfaceFormat::R8G8B8X8;
662 0 : GLenum target = gl->GetPreferredEGLImageTextureTarget();
663 0 : GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
664 : mTextureSource = new EGLImageTextureSource(mProvider,
665 0 : mImage,
666 : format,
667 : target,
668 : wrapMode,
669 0 : mSize);
670 : }
671 :
672 0 : return true;
673 : }
674 :
675 : void
676 0 : EGLImageTextureHost::Unlock()
677 : {
678 0 : }
679 :
680 : void
681 0 : EGLImageTextureHost::SetTextureSourceProvider(TextureSourceProvider* aProvider)
682 : {
683 0 : if (mProvider != aProvider) {
684 0 : if (!aProvider || !aProvider->GetGLContext()) {
685 0 : mProvider = nullptr;
686 0 : mTextureSource = nullptr;
687 0 : return;
688 : }
689 0 : mProvider = aProvider;
690 : }
691 :
692 0 : if (mTextureSource) {
693 0 : mTextureSource->SetTextureSourceProvider(aProvider);
694 : }
695 : }
696 :
697 : gfx::SurfaceFormat
698 0 : EGLImageTextureHost::GetFormat() const
699 : {
700 0 : MOZ_ASSERT(mTextureSource);
701 0 : return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN;
702 : }
703 :
704 : //
705 :
706 0 : GLTextureHost::GLTextureHost(TextureFlags aFlags,
707 : GLuint aTextureHandle,
708 : GLenum aTarget,
709 : GLsync aSync,
710 : gfx::IntSize aSize,
711 0 : bool aHasAlpha)
712 : : TextureHost(aFlags)
713 : , mTexture(aTextureHandle)
714 : , mTarget(aTarget)
715 : , mSync(aSync)
716 : , mSize(aSize)
717 0 : , mHasAlpha(aHasAlpha)
718 0 : {}
719 :
720 0 : GLTextureHost::~GLTextureHost()
721 0 : {}
722 :
723 : gl::GLContext*
724 0 : GLTextureHost::gl() const
725 : {
726 0 : return mProvider ? mProvider->GetGLContext() : nullptr;
727 : }
728 :
729 : bool
730 0 : GLTextureHost::Lock()
731 : {
732 0 : GLContext* gl = this->gl();
733 0 : if (!gl || !gl->MakeCurrent()) {
734 0 : return false;
735 : }
736 :
737 0 : if (mSync) {
738 0 : if (!gl->MakeCurrent()) {
739 0 : return false;
740 : }
741 0 : gl->fWaitSync(mSync, 0, LOCAL_GL_TIMEOUT_IGNORED);
742 0 : gl->fDeleteSync(mSync);
743 0 : mSync = 0;
744 : }
745 :
746 0 : if (!mTextureSource) {
747 0 : gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
748 0 : : gfx::SurfaceFormat::R8G8B8X8;
749 : mTextureSource = new GLTextureSource(mProvider,
750 0 : mTexture,
751 0 : mTarget,
752 0 : mSize,
753 : format,
754 0 : false /* owned by the client */);
755 : }
756 :
757 0 : return true;
758 : }
759 :
760 : void
761 0 : GLTextureHost::SetTextureSourceProvider(TextureSourceProvider* aProvider)
762 : {
763 0 : if (mProvider != aProvider) {
764 0 : if (!aProvider || !aProvider->GetGLContext()) {
765 0 : mProvider = nullptr;
766 0 : mTextureSource = nullptr;
767 0 : return;
768 : }
769 0 : mProvider = aProvider;
770 : }
771 :
772 0 : if (mTextureSource) {
773 0 : mTextureSource->SetTextureSourceProvider(aProvider);
774 : }
775 : }
776 :
777 : gfx::SurfaceFormat
778 0 : GLTextureHost::GetFormat() const
779 : {
780 0 : MOZ_ASSERT(mTextureSource);
781 0 : return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN;
782 : }
783 :
784 : } // namespace layers
785 : } // namespace mozilla
|