michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "TextureHostOGL.h" michael@0: #include "GLContext.h" // for GLContext, etc michael@0: #include "GLSharedHandleHelpers.h" michael@0: #include "GLUploadHelpers.h" michael@0: #include "GLReadTexImageHelper.h" michael@0: #include "SharedSurface.h" // for SharedSurface michael@0: #include "SharedSurfaceEGL.h" // for SharedSurface_EGLImage michael@0: #include "SharedSurfaceGL.h" // for SharedSurface_GLTexture, etc michael@0: #include "SurfaceStream.h" // for SurfaceStream michael@0: #include "SurfaceTypes.h" // for SharedSurfaceType, etc michael@0: #include "gfx2DGlue.h" // for ContentForFormat, etc michael@0: #include "gfxReusableSurfaceWrapper.h" // for gfxReusableSurfaceWrapper michael@0: #include "mozilla/gfx/2D.h" // for DataSourceSurface michael@0: #include "mozilla/gfx/BaseSize.h" // for BaseSize michael@0: #include "mozilla/layers/CompositorOGL.h" // for CompositorOGL michael@0: #ifdef MOZ_WIDGET_GONK michael@0: # include "GrallocImages.h" // for GrallocImage michael@0: # include "EGLImageHelpers.h" michael@0: #endif michael@0: #include "mozilla/layers/ISurfaceAllocator.h" michael@0: #include "mozilla/layers/YCbCrImageDataSerializer.h" michael@0: #include "mozilla/layers/GrallocTextureHost.h" michael@0: #include "nsPoint.h" // for nsIntPoint michael@0: #include "nsRegion.h" // for nsIntRegion michael@0: #include "GfxTexturesReporter.h" // for GfxTexturesReporter michael@0: #include "GLBlitTextureImageHelper.h" michael@0: #ifdef XP_MACOSX michael@0: #include "SharedSurfaceIO.h" michael@0: #include "mozilla/layers/MacIOSurfaceTextureHostOGL.h" michael@0: #endif michael@0: #include "GeckoProfiler.h" michael@0: michael@0: using namespace mozilla::gl; michael@0: using namespace mozilla::gfx; michael@0: michael@0: namespace mozilla { michael@0: namespace layers { michael@0: michael@0: class Compositor; michael@0: michael@0: TemporaryRef michael@0: CreateCompositableBackendSpecificDataOGL() michael@0: { michael@0: #ifdef MOZ_WIDGET_GONK michael@0: return new CompositableDataGonkOGL(); michael@0: #else michael@0: return nullptr; michael@0: #endif michael@0: } michael@0: michael@0: TemporaryRef michael@0: CreateTextureHostOGL(const SurfaceDescriptor& aDesc, michael@0: ISurfaceAllocator* aDeallocator, michael@0: TextureFlags aFlags) michael@0: { michael@0: RefPtr result; michael@0: switch (aDesc.type()) { michael@0: case SurfaceDescriptor::TSurfaceDescriptorShmem: michael@0: case SurfaceDescriptor::TSurfaceDescriptorMemory: { michael@0: result = CreateBackendIndependentTextureHost(aDesc, michael@0: aDeallocator, aFlags); michael@0: break; michael@0: } michael@0: case SurfaceDescriptor::TSharedTextureDescriptor: { michael@0: const SharedTextureDescriptor& desc = aDesc.get_SharedTextureDescriptor(); michael@0: result = new SharedTextureHostOGL(aFlags, michael@0: desc.shareType(), michael@0: desc.handle(), michael@0: desc.size(), michael@0: desc.inverted()); michael@0: break; michael@0: } michael@0: case SurfaceDescriptor::TSurfaceStreamDescriptor: { michael@0: const SurfaceStreamDescriptor& desc = aDesc.get_SurfaceStreamDescriptor(); michael@0: result = new StreamTextureHostOGL(aFlags, desc); michael@0: break; michael@0: } michael@0: #ifdef XP_MACOSX michael@0: case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: { michael@0: const SurfaceDescriptorMacIOSurface& desc = michael@0: aDesc.get_SurfaceDescriptorMacIOSurface(); michael@0: result = new MacIOSurfaceTextureHostOGL(aFlags, desc); michael@0: break; michael@0: } michael@0: #endif michael@0: #ifdef MOZ_WIDGET_GONK michael@0: case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: { michael@0: const NewSurfaceDescriptorGralloc& desc = michael@0: aDesc.get_NewSurfaceDescriptorGralloc(); michael@0: result = new GrallocTextureHostOGL(aFlags, desc); michael@0: break; michael@0: } michael@0: #endif michael@0: default: return nullptr; michael@0: } michael@0: return result.forget(); michael@0: } michael@0: michael@0: static gl::TextureImage::Flags michael@0: FlagsToGLFlags(TextureFlags aFlags) michael@0: { michael@0: uint32_t result = TextureImage::NoFlags; michael@0: michael@0: if (aFlags & TEXTURE_USE_NEAREST_FILTER) michael@0: result |= TextureImage::UseNearestFilter; michael@0: if (aFlags & TEXTURE_NEEDS_Y_FLIP) michael@0: result |= TextureImage::NeedsYFlip; michael@0: if (aFlags & TEXTURE_DISALLOW_BIGIMAGE) michael@0: result |= TextureImage::DisallowBigImage; michael@0: michael@0: return static_cast(result); michael@0: } michael@0: michael@0: GLenum michael@0: WrapMode(gl::GLContext *aGl, bool aAllowRepeat) michael@0: { michael@0: if (aAllowRepeat && michael@0: (aGl->IsExtensionSupported(GLContext::ARB_texture_non_power_of_two) || michael@0: aGl->IsExtensionSupported(GLContext::OES_texture_npot))) { michael@0: return LOCAL_GL_REPEAT; michael@0: } michael@0: return LOCAL_GL_CLAMP_TO_EDGE; michael@0: } michael@0: michael@0: CompositableDataGonkOGL::CompositableDataGonkOGL() michael@0: : mTexture(0) michael@0: { michael@0: } michael@0: CompositableDataGonkOGL::~CompositableDataGonkOGL() michael@0: { michael@0: DeleteTextureIfPresent(); michael@0: } michael@0: michael@0: gl::GLContext* michael@0: CompositableDataGonkOGL::gl() const michael@0: { michael@0: return mCompositor ? mCompositor->gl() : nullptr; michael@0: } michael@0: michael@0: void CompositableDataGonkOGL::SetCompositor(Compositor* aCompositor) michael@0: { michael@0: mCompositor = static_cast(aCompositor); michael@0: } michael@0: michael@0: void CompositableDataGonkOGL::ClearData() michael@0: { michael@0: CompositableBackendSpecificData::ClearData(); michael@0: DeleteTextureIfPresent(); michael@0: } michael@0: michael@0: GLuint CompositableDataGonkOGL::GetTexture() michael@0: { michael@0: if (!mTexture) { michael@0: if (gl()->MakeCurrent()) { michael@0: gl()->fGenTextures(1, &mTexture); michael@0: } michael@0: } michael@0: return mTexture; michael@0: } michael@0: michael@0: void michael@0: CompositableDataGonkOGL::DeleteTextureIfPresent() michael@0: { michael@0: if (mTexture) { michael@0: if (gl()->MakeCurrent()) { michael@0: gl()->fDeleteTextures(1, &mTexture); michael@0: } michael@0: mTexture = 0; michael@0: } michael@0: } michael@0: michael@0: #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 michael@0: bool michael@0: TextureHostOGL::SetReleaseFence(const android::sp& aReleaseFence) michael@0: { michael@0: if (!aReleaseFence.get() || !aReleaseFence->isValid()) { michael@0: // HWC might not provide Fence. michael@0: // In this case, HWC implicitly handles buffer's fence. michael@0: return false; michael@0: } michael@0: michael@0: if (!mReleaseFence.get()) { michael@0: mReleaseFence = aReleaseFence; michael@0: } else { michael@0: android::sp mergedFence = android::Fence::merge( michael@0: android::String8::format("TextureHostOGL"), michael@0: mReleaseFence, aReleaseFence); michael@0: if (!mergedFence.get()) { michael@0: // synchronization is broken, the best we can do is hope fences michael@0: // signal in order so the new fence will act like a union. michael@0: // This error handling is same as android::ConsumerBase does. michael@0: mReleaseFence = aReleaseFence; michael@0: return false; michael@0: } michael@0: mReleaseFence = mergedFence; michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: android::sp michael@0: TextureHostOGL::GetAndResetReleaseFence() michael@0: { michael@0: // Hold previous ReleaseFence to prevent Fence delivery failure via gecko IPC. michael@0: mPrevReleaseFence = mReleaseFence; michael@0: // Reset current ReleaseFence. michael@0: mReleaseFence = android::Fence::NO_FENCE; michael@0: return mPrevReleaseFence; michael@0: } michael@0: #endif michael@0: michael@0: bool michael@0: TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, michael@0: nsIntRegion* aDestRegion, michael@0: gfx::IntPoint* aSrcOffset) michael@0: { michael@0: MOZ_ASSERT(mGL); michael@0: if (!mGL) { michael@0: NS_WARNING("trying to update TextureImageTextureSourceOGL without a GLContext"); michael@0: return false; michael@0: } michael@0: MOZ_ASSERT(aSurface); michael@0: michael@0: IntSize size = aSurface->GetSize(); michael@0: if (!mTexImage || michael@0: (mTexImage->GetSize() != size && !aSrcOffset) || michael@0: mTexImage->GetContentType() != gfx::ContentForFormat(aSurface->GetFormat())) { michael@0: if (mFlags & TEXTURE_DISALLOW_BIGIMAGE) { michael@0: mTexImage = CreateBasicTextureImage(mGL, size, michael@0: gfx::ContentForFormat(aSurface->GetFormat()), michael@0: WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), michael@0: FlagsToGLFlags(mFlags), michael@0: SurfaceFormatToImageFormat(aSurface->GetFormat())); michael@0: } else { michael@0: // XXX - clarify which size we want to use. IncrementalContentHost will michael@0: // require the size of the destination surface to be different from michael@0: // the size of aSurface. michael@0: // See bug 893300 (tracks the implementation of ContentHost for new textures). michael@0: mTexImage = CreateTextureImage(mGL, michael@0: size, michael@0: gfx::ContentForFormat(aSurface->GetFormat()), michael@0: WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), michael@0: FlagsToGLFlags(mFlags), michael@0: SurfaceFormatToImageFormat(aSurface->GetFormat())); michael@0: } michael@0: ClearCachedFilter(); michael@0: } michael@0: michael@0: mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset); michael@0: michael@0: if (mTexImage->InUpdate()) { michael@0: mTexImage->EndUpdate(); michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: void michael@0: TextureImageTextureSourceOGL::EnsureBuffer(const nsIntSize& aSize, michael@0: gfxContentType aContentType) michael@0: { michael@0: if (!mTexImage || michael@0: mTexImage->GetSize() != aSize.ToIntSize() || michael@0: mTexImage->GetContentType() != aContentType) { michael@0: mTexImage = CreateTextureImage(mGL, michael@0: aSize.ToIntSize(), michael@0: aContentType, michael@0: WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT), michael@0: FlagsToGLFlags(mFlags)); michael@0: } michael@0: mTexImage->Resize(aSize.ToIntSize()); michael@0: } michael@0: michael@0: void michael@0: TextureImageTextureSourceOGL::CopyTo(const nsIntRect& aSourceRect, michael@0: DataTextureSource *aDest, michael@0: const nsIntRect& aDestRect) michael@0: { michael@0: MOZ_ASSERT(aDest->AsSourceOGL(), "Incompatible destination type!"); michael@0: TextureImageTextureSourceOGL *dest = michael@0: aDest->AsSourceOGL()->AsTextureImageTextureSource(); michael@0: MOZ_ASSERT(dest, "Incompatible destination type!"); michael@0: michael@0: mGL->BlitTextureImageHelper()->BlitTextureImage(mTexImage, aSourceRect, michael@0: dest->mTexImage, aDestRect); michael@0: dest->mTexImage->MarkValid(); michael@0: } michael@0: michael@0: void michael@0: TextureImageTextureSourceOGL::SetCompositor(Compositor* aCompositor) michael@0: { michael@0: CompositorOGL* glCompositor = static_cast(aCompositor); michael@0: michael@0: if (!glCompositor || (mGL != glCompositor->gl())) { michael@0: DeallocateDeviceData(); michael@0: mGL = glCompositor ? glCompositor->gl() : nullptr; michael@0: } michael@0: } michael@0: michael@0: gfx::IntSize michael@0: TextureImageTextureSourceOGL::GetSize() const michael@0: { michael@0: if (mTexImage) { michael@0: if (mIterating) { michael@0: return mTexImage->GetTileRect().Size(); michael@0: } michael@0: return mTexImage->GetSize(); michael@0: } michael@0: NS_WARNING("Trying to query the size of an empty TextureSource."); michael@0: return gfx::IntSize(0, 0); michael@0: } michael@0: michael@0: gfx::SurfaceFormat michael@0: TextureImageTextureSourceOGL::GetFormat() const michael@0: { michael@0: if (mTexImage) { michael@0: return mTexImage->GetTextureFormat(); michael@0: } michael@0: NS_WARNING("Trying to query the format of an empty TextureSource."); michael@0: return gfx::SurfaceFormat::UNKNOWN; michael@0: } michael@0: michael@0: nsIntRect TextureImageTextureSourceOGL::GetTileRect() michael@0: { michael@0: return ThebesIntRect(mTexImage->GetTileRect()); michael@0: } michael@0: michael@0: void michael@0: TextureImageTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) michael@0: { michael@0: MOZ_ASSERT(mTexImage, michael@0: "Trying to bind a TextureSource that does not have an underlying GL texture."); michael@0: mTexImage->BindTexture(aTextureUnit); michael@0: SetFilter(mGL, aFilter); michael@0: } michael@0: michael@0: SharedTextureSourceOGL::SharedTextureSourceOGL(CompositorOGL* aCompositor, michael@0: gl::SharedTextureHandle aHandle, michael@0: gfx::SurfaceFormat aFormat, michael@0: GLenum aTarget, michael@0: GLenum aWrapMode, michael@0: SharedTextureShareType aShareType, michael@0: gfx::IntSize aSize) michael@0: : mSize(aSize) michael@0: , mCompositor(aCompositor) michael@0: , mSharedHandle(aHandle) michael@0: , mFormat(aFormat) michael@0: , mShareType(aShareType) michael@0: , mTextureTarget(aTarget) michael@0: , mWrapMode(aWrapMode) michael@0: {} michael@0: michael@0: void michael@0: SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) michael@0: { michael@0: if (!gl()) { michael@0: NS_WARNING("Trying to bind a texture without a GLContext"); michael@0: return; michael@0: } michael@0: GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit); michael@0: michael@0: gl()->fActiveTexture(aTextureUnit); michael@0: gl()->fBindTexture(mTextureTarget, tex); michael@0: if (!AttachSharedHandle(gl(), mShareType, mSharedHandle)) { michael@0: NS_ERROR("Failed to bind shared texture handle"); michael@0: return; michael@0: } michael@0: ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget); michael@0: } michael@0: michael@0: void michael@0: SharedTextureSourceOGL::DetachSharedHandle() michael@0: { michael@0: if (!gl()) { michael@0: return; michael@0: } michael@0: gl::DetachSharedHandle(gl(), mShareType, mSharedHandle); michael@0: } michael@0: michael@0: void michael@0: SharedTextureSourceOGL::SetCompositor(Compositor* aCompositor) michael@0: { michael@0: mCompositor = static_cast(aCompositor); michael@0: } michael@0: michael@0: bool michael@0: SharedTextureSourceOGL::IsValid() const michael@0: { michael@0: return !!gl(); michael@0: } michael@0: michael@0: gl::GLContext* michael@0: SharedTextureSourceOGL::gl() const michael@0: { michael@0: return mCompositor ? mCompositor->gl() : nullptr; michael@0: } michael@0: michael@0: gfx::Matrix4x4 michael@0: SharedTextureSourceOGL::GetTextureTransform() michael@0: { michael@0: SharedHandleDetails handleDetails; michael@0: if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) { michael@0: NS_WARNING("Could not get shared handle details"); michael@0: return gfx::Matrix4x4(); michael@0: } michael@0: michael@0: return handleDetails.mTextureTransform; michael@0: } michael@0: michael@0: SharedTextureHostOGL::SharedTextureHostOGL(TextureFlags aFlags, michael@0: gl::SharedTextureShareType aShareType, michael@0: gl::SharedTextureHandle aSharedHandle, michael@0: gfx::IntSize aSize, michael@0: bool inverted) michael@0: : TextureHost(aFlags) michael@0: , mSize(aSize) michael@0: , mCompositor(nullptr) michael@0: , mSharedHandle(aSharedHandle) michael@0: , mShareType(aShareType) michael@0: { michael@0: } michael@0: michael@0: SharedTextureHostOGL::~SharedTextureHostOGL() michael@0: { michael@0: // If need to deallocate textures, call DeallocateSharedData() before michael@0: // the destructor michael@0: } michael@0: michael@0: gl::GLContext* michael@0: SharedTextureHostOGL::gl() const michael@0: { michael@0: return mCompositor ? mCompositor->gl() : nullptr; michael@0: } michael@0: michael@0: bool michael@0: SharedTextureHostOGL::Lock() michael@0: { michael@0: if (!mCompositor) { michael@0: return false; michael@0: } michael@0: michael@0: if (!mTextureSource) { michael@0: // XXX on android GetSharedHandleDetails can call into Java which we'd michael@0: // rather not do from the compositor michael@0: SharedHandleDetails handleDetails; michael@0: if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) { michael@0: NS_WARNING("Could not get shared handle details"); michael@0: return false; michael@0: } michael@0: michael@0: GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE; michael@0: mTextureSource = new SharedTextureSourceOGL(mCompositor, michael@0: mSharedHandle, michael@0: handleDetails.mTextureFormat, michael@0: handleDetails.mTarget, michael@0: wrapMode, michael@0: mShareType, michael@0: mSize); michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: void michael@0: SharedTextureHostOGL::Unlock() michael@0: { michael@0: if (!mTextureSource) { michael@0: return; michael@0: } michael@0: mTextureSource->DetachSharedHandle(); michael@0: } michael@0: michael@0: void michael@0: SharedTextureHostOGL::SetCompositor(Compositor* aCompositor) michael@0: { michael@0: CompositorOGL* glCompositor = static_cast(aCompositor); michael@0: mCompositor = glCompositor; michael@0: if (mTextureSource) { michael@0: mTextureSource->SetCompositor(glCompositor); michael@0: } michael@0: } michael@0: michael@0: gfx::SurfaceFormat michael@0: SharedTextureHostOGL::GetFormat() const michael@0: { michael@0: MOZ_ASSERT(mTextureSource); michael@0: return mTextureSource->GetFormat(); michael@0: } michael@0: michael@0: void michael@0: StreamTextureSourceOGL::BindTexture(GLenum activetex, gfx::Filter aFilter) michael@0: { michael@0: MOZ_ASSERT(gl()); michael@0: gl()->fActiveTexture(activetex); michael@0: gl()->fBindTexture(mTextureTarget, mTextureHandle); michael@0: SetFilter(gl(), aFilter); michael@0: } michael@0: michael@0: bool michael@0: StreamTextureSourceOGL::RetrieveTextureFromStream() michael@0: { michael@0: gl()->MakeCurrent(); michael@0: michael@0: SharedSurface* sharedSurf = mStream->SwapConsumer(); michael@0: if (!sharedSurf) { michael@0: // We don't have a valid surf to show yet. michael@0: return false; michael@0: } michael@0: michael@0: gl()->MakeCurrent(); michael@0: michael@0: mSize = IntSize(sharedSurf->Size().width, sharedSurf->Size().height); michael@0: michael@0: DataSourceSurface* toUpload = nullptr; michael@0: switch (sharedSurf->Type()) { michael@0: case SharedSurfaceType::GLTextureShare: { michael@0: SharedSurface_GLTexture* glTexSurf = SharedSurface_GLTexture::Cast(sharedSurf); michael@0: mTextureHandle = glTexSurf->ConsTexture(gl()); michael@0: mTextureTarget = glTexSurf->ConsTextureTarget(); michael@0: MOZ_ASSERT(mTextureHandle); michael@0: mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 michael@0: : SurfaceFormat::R8G8B8X8; michael@0: break; michael@0: } michael@0: case SharedSurfaceType::EGLImageShare: { michael@0: SharedSurface_EGLImage* eglImageSurf = michael@0: SharedSurface_EGLImage::Cast(sharedSurf); michael@0: michael@0: eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget); michael@0: MOZ_ASSERT(mTextureHandle); michael@0: mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 michael@0: : SurfaceFormat::R8G8B8X8; michael@0: break; michael@0: } michael@0: #ifdef XP_MACOSX michael@0: case SharedSurfaceType::IOSurface: { michael@0: SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf); michael@0: mTextureHandle = glTexSurf->ConsTexture(gl()); michael@0: mTextureTarget = glTexSurf->ConsTextureTarget(); michael@0: MOZ_ASSERT(mTextureHandle); michael@0: mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 michael@0: : SurfaceFormat::R8G8B8X8; michael@0: break; michael@0: } michael@0: #endif michael@0: case SharedSurfaceType::Basic: { michael@0: toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData(); michael@0: MOZ_ASSERT(toUpload); michael@0: break; michael@0: } michael@0: default: michael@0: MOZ_CRASH("Invalid SharedSurface type."); michael@0: } michael@0: michael@0: if (toUpload) { michael@0: // mBounds seems to end up as (0,0,0,0) a lot, so don't use it? michael@0: nsIntSize size(ThebesIntSize(toUpload->GetSize())); michael@0: nsIntRect rect(nsIntPoint(0,0), size); michael@0: nsIntRegion bounds(rect); michael@0: mFormat = UploadSurfaceToTexture(gl(), michael@0: toUpload, michael@0: bounds, michael@0: mUploadTexture, michael@0: true); michael@0: mTextureHandle = mUploadTexture; michael@0: mTextureTarget = LOCAL_GL_TEXTURE_2D; michael@0: } michael@0: michael@0: MOZ_ASSERT(mTextureHandle); michael@0: gl()->fBindTexture(mTextureTarget, mTextureHandle); michael@0: gl()->fTexParameteri(mTextureTarget, michael@0: LOCAL_GL_TEXTURE_WRAP_S, michael@0: LOCAL_GL_CLAMP_TO_EDGE); michael@0: gl()->fTexParameteri(mTextureTarget, michael@0: LOCAL_GL_TEXTURE_WRAP_T, michael@0: LOCAL_GL_CLAMP_TO_EDGE); michael@0: michael@0: ClearCachedFilter(); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: void michael@0: StreamTextureSourceOGL::DeallocateDeviceData() michael@0: { michael@0: if (mUploadTexture) { michael@0: MOZ_ASSERT(gl()); michael@0: gl()->MakeCurrent(); michael@0: gl()->fDeleteTextures(1, &mUploadTexture); michael@0: mUploadTexture = 0; michael@0: mTextureHandle = 0; michael@0: } michael@0: } michael@0: michael@0: gl::GLContext* michael@0: StreamTextureSourceOGL::gl() const michael@0: { michael@0: return mCompositor ? mCompositor->gl() : nullptr; michael@0: } michael@0: michael@0: void michael@0: StreamTextureSourceOGL::SetCompositor(Compositor* aCompositor) michael@0: { michael@0: mCompositor = static_cast(aCompositor); michael@0: } michael@0: michael@0: StreamTextureHostOGL::StreamTextureHostOGL(TextureFlags aFlags, michael@0: const SurfaceStreamDescriptor& aDesc) michael@0: : TextureHost(aFlags) michael@0: { michael@0: mStream = SurfaceStream::FromHandle(aDesc.handle()); michael@0: MOZ_ASSERT(mStream); michael@0: } michael@0: michael@0: StreamTextureHostOGL::~StreamTextureHostOGL() michael@0: { michael@0: // If need to deallocate textures, call DeallocateSharedData() before michael@0: // the destructor michael@0: } michael@0: michael@0: bool michael@0: StreamTextureHostOGL::Lock() michael@0: { michael@0: if (!mCompositor) { michael@0: return false; michael@0: } michael@0: michael@0: if (!mTextureSource) { michael@0: mTextureSource = new StreamTextureSourceOGL(mCompositor, michael@0: mStream); michael@0: } michael@0: michael@0: return mTextureSource->RetrieveTextureFromStream(); michael@0: } michael@0: michael@0: void michael@0: StreamTextureHostOGL::Unlock() michael@0: { michael@0: } michael@0: michael@0: void michael@0: StreamTextureHostOGL::SetCompositor(Compositor* aCompositor) michael@0: { michael@0: CompositorOGL* glCompositor = static_cast(aCompositor); michael@0: mCompositor = glCompositor; michael@0: if (mTextureSource) { michael@0: mTextureSource->SetCompositor(glCompositor); michael@0: } michael@0: } michael@0: michael@0: gfx::SurfaceFormat michael@0: StreamTextureHostOGL::GetFormat() const michael@0: { michael@0: MOZ_ASSERT(mTextureSource); michael@0: return mTextureSource->GetFormat(); michael@0: } michael@0: michael@0: gfx::IntSize michael@0: StreamTextureHostOGL::GetSize() const michael@0: { michael@0: MOZ_ASSERT(mTextureSource); michael@0: return mTextureSource->GetSize(); michael@0: } michael@0: michael@0: } // namespace michael@0: } // namespace