diff --git a/gfx/layers/Compositor.cpp b/gfx/layers/Compositor.cpp index 2ddf4f05c9e..81883297380 100644 --- a/gfx/layers/Compositor.cpp +++ b/gfx/layers/Compositor.cpp @@ -11,6 +11,13 @@ #include "gfx2DGlue.h" #include "nsAppRunner.h" +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 +#include "libdisplay/GonkDisplay.h" // for GonkDisplay +#include +#include "nsWindow.h" +#include "nsScreenManagerGonk.h" +#endif + namespace mozilla { namespace gfx { class Matrix4x4; @@ -353,5 +360,49 @@ DecomposeIntoNoRepeatRects(const gfx::Rect& aRect, return 4; } +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 +void +Compositor::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget) +{ + // OpenGL does not provide ReleaseFence for rendering. + // Instead use DispAcquireFence as layer buffer's ReleaseFence + // to prevent flickering and tearing. + // DispAcquireFence is DisplaySurface's AcquireFence. + // AcquireFence will be signaled when a buffer's content is available. + // See Bug 974152. + + if (!aLayer || !aWidget) { + return; + } + nsWindow* window = static_cast(aWidget); + RefPtr fence = new FenceHandle::FdObj( + window->GetScreen()->GetPrevDispAcquireFd()); + mReleaseFenceHandle.Merge(FenceHandle(fence)); +} + +FenceHandle +Compositor::GetReleaseFence() +{ + if (!mReleaseFenceHandle.IsValid()) { + return FenceHandle(); + } + + RefPtr fdObj = mReleaseFenceHandle.GetDupFdObj(); + return FenceHandle(fdObj); +} + +#else +void +Compositor::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget) +{ +} + +FenceHandle +Compositor::GetReleaseFence() +{ + return FenceHandle(); +} +#endif + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index 13648a9289e..5b7d830bfdb 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -370,12 +370,9 @@ public: */ virtual void EndFrame() = 0; - virtual void SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget) {} + virtual void SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget); - virtual FenceHandle GetReleaseFence() - { - return FenceHandle(); - } + virtual FenceHandle GetReleaseFence(); /** * Post-rendering stuff if the rendering is done outside of this Compositor @@ -541,6 +538,10 @@ protected: RefPtr mTarget; gfx::IntRect mTargetBounds; +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 + FenceHandle mReleaseFenceHandle; +#endif + private: static LayersBackend sBackend; diff --git a/gfx/layers/GrallocImages.cpp b/gfx/layers/GrallocImages.cpp index 77576f577b6..364b13498a4 100644 --- a/gfx/layers/GrallocImages.cpp +++ b/gfx/layers/GrallocImages.cpp @@ -397,18 +397,15 @@ ConvertOmxYUVFormatToRGB565(android::sp& aBuffer, return OK; } -already_AddRefed -GrallocImage::GetAsSourceSurface() +already_AddRefed +GetDataSourceSurfaceFrom(android::sp& aGraphicBuffer, + gfx::IntSize aSize, + const layers::PlanarYCbCrData& aYcbcrData) { - if (!mTextureClient) { - return nullptr; - } - - android::sp graphicBuffer = - mTextureClient->GetGraphicBuffer(); + MOZ_ASSERT(aGraphicBuffer.get()); RefPtr surface = - gfx::Factory::CreateDataSourceSurface(GetSize(), gfx::SurfaceFormat::R5G6B5); + gfx::Factory::CreateDataSourceSurface(aSize, gfx::SurfaceFormat::R5G6B5); if (NS_WARN_IF(!surface)) { return nullptr; } @@ -420,13 +417,13 @@ GrallocImage::GetAsSourceSurface() } int32_t rv; - rv = ConvertOmxYUVFormatToRGB565(graphicBuffer, surface, &mappedSurface, mData); + rv = ConvertOmxYUVFormatToRGB565(aGraphicBuffer, surface, &mappedSurface, aYcbcrData); if (rv == OK) { surface->Unmap(); return surface.forget(); } - rv = ConvertVendorYUVFormatToRGB565(graphicBuffer, surface, &mappedSurface); + rv = ConvertVendorYUVFormatToRGB565(aGraphicBuffer, surface, &mappedSurface); surface->Unmap(); if (rv != OK) { NS_WARNING("Unknown color format"); @@ -436,6 +433,22 @@ GrallocImage::GetAsSourceSurface() return surface.forget(); } +already_AddRefed +GrallocImage::GetAsSourceSurface() +{ + if (!mTextureClient) { + return nullptr; + } + + android::sp graphicBuffer = + mTextureClient->GetGraphicBuffer(); + + RefPtr surface = + GetDataSourceSurfaceFrom(graphicBuffer, mSize, mData); + + return surface.forget(); +} + android::sp GrallocImage::GetGraphicBuffer() const { diff --git a/gfx/layers/GrallocImages.h b/gfx/layers/GrallocImages.h index 727235fc0f2..701051175b8 100644 --- a/gfx/layers/GrallocImages.h +++ b/gfx/layers/GrallocImages.h @@ -22,6 +22,11 @@ namespace layers { class GrallocTextureClientOGL; +already_AddRefed +GetDataSourceSurfaceFrom(android::sp& aGraphicBuffer, + gfx::IntSize aSize, + const layers::PlanarYCbCrData& aYcbcrData); + /** * The YUV format supported by Android HAL * diff --git a/gfx/layers/basic/GrallocTextureHostBasic.cpp b/gfx/layers/basic/GrallocTextureHostBasic.cpp new file mode 100644 index 00000000000..810ba8e573e --- /dev/null +++ b/gfx/layers/basic/GrallocTextureHostBasic.cpp @@ -0,0 +1,291 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "GrallocTextureHostBasic.h" +#include "GrallocImages.h" // for GetDataSourceSurfaceFrom() +#include "mozilla/layers/SharedBufferManagerParent.h" + +#if ANDROID_VERSION >= 17 +#include +#endif + +namespace mozilla { +namespace layers { + +static SurfaceFormat +HalFormatToSurfaceFormat(int aHalFormat, TextureFlags aFlags) +{ + bool swapRB = bool(aFlags & TextureFlags::RB_SWAPPED); + switch (aHalFormat) { + case android::PIXEL_FORMAT_BGRA_8888: + return swapRB ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::B8G8R8A8; + case android::PIXEL_FORMAT_RGBA_8888: + return swapRB ? gfx::SurfaceFormat::B8G8R8A8 : gfx::SurfaceFormat::R8G8B8A8; + case android::PIXEL_FORMAT_RGBX_8888: + return swapRB ? gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::R8G8B8X8; + case android::PIXEL_FORMAT_RGB_565: + return gfx::SurfaceFormat::R5G6B5; + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: + case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + case HAL_PIXEL_FORMAT_YV12: +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 + case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: +#endif + // Needs convert to RGB565 + return gfx::SurfaceFormat::R5G6B5; + default: + if (aHalFormat >= 0x100 && aHalFormat <= 0x1FF) { + // Reserved range for HAL specific formats. + // Needs convert to RGB565 + return gfx::SurfaceFormat::R5G6B5; + } else { + MOZ_CRASH("Unhandled HAL pixel format"); + return SurfaceFormat::UNKNOWN; // not reached + } + } +} + +static bool +NeedsConvertFromYUVtoRGB565(int aHalFormat) +{ + switch (aHalFormat) { + case android::PIXEL_FORMAT_BGRA_8888: + case android::PIXEL_FORMAT_RGBA_8888: + case android::PIXEL_FORMAT_RGBX_8888: + case android::PIXEL_FORMAT_RGB_565: + return false; + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: + case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + case HAL_PIXEL_FORMAT_YV12: +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 + case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: +#endif + return true; + default: + if (aHalFormat >= 0x100 && aHalFormat <= 0x1FF) { + // Reserved range for HAL specific formats. + return true; + } else { + MOZ_CRASH("Unhandled HAL pixel format"); + return false; // not reached + } + } +} + +GrallocTextureHostBasic::GrallocTextureHostBasic( + TextureFlags aFlags, + const NewSurfaceDescriptorGralloc& aDescriptor) + : TextureHost(aFlags) + , mGrallocHandle(aDescriptor) + , mSize(0, 0) + , mCropSize(0, 0) + , mFormat(gfx::SurfaceFormat::UNKNOWN) + , mIsOpaque(aDescriptor.isOpaque()) +{ + android::GraphicBuffer* grallocBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get(); + MOZ_ASSERT(grallocBuffer); + + if (grallocBuffer) { + mFormat = + HalFormatToSurfaceFormat(grallocBuffer->getPixelFormat(), + aFlags & TextureFlags::RB_SWAPPED); + mSize = gfx::IntSize(grallocBuffer->getWidth(), grallocBuffer->getHeight()); + mCropSize = mSize; + } else { + printf_stderr("gralloc buffer is nullptr\n"); + } +} + +bool +GrallocTextureHostBasic::Lock() +{ + if (!mCompositor || !IsValid()) { + return false; + } + + if (mTextureSource) { + return true; + } + + android::sp graphicBuffer = + GetGraphicBufferFromDesc(mGrallocHandle); + MOZ_ASSERT(graphicBuffer.get()); + + RefPtr surf; + if (NeedsConvertFromYUVtoRGB565(graphicBuffer->getPixelFormat())) { + PlanarYCbCrData ycbcrData; + surf = GetDataSourceSurfaceFrom(graphicBuffer, + mCropSize, + ycbcrData); + } else { + uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN; + int32_t rv = graphicBuffer->lock(usage, + reinterpret_cast(&mMappedBuffer)); + if (rv) { + mMappedBuffer = nullptr; + NS_WARNING("Couldn't lock graphic buffer"); + return false; + } + surf = Factory::CreateWrappingDataSourceSurface( + mMappedBuffer, + graphicBuffer->getStride() * gfx::BytesPerPixel(mFormat), + mCropSize, + mFormat); + } + mTextureSource = mCompositor->CreateDataTextureSource(mFlags); + mTextureSource->Update(surf, nullptr); + return true; +} + +bool +GrallocTextureHostBasic::IsValid() const +{ + android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get(); + return graphicBuffer != nullptr; +} + +bool +GrallocTextureHostBasic::BindTextureSource(CompositableTextureSourceRef& aTexture) +{ + aTexture = mTextureSource; + return !!aTexture; +} + +void +GrallocTextureHostBasic::UnbindTextureSource() +{ + ClearTextureSource(); +} + +void +GrallocTextureHostBasic::ClearTextureSource() +{ + mTextureSource = nullptr; + if (mMappedBuffer) { + android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get(); + MOZ_ASSERT(graphicBuffer); + mMappedBuffer = nullptr; + graphicBuffer->unlock(); + } +} + +void +GrallocTextureHostBasic::SetCompositor(Compositor* aCompositor) +{ + BasicCompositor* compositor = static_cast(aCompositor); + mCompositor = compositor; + if (mTextureSource) { + mTextureSource->SetCompositor(compositor); + } +} + +gfx::SurfaceFormat +GrallocTextureHostBasic::GetFormat() const { + return mFormat; +} + +void +GrallocTextureHostBasic::WaitAcquireFenceHandleSyncComplete() +{ + if (!mAcquireFenceHandle.IsValid()) { + return; + } + +#if ANDROID_VERSION >= 17 + RefPtr fdObj = mAcquireFenceHandle.GetAndResetFdObj(); + android::sp fence( + new android::Fence(fdObj->GetAndResetFd())); + + // Wait fece complete with timeout. + // If a source of the fence becomes invalid because of error, + // fene complete is not signaled. See Bug 1061435. + int rv = fence->wait(400 /*400 msec*/); + if (rv != android::OK) { + NS_ERROR("failed to wait fence complete"); + } +#endif +} + +void +GrallocTextureHostBasic::SetCropRect(nsIntRect aCropRect) +{ + MOZ_ASSERT(aCropRect.TopLeft() == IntPoint(0, 0)); + MOZ_ASSERT(!aCropRect.IsEmpty()); + MOZ_ASSERT(aCropRect.width <= mSize.width); + MOZ_ASSERT(aCropRect.height <= mSize.height); + + gfx::IntSize cropSize(aCropRect.width, aCropRect.height); + if (mCropSize == cropSize) { + return; + } + + mCropSize = cropSize; + ClearTextureSource(); +} + +void +GrallocTextureHostBasic::DeallocateSharedData() +{ + ClearTextureSource(); + + if (mGrallocHandle.buffer().type() != MaybeMagicGrallocBufferHandle::Tnull_t) { + MaybeMagicGrallocBufferHandle handle = mGrallocHandle.buffer(); + base::ProcessId owner; + if (handle.type() == MaybeMagicGrallocBufferHandle::TGrallocBufferRef) { + owner = handle.get_GrallocBufferRef().mOwner; + } + else { + owner = handle.get_MagicGrallocBufferHandle().mRef.mOwner; + } + + SharedBufferManagerParent::DropGrallocBuffer(owner, mGrallocHandle); + } +} + +void +GrallocTextureHostBasic::ForgetSharedData() +{ + ClearTextureSource(); +} + +void +GrallocTextureHostBasic::DeallocateDeviceData() +{ + ClearTextureSource(); +} + +LayerRenderState +GrallocTextureHostBasic::GetRenderState() +{ + android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get(); + + if (graphicBuffer) { + LayerRenderStateFlags flags = LayerRenderStateFlags::LAYER_RENDER_STATE_DEFAULT; + if (mIsOpaque) { + flags |= LayerRenderStateFlags::OPAQUE; + } + if (mFlags & TextureFlags::ORIGIN_BOTTOM_LEFT) { + flags |= LayerRenderStateFlags::ORIGIN_BOTTOM_LEFT; + } + if (mFlags & TextureFlags::RB_SWAPPED) { + flags |= LayerRenderStateFlags::FORMAT_RB_SWAP; + } + return LayerRenderState(graphicBuffer, + mCropSize, + flags, + this); + } + + return LayerRenderState(); +} + +} // namespace layers +} // namespace mozilla diff --git a/gfx/layers/basic/GrallocTextureHostBasic.h b/gfx/layers/basic/GrallocTextureHostBasic.h new file mode 100644 index 00000000000..b1bcece152c --- /dev/null +++ b/gfx/layers/basic/GrallocTextureHostBasic.h @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GFX_GRALLOCTEXTUREHOST_BASIC_H +#define MOZILLA_GFX_GRALLOCTEXTUREHOST_BASIC_H + +#include "mozilla/layers/BasicCompositor.h" +#include "mozilla/layers/ShadowLayerUtilsGralloc.h" +#include "mozilla/layers/TextureHostBasic.h" + +namespace mozilla { +namespace layers { + +class BasicCompositor; + +/** + * A TextureHost for shared gralloc + * + * Most of the logic actually happens in GrallocTextureSourceBasic. + */ +class GrallocTextureHostBasic : public TextureHost +{ +public: + GrallocTextureHostBasic(TextureFlags aFlags, + const NewSurfaceDescriptorGralloc& aDescriptor); + + virtual void SetCompositor(Compositor* aCompositor) override; + + virtual bool Lock() override; + + virtual gfx::SurfaceFormat GetFormat() const override; + + virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override; + + virtual void UnbindTextureSource() override; + + virtual already_AddRefed GetAsSurface() override + { + return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING) + } + + virtual void WaitAcquireFenceHandleSyncComplete() override; + + virtual gfx::IntSize GetSize() const override { return mCropSize; } + + virtual void SetCropRect(nsIntRect aCropRect) override; + + virtual void DeallocateSharedData() override; + + virtual void ForgetSharedData() override; + + virtual void DeallocateDeviceData() override; + + virtual LayerRenderState GetRenderState() override; + + bool IsValid() const; + + void ClearTextureSource(); + +#ifdef MOZ_LAYERS_HAVE_LOG + virtual const char* Name() override { return "GrallocTextureHostBasic"; } +#endif + +protected: + RefPtr mCompositor; + RefPtr mTextureSource; + NewSurfaceDescriptorGralloc mGrallocHandle; + // gralloc buffer size. + gfx::IntSize mSize; + // Size reported by TextureClient, can be different in some cases (video?), + // used by LayerRenderState. + gfx::IntSize mCropSize; + gfx::SurfaceFormat mFormat; + bool mIsOpaque; + /** + * Points to a mapped gralloc buffer when TextureSource is valid. + */ + uint8_t* mMappedBuffer; +}; + +} // namespace layers +} // namespace mozilla + +#endif // MOZILLA_GFX_GRALLOCTEXTUREHOST_BASIC_H diff --git a/gfx/layers/basic/TextureHostBasic.cpp b/gfx/layers/basic/TextureHostBasic.cpp index 8058e43efca..07949f70a02 100644 --- a/gfx/layers/basic/TextureHostBasic.cpp +++ b/gfx/layers/basic/TextureHostBasic.cpp @@ -7,6 +7,9 @@ #ifdef XP_MACOSX #include "MacIOSurfaceTextureHostBasic.h" #endif +#ifdef MOZ_WIDGET_GONK +#include "GrallocTextureHostBasic.h" +#endif using namespace mozilla::gl; using namespace mozilla::gfx; @@ -25,6 +28,13 @@ CreateTextureHostBasic(const SurfaceDescriptor& aDesc, aDesc.get_SurfaceDescriptorMacIOSurface(); return MakeAndAddRef(aFlags, desc); } +#endif +#ifdef MOZ_WIDGET_GONK + if (aDesc.type() == SurfaceDescriptor::TNewSurfaceDescriptorGralloc) { + const NewSurfaceDescriptorGralloc& desc = + aDesc.get_NewSurfaceDescriptorGralloc(); + return MakeAndAddRef(aFlags, desc); + } #endif return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); } diff --git a/gfx/layers/client/TextureClientSharedSurface.cpp b/gfx/layers/client/TextureClientSharedSurface.cpp index d9fa324b224..a8aea9b008c 100644 --- a/gfx/layers/client/TextureClientSharedSurface.cpp +++ b/gfx/layers/client/TextureClientSharedSurface.cpp @@ -14,9 +14,12 @@ #include "SharedSurface.h" #ifdef MOZ_WIDGET_GONK +#include "mozilla/layers/GrallocTextureClient.h" #include "SharedSurfaceGralloc.h" #endif +using namespace mozilla::gl; + namespace mozilla { namespace layers { diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index f27b2d4ec52..a47e37e881f 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -214,10 +214,10 @@ TextureHost::Create(const SurfaceDescriptor& aDesc, return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags); case SurfaceDescriptor::TEGLImageDescriptor: - case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: case SurfaceDescriptor::TSurfaceTextureDescriptor: return CreateTextureHostOGL(aDesc, aDeallocator, aFlags); + case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: if (aBackend == LayersBackend::LAYERS_OPENGL) { return CreateTextureHostOGL(aDesc, aDeallocator, aFlags); diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 9bc538938a3..5853c319b0a 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -217,9 +217,11 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': # has full system permissions there. if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': EXPORTS.mozilla.layers += [ + 'basic/GrallocTextureHostBasic.h', 'ipc/ShadowLayerUtilsGralloc.h', ] UNIFIED_SOURCES += [ + 'basic/GrallocTextureHostBasic.cpp', 'GrallocImages.cpp', 'opengl/EGLImageHelpers.cpp', 'opengl/GrallocTextureClient.cpp', diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 208cdcdf96f..231565e1d9c 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -51,13 +51,6 @@ #include "GeckoProfiler.h" -#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 -#include "libdisplay/GonkDisplay.h" // for GonkDisplay -#include -#include "nsWindow.h" -#include "nsScreenManagerGonk.h" -#endif - namespace mozilla { using namespace std; @@ -1458,50 +1451,6 @@ CompositorOGL::EndFrame() } } -#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 -void -CompositorOGL::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget) -{ - // OpenGL does not provide ReleaseFence for rendering. - // Instead use DispAcquireFence as layer buffer's ReleaseFence - // to prevent flickering and tearing. - // DispAcquireFence is DisplaySurface's AcquireFence. - // AcquireFence will be signaled when a buffer's content is available. - // See Bug 974152. - - if (!aLayer || !aWidget) { - return; - } - nsWindow* window = static_cast(aWidget); - RefPtr fence = new FenceHandle::FdObj( - window->GetScreen()->GetPrevDispAcquireFd()); - mReleaseFenceHandle.Merge(FenceHandle(fence)); -} - -FenceHandle -CompositorOGL::GetReleaseFence() -{ - if (!mReleaseFenceHandle.IsValid()) { - return FenceHandle(); - } - - RefPtr fdObj = mReleaseFenceHandle.GetDupFdObj(); - return FenceHandle(fdObj); -} - -#else -void -CompositorOGL::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget) -{ -} - -FenceHandle -CompositorOGL::GetReleaseFence() -{ - return FenceHandle(); -} -#endif - void CompositorOGL::EndFrameForExternalComposition(const gfx::Matrix& aTransform) { diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 33af2030ccf..f6f57bc07b9 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -232,8 +232,6 @@ public: const gfx::Rect& aVisibleRect) override; virtual void EndFrame() override; - virtual void SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget) override; - virtual FenceHandle GetReleaseFence() override; virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) override; virtual bool SupportsPartialTextureUpdate() override; @@ -452,7 +450,6 @@ private: */ gfx::IntSize mViewportSize; - FenceHandle mReleaseFenceHandle; ShaderProgramOGL *mCurrentProgram; gfx::Rect mRenderBound; diff --git a/gfx/layers/opengl/GrallocTextureHost.cpp b/gfx/layers/opengl/GrallocTextureHost.cpp index 49141b58529..19b58fa6cff 100644 --- a/gfx/layers/opengl/GrallocTextureHost.cpp +++ b/gfx/layers/opengl/GrallocTextureHost.cpp @@ -118,7 +118,7 @@ GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags, mSize = gfx::IntSize(graphicBuffer->getWidth(), graphicBuffer->getHeight()); mCropSize = mSize; } else { - printf_stderr("gralloc buffer is nullptr"); + printf_stderr("gralloc buffer is nullptr\n"); } } @@ -419,7 +419,7 @@ GrallocTextureHostOGL::WaitAcquireFenceHandleSyncComplete() EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), sync, 0, - 400000000 /*400 usec*/); + 400000000 /*400 msec*/); if (status != LOCAL_EGL_CONDITION_SATISFIED) { NS_ERROR("failed to wait native fence sync"); } diff --git a/widget/gonk/libdisplay/GonkDisplayJB.cpp b/widget/gonk/libdisplay/GonkDisplayJB.cpp index 0cb8f48d8d3..40aac88bbfe 100644 --- a/widget/gonk/libdisplay/GonkDisplayJB.cpp +++ b/widget/gonk/libdisplay/GonkDisplayJB.cpp @@ -323,24 +323,41 @@ GonkDisplayJB::DequeueBuffer() bool GonkDisplayJB::QueueBuffer(ANativeWindowBuffer* buf) { - int error = 0; bool success = false; + int error = DoQueueBuffer(buf); + // Check for bootAnim or normal display flow. + if (!mBootAnimSTClient.get()) { + success = Post(mDispSurface->lastHandle, mDispSurface->GetPrevDispAcquireFd()); + } else { + success = Post(mBootAnimDispSurface->lastHandle, mBootAnimDispSurface->GetPrevDispAcquireFd()); + } + return error == 0 && success; +} + +int +GonkDisplayJB::DoQueueBuffer(ANativeWindowBuffer* buf) +{ + int error = 0; // Check for bootAnim or normal display flow. if (!mBootAnimSTClient.get()) { error = mSTClient->queueBuffer(mSTClient.get(), buf, -1); - success = Post(mDispSurface->lastHandle, mDispSurface->GetPrevDispAcquireFd()); } else { error = mBootAnimSTClient->queueBuffer(mBootAnimSTClient.get(), buf, -1); - success = Post(mBootAnimDispSurface->lastHandle, mBootAnimDispSurface->GetPrevDispAcquireFd()); } - - return error == 0 && success; + return error; } void GonkDisplayJB::UpdateDispSurface(EGLDisplay dpy, EGLSurface sur) { - eglSwapBuffers(dpy, sur); + if (sur != EGL_NO_SURFACE) { + eglSwapBuffers(dpy, sur); + } else { + // When BasicCompositor is used as Compositor, + // EGLSurface does not exit. + ANativeWindowBuffer* buf = DequeueBuffer(); + DoQueueBuffer(buf); + } } void diff --git a/widget/gonk/libdisplay/GonkDisplayJB.h b/widget/gonk/libdisplay/GonkDisplayJB.h index 894491c7924..b1a58a09fcd 100644 --- a/widget/gonk/libdisplay/GonkDisplayJB.h +++ b/widget/gonk/libdisplay/GonkDisplayJB.h @@ -58,6 +58,8 @@ private: uint32_t aWidth, uint32_t aHeight); void PowerOnDisplay(int aDpy); + int DoQueueBuffer(ANativeWindowBuffer* buf); + hw_module_t const* mModule; hw_module_t const* mFBModule; hwc_composer_device_1_t* mHwc;