mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 957323 - handle android's fence on gonk r=nical,doublec,pchang
This commit is contained in:
parent
9daa614006
commit
1acf2e8c86
@ -15,6 +15,9 @@
|
|||||||
#include <stagefright/OMXClient.h>
|
#include <stagefright/OMXClient.h>
|
||||||
#include <stagefright/OMXCodec.h>
|
#include <stagefright/OMXCodec.h>
|
||||||
#include <OMX.h>
|
#include <OMX.h>
|
||||||
|
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
#include <ui/Fence.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/Types.h"
|
#include "mozilla/Types.h"
|
||||||
@ -213,7 +216,7 @@ VideoGraphicBuffer::Unlock()
|
|||||||
// The message is delivered to OmxDecoder on ALooper thread.
|
// The message is delivered to OmxDecoder on ALooper thread.
|
||||||
// MediaBuffer::release() could take a very long time.
|
// MediaBuffer::release() could take a very long time.
|
||||||
// PostReleaseVideoBuffer() prevents long time locking.
|
// PostReleaseVideoBuffer() prevents long time locking.
|
||||||
omxDecoder->PostReleaseVideoBuffer(mMediaBuffer);
|
omxDecoder->PostReleaseVideoBuffer(mMediaBuffer, mReleaseFenceHandle);
|
||||||
} else {
|
} else {
|
||||||
NS_WARNING("OmxDecoder is not present");
|
NS_WARNING("OmxDecoder is not present");
|
||||||
if (mMediaBuffer) {
|
if (mMediaBuffer) {
|
||||||
@ -794,7 +797,7 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
|||||||
{
|
{
|
||||||
Mutex::Autolock autoLock(mSeekLock);
|
Mutex::Autolock autoLock(mSeekLock);
|
||||||
mIsVideoSeeking = false;
|
mIsVideoSeeking = false;
|
||||||
ReleaseAllPendingVideoBuffersLocked();
|
PostReleaseVideoBuffer(nullptr, FenceHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
aDoSeek = false;
|
aDoSeek = false;
|
||||||
@ -841,6 +844,9 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
|||||||
aFrame->mKeyFrame = keyFrame;
|
aFrame->mKeyFrame = keyFrame;
|
||||||
aFrame->Y.mWidth = mVideoWidth;
|
aFrame->Y.mWidth = mVideoWidth;
|
||||||
aFrame->Y.mHeight = mVideoHeight;
|
aFrame->Y.mHeight = mVideoHeight;
|
||||||
|
// Release to hold video buffer in OmxDecoder more.
|
||||||
|
// MediaBuffer's ref count is changed from 2 to 1.
|
||||||
|
ReleaseVideoBuffer();
|
||||||
} else if (mVideoBuffer->range_length() > 0) {
|
} else if (mVideoBuffer->range_length() > 0) {
|
||||||
char *data = static_cast<char *>(mVideoBuffer->data()) + mVideoBuffer->range_offset();
|
char *data = static_cast<char *>(mVideoBuffer->data()) + mVideoBuffer->range_offset();
|
||||||
size_t length = mVideoBuffer->range_length();
|
size_t length = mVideoBuffer->range_length();
|
||||||
@ -1022,11 +1028,13 @@ void OmxDecoder::onMessageReceived(const sp<AMessage> &msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OmxDecoder::PostReleaseVideoBuffer(MediaBuffer *aBuffer)
|
void OmxDecoder::PostReleaseVideoBuffer(MediaBuffer *aBuffer, const FenceHandle& aReleaseFenceHandle)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
Mutex::Autolock autoLock(mPendingVideoBuffersLock);
|
Mutex::Autolock autoLock(mPendingVideoBuffersLock);
|
||||||
mPendingVideoBuffers.push(aBuffer);
|
if (aBuffer) {
|
||||||
|
mPendingVideoBuffers.push(BufferItem(aBuffer, aReleaseFenceHandle));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<AMessage> notify =
|
sp<AMessage> notify =
|
||||||
@ -1037,14 +1045,13 @@ void OmxDecoder::PostReleaseVideoBuffer(MediaBuffer *aBuffer)
|
|||||||
|
|
||||||
void OmxDecoder::ReleaseAllPendingVideoBuffersLocked()
|
void OmxDecoder::ReleaseAllPendingVideoBuffersLocked()
|
||||||
{
|
{
|
||||||
Vector<MediaBuffer *> releasingVideoBuffers;
|
Vector<BufferItem> releasingVideoBuffers;
|
||||||
{
|
{
|
||||||
Mutex::Autolock autoLock(mPendingVideoBuffersLock);
|
Mutex::Autolock autoLock(mPendingVideoBuffersLock);
|
||||||
|
|
||||||
int size = mPendingVideoBuffers.size();
|
int size = mPendingVideoBuffers.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
MediaBuffer *buffer = mPendingVideoBuffers[i];
|
releasingVideoBuffers.push(mPendingVideoBuffers[i]);
|
||||||
releasingVideoBuffers.push(buffer);
|
|
||||||
}
|
}
|
||||||
mPendingVideoBuffers.clear();
|
mPendingVideoBuffers.clear();
|
||||||
}
|
}
|
||||||
@ -1052,7 +1059,28 @@ void OmxDecoder::ReleaseAllPendingVideoBuffersLocked()
|
|||||||
int size = releasingVideoBuffers.size();
|
int size = releasingVideoBuffers.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
MediaBuffer *buffer;
|
MediaBuffer *buffer;
|
||||||
buffer = releasingVideoBuffers[i];
|
buffer = releasingVideoBuffers[i].mMediaBuffer;
|
||||||
|
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
|
||||||
|
android::sp<Fence> fence;
|
||||||
|
int fenceFd = -1;
|
||||||
|
fence = releasingVideoBuffers[i].mReleaseFenceHandle.mFence;
|
||||||
|
if (fence.get() && fence->isValid()) {
|
||||||
|
fenceFd = fence->dup();
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(buffer->refcount() == 1);
|
||||||
|
// This code expect MediaBuffer's ref count is 1.
|
||||||
|
// Return gralloc buffer to ANativeWindow
|
||||||
|
ANativeWindow* window = static_cast<ANativeWindow*>(mNativeWindowClient.get());
|
||||||
|
window->cancelBuffer(window,
|
||||||
|
buffer->graphicBuffer().get(),
|
||||||
|
fenceFd);
|
||||||
|
// Mark MediaBuffer as rendered.
|
||||||
|
// When gralloc buffer is directly returned to ANativeWindow,
|
||||||
|
// this mark is necesary.
|
||||||
|
sp<MetaData> metaData = buffer->meta_data();
|
||||||
|
metaData->setInt32(kKeyRendered, 1);
|
||||||
|
#endif
|
||||||
|
// Return MediaBuffer to OMXCodec.
|
||||||
buffer->release();
|
buffer->release();
|
||||||
}
|
}
|
||||||
releasingVideoBuffers.clear();
|
releasingVideoBuffers.clear();
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "GonkNativeWindow.h"
|
#include "GonkNativeWindow.h"
|
||||||
#include "GonkNativeWindowClient.h"
|
#include "GonkNativeWindowClient.h"
|
||||||
#include "GrallocImages.h"
|
#include "GrallocImages.h"
|
||||||
|
#include "mozilla/layers/FenceUtils.h"
|
||||||
#include "MP3FrameParser.h"
|
#include "MP3FrameParser.h"
|
||||||
#include "MPAPI.h"
|
#include "MPAPI.h"
|
||||||
#include "MediaResource.h"
|
#include "MediaResource.h"
|
||||||
@ -83,6 +84,7 @@ class OmxDecoder : public OMXCodecProxy::EventListener {
|
|||||||
typedef mozilla::MP3FrameParser MP3FrameParser;
|
typedef mozilla::MP3FrameParser MP3FrameParser;
|
||||||
typedef mozilla::MediaResource MediaResource;
|
typedef mozilla::MediaResource MediaResource;
|
||||||
typedef mozilla::AbstractMediaDecoder AbstractMediaDecoder;
|
typedef mozilla::AbstractMediaDecoder AbstractMediaDecoder;
|
||||||
|
typedef mozilla::layers::FenceHandle FenceHandle;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kPreferSoftwareCodecs = 1,
|
kPreferSoftwareCodecs = 1,
|
||||||
@ -122,11 +124,26 @@ class OmxDecoder : public OMXCodecProxy::EventListener {
|
|||||||
MediaBuffer *mVideoBuffer;
|
MediaBuffer *mVideoBuffer;
|
||||||
MediaBuffer *mAudioBuffer;
|
MediaBuffer *mAudioBuffer;
|
||||||
|
|
||||||
|
struct BufferItem {
|
||||||
|
BufferItem()
|
||||||
|
: mMediaBuffer(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
BufferItem(MediaBuffer* aMediaBuffer, const FenceHandle& aReleaseFenceHandle)
|
||||||
|
: mMediaBuffer(aMediaBuffer)
|
||||||
|
, mReleaseFenceHandle(aReleaseFenceHandle) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaBuffer* mMediaBuffer;
|
||||||
|
// a fence will signal when the current buffer is no longer being read.
|
||||||
|
FenceHandle mReleaseFenceHandle;
|
||||||
|
};
|
||||||
|
|
||||||
// Hold video's MediaBuffers that are released during video seeking.
|
// Hold video's MediaBuffers that are released during video seeking.
|
||||||
// The holded MediaBuffers are released soon after seek completion.
|
// The holded MediaBuffers are released soon after seek completion.
|
||||||
// OMXCodec does not accept MediaBuffer during seeking. If MediaBuffer is
|
// OMXCodec does not accept MediaBuffer during seeking. If MediaBuffer is
|
||||||
// returned to OMXCodec during seeking, OMXCodec calls assert.
|
// returned to OMXCodec during seeking, OMXCodec calls assert.
|
||||||
Vector<MediaBuffer *> mPendingVideoBuffers;
|
Vector<BufferItem> mPendingVideoBuffers;
|
||||||
// The lock protects mPendingVideoBuffers.
|
// The lock protects mPendingVideoBuffers.
|
||||||
Mutex mPendingVideoBuffersLock;
|
Mutex mPendingVideoBuffersLock;
|
||||||
|
|
||||||
@ -235,7 +252,7 @@ public:
|
|||||||
void Pause();
|
void Pause();
|
||||||
|
|
||||||
// Post kNotifyPostReleaseVideoBuffer message to OmxDecoder via ALooper.
|
// Post kNotifyPostReleaseVideoBuffer message to OmxDecoder via ALooper.
|
||||||
void PostReleaseVideoBuffer(MediaBuffer *aBuffer);
|
void PostReleaseVideoBuffer(MediaBuffer *aBuffer, const FenceHandle& aReleaseFenceHandle);
|
||||||
// Receive a message from AHandlerReflector.
|
// Receive a message from AHandlerReflector.
|
||||||
// Called on ALooper thread.
|
// Called on ALooper thread.
|
||||||
void onMessageReceived(const sp<AMessage> &msg);
|
void onMessageReceived(const sp<AMessage> &msg);
|
||||||
|
@ -8,11 +8,12 @@
|
|||||||
|
|
||||||
#ifdef MOZ_WIDGET_GONK
|
#ifdef MOZ_WIDGET_GONK
|
||||||
|
|
||||||
#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
|
|
||||||
#include "mozilla/layers/LayersSurfaces.h"
|
|
||||||
#include "mozilla/gfx/Point.h"
|
|
||||||
#include "ImageLayers.h"
|
#include "ImageLayers.h"
|
||||||
#include "ImageContainer.h"
|
#include "ImageContainer.h"
|
||||||
|
#include "mozilla/gfx/Point.h"
|
||||||
|
#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
|
||||||
|
#include "mozilla/layers/FenceUtils.h"
|
||||||
|
#include "mozilla/layers/LayersSurfaces.h"
|
||||||
|
|
||||||
#include <ui/GraphicBuffer.h>
|
#include <ui/GraphicBuffer.h>
|
||||||
|
|
||||||
@ -46,6 +47,16 @@ public:
|
|||||||
return mSurfaceDescriptor;
|
return mSurfaceDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle)
|
||||||
|
{
|
||||||
|
mReleaseFenceHandle = aReleaseFenceHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FenceHandle& GetReleaseFenceHandle() const
|
||||||
|
{
|
||||||
|
return mReleaseFenceHandle;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Unlock() {}
|
virtual void Unlock() {}
|
||||||
|
|
||||||
@ -65,6 +76,7 @@ private:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
SurfaceDescriptor mSurfaceDescriptor;
|
SurfaceDescriptor mSurfaceDescriptor;
|
||||||
|
FenceHandle mReleaseFenceHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +38,7 @@ class GraphicBuffer;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
|
class TextureHost;
|
||||||
|
|
||||||
typedef uint32_t TextureFlags;
|
typedef uint32_t TextureFlags;
|
||||||
|
|
||||||
@ -88,18 +89,20 @@ enum LayerRenderStateFlags {
|
|||||||
struct LayerRenderState {
|
struct LayerRenderState {
|
||||||
LayerRenderState()
|
LayerRenderState()
|
||||||
#ifdef MOZ_WIDGET_GONK
|
#ifdef MOZ_WIDGET_GONK
|
||||||
: mSurface(nullptr), mFlags(0), mHasOwnOffset(false)
|
: mSurface(nullptr), mFlags(0), mHasOwnOffset(false), mTexture(nullptr)
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_GONK
|
#ifdef MOZ_WIDGET_GONK
|
||||||
LayerRenderState(android::GraphicBuffer* aSurface,
|
LayerRenderState(android::GraphicBuffer* aSurface,
|
||||||
const nsIntSize& aSize,
|
const nsIntSize& aSize,
|
||||||
uint32_t aFlags)
|
uint32_t aFlags,
|
||||||
|
TextureHost* aTexture)
|
||||||
: mSurface(aSurface)
|
: mSurface(aSurface)
|
||||||
, mSize(aSize)
|
, mSize(aSize)
|
||||||
, mFlags(aFlags)
|
, mFlags(aFlags)
|
||||||
, mHasOwnOffset(false)
|
, mHasOwnOffset(false)
|
||||||
|
, mTexture(aTexture)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool YFlipped() const
|
bool YFlipped() const
|
||||||
@ -123,6 +126,7 @@ struct LayerRenderState {
|
|||||||
android::sp<android::GraphicBuffer> mSurface;
|
android::sp<android::GraphicBuffer> mSurface;
|
||||||
// size of mSurface
|
// size of mSurface
|
||||||
nsIntSize mSize;
|
nsIntSize mSize;
|
||||||
|
TextureHost* mTexture;
|
||||||
#endif
|
#endif
|
||||||
// see LayerRenderStateFlags
|
// see LayerRenderStateFlags
|
||||||
uint32_t mFlags;
|
uint32_t mFlags;
|
||||||
|
@ -378,6 +378,20 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
|
|||||||
->SetDescriptorFromReply(ots.textureId(), ots.image());
|
->SetDescriptorFromReply(ots.textureId(), ots.image());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EditReply::TReturnReleaseFence: {
|
||||||
|
const ReturnReleaseFence& rep = reply.get_ReturnReleaseFence();
|
||||||
|
FenceHandle fence = rep.fence();
|
||||||
|
PTextureChild* child = rep.textureChild();
|
||||||
|
|
||||||
|
if (!fence.IsValid() || !child) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
|
||||||
|
if (texture) {
|
||||||
|
texture->SetReleaseFenceHandle(fence);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NS_RUNTIMEABORT("not reached");
|
NS_RUNTIMEABORT("not reached");
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder
|
#include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder
|
||||||
#include "mozilla/layers/SharedPlanarYCbCrImage.h"
|
#include "mozilla/layers/SharedPlanarYCbCrImage.h"
|
||||||
#include "mozilla/layers/YCbCrImageDataSerializer.h"
|
#include "mozilla/layers/YCbCrImageDataSerializer.h"
|
||||||
#include "mozilla/layers/PTextureChild.h"
|
|
||||||
#include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc
|
#include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc
|
||||||
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
||||||
#include "ImageContainer.h" // for PlanarYCbCrImage, etc
|
#include "ImageContainer.h" // for PlanarYCbCrImage, etc
|
||||||
@ -159,6 +158,13 @@ TextureClient::DestroyIPDLActor(PTextureChild* actor)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
TextureClient*
|
||||||
|
TextureClient::AsTextureClient(PTextureChild* actor)
|
||||||
|
{
|
||||||
|
return actor? static_cast<TextureChild*>(actor)->mTextureClient : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
|
TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
|
||||||
{
|
{
|
||||||
|
@ -17,10 +17,12 @@
|
|||||||
#include "mozilla/gfx/2D.h" // for DrawTarget
|
#include "mozilla/gfx/2D.h" // for DrawTarget
|
||||||
#include "mozilla/gfx/Point.h" // for IntSize
|
#include "mozilla/gfx/Point.h" // for IntSize
|
||||||
#include "mozilla/gfx/Types.h" // for SurfaceFormat
|
#include "mozilla/gfx/Types.h" // for SurfaceFormat
|
||||||
|
#include "mozilla/layers/FenceUtils.h" // for FenceHandle
|
||||||
#include "mozilla/ipc/Shmem.h" // for Shmem
|
#include "mozilla/ipc/Shmem.h" // for Shmem
|
||||||
#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
|
#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
|
||||||
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
|
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
|
||||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
||||||
|
#include "mozilla/layers/PTextureChild.h" // for PTextureChild
|
||||||
#include "mozilla/mozalloc.h" // for operator delete
|
#include "mozilla/mozalloc.h" // for operator delete
|
||||||
#include "nsAutoPtr.h" // for nsRefPtr
|
#include "nsAutoPtr.h" // for nsRefPtr
|
||||||
#include "nsCOMPtr.h" // for already_AddRefed
|
#include "nsCOMPtr.h" // for already_AddRefed
|
||||||
@ -230,6 +232,11 @@ public:
|
|||||||
static PTextureChild* CreateIPDLActor();
|
static PTextureChild* CreateIPDLActor();
|
||||||
static bool DestroyIPDLActor(PTextureChild* actor);
|
static bool DestroyIPDLActor(PTextureChild* actor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the TextureClient corresponding to the actor passed in parameter.
|
||||||
|
*/
|
||||||
|
static TextureClient* AsTextureClient(PTextureChild* actor);
|
||||||
|
|
||||||
virtual bool IsAllocated() const = 0;
|
virtual bool IsAllocated() const = 0;
|
||||||
|
|
||||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
|
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
|
||||||
@ -287,6 +294,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
void ForceRemove();
|
void ForceRemove();
|
||||||
|
|
||||||
|
virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) {}
|
||||||
|
|
||||||
|
const FenceHandle& GetReleaseFenceHandle() const
|
||||||
|
{
|
||||||
|
return FenceHandle();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Called once, just before the destructor.
|
* Called once, just before the destructor.
|
||||||
|
@ -36,6 +36,9 @@ CompositableHost::CompositableHost(const TextureInfo& aTextureInfo)
|
|||||||
CompositableHost::~CompositableHost()
|
CompositableHost::~CompositableHost()
|
||||||
{
|
{
|
||||||
MOZ_COUNT_DTOR(CompositableHost);
|
MOZ_COUNT_DTOR(CompositableHost);
|
||||||
|
if (mBackendData) {
|
||||||
|
mBackendData->ClearData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -62,6 +65,8 @@ CompositableHost::UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
|
|||||||
void
|
void
|
||||||
CompositableHost::RemoveTextureHost(TextureHost* aTexture)
|
CompositableHost::RemoveTextureHost(TextureHost* aTexture)
|
||||||
{
|
{
|
||||||
|
// Clear strong refrence to CompositableBackendSpecificData
|
||||||
|
aTexture->SetCompositableBackendSpecificData(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
|
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
|
||||||
#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
|
#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
|
||||||
#include "mozilla/layers/PCompositableParent.h"
|
#include "mozilla/layers/PCompositableParent.h"
|
||||||
|
#include "mozilla/layers/TextureHost.h" // for TextureHost
|
||||||
#include "mozilla/mozalloc.h" // for operator delete
|
#include "mozilla/mozalloc.h" // for operator delete
|
||||||
#include "nsCOMPtr.h" // for already_AddRefed
|
#include "nsCOMPtr.h" // for already_AddRefed
|
||||||
#include "nsRegion.h" // for nsIntRegion
|
#include "nsRegion.h" // for nsIntRegion
|
||||||
@ -46,7 +47,6 @@ struct TiledLayerProperties
|
|||||||
|
|
||||||
class Layer;
|
class Layer;
|
||||||
class DeprecatedTextureHost;
|
class DeprecatedTextureHost;
|
||||||
class TextureHost;
|
|
||||||
class SurfaceDescriptor;
|
class SurfaceDescriptor;
|
||||||
class Compositor;
|
class Compositor;
|
||||||
class ISurfaceAllocator;
|
class ISurfaceAllocator;
|
||||||
@ -70,7 +70,45 @@ public:
|
|||||||
MOZ_COUNT_DTOR(CompositableBackendSpecificData);
|
MOZ_COUNT_DTOR(CompositableBackendSpecificData);
|
||||||
}
|
}
|
||||||
virtual void SetCompositor(Compositor* aCompositor) {}
|
virtual void SetCompositor(Compositor* aCompositor) {}
|
||||||
virtual void ClearData() {}
|
virtual void ClearData()
|
||||||
|
{
|
||||||
|
mCurrentReleaseFenceTexture = nullptr;
|
||||||
|
ClearPendingReleaseFenceTextureList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a texture currently used for Composition.
|
||||||
|
* This function is called when the texutre might receive ReleaseFence
|
||||||
|
* as a result of Composition.
|
||||||
|
*/
|
||||||
|
void SetCurrentReleaseFenceTexture(TextureHost* aTexture)
|
||||||
|
{
|
||||||
|
if (mCurrentReleaseFenceTexture) {
|
||||||
|
mPendingReleaseFenceTextures.push_back(mCurrentReleaseFenceTexture);
|
||||||
|
}
|
||||||
|
mCurrentReleaseFenceTexture = aTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::vector< RefPtr<TextureHost> >& GetPendingReleaseFenceTextureList()
|
||||||
|
{
|
||||||
|
return mPendingReleaseFenceTextures;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ClearPendingReleaseFenceTextureList()
|
||||||
|
{
|
||||||
|
return mPendingReleaseFenceTextures.clear();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Store a TextureHost currently used for Composition
|
||||||
|
* and it might receive ReleaseFence for the texutre.
|
||||||
|
*/
|
||||||
|
RefPtr<TextureHost> mCurrentReleaseFenceTexture;
|
||||||
|
/**
|
||||||
|
* Store TextureHosts that might have ReleaseFence to be delivered
|
||||||
|
* to TextureClient by CompositableHost.
|
||||||
|
*/
|
||||||
|
std::vector< RefPtr<TextureHost> > mPendingReleaseFenceTextures;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,6 +89,12 @@ TextureHost::AsTextureHost(PTextureParent* actor)
|
|||||||
return actor? static_cast<TextureParent*>(actor)->mTextureHost : nullptr;
|
return actor? static_cast<TextureParent*>(actor)->mTextureHost : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PTextureParent*
|
||||||
|
TextureHost::GetIPDLActor()
|
||||||
|
{
|
||||||
|
return mActor;
|
||||||
|
}
|
||||||
|
|
||||||
// implemented in TextureOGL.cpp
|
// implemented in TextureOGL.cpp
|
||||||
TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostOGL(SurfaceDescriptorType aDescriptorType,
|
TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostOGL(SurfaceDescriptorType aDescriptorType,
|
||||||
uint32_t aDeprecatedTextureHostFlags,
|
uint32_t aDeprecatedTextureHostFlags,
|
||||||
@ -242,7 +248,8 @@ TextureHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData*
|
|||||||
|
|
||||||
|
|
||||||
TextureHost::TextureHost(TextureFlags aFlags)
|
TextureHost::TextureHost(TextureFlags aFlags)
|
||||||
: mFlags(aFlags)
|
: mActor(nullptr)
|
||||||
|
, mFlags(aFlags)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TextureHost::~TextureHost()
|
TextureHost::~TextureHost()
|
||||||
@ -723,6 +730,7 @@ TextureParent::Init(const SurfaceDescriptor& aSharedData,
|
|||||||
mTextureHost = TextureHost::Create(aSharedData,
|
mTextureHost = TextureHost::Create(aSharedData,
|
||||||
mAllocator,
|
mAllocator,
|
||||||
aFlags);
|
aFlags);
|
||||||
|
mTextureHost->mActor = this;
|
||||||
return !!mTextureHost;
|
return !!mTextureHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,6 +768,8 @@ TextureParent::ActorDestroy(ActorDestroyReason why)
|
|||||||
if (mTextureHost->GetFlags() & TEXTURE_DEALLOCATE_CLIENT) {
|
if (mTextureHost->GetFlags() & TEXTURE_DEALLOCATE_CLIENT) {
|
||||||
mTextureHost->ForgetSharedData();
|
mTextureHost->ForgetSharedData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTextureHost->mActor = nullptr;
|
||||||
mTextureHost = nullptr;
|
mTextureHost = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ class CompositableHost;
|
|||||||
class CompositableBackendSpecificData;
|
class CompositableBackendSpecificData;
|
||||||
class SurfaceDescriptor;
|
class SurfaceDescriptor;
|
||||||
class ISurfaceAllocator;
|
class ISurfaceAllocator;
|
||||||
|
class TextureHostOGL;
|
||||||
class TextureSourceOGL;
|
class TextureSourceOGL;
|
||||||
class TextureSourceD3D9;
|
class TextureSourceD3D9;
|
||||||
class TextureSourceD3D11;
|
class TextureSourceD3D11;
|
||||||
@ -273,7 +274,6 @@ class TextureHost
|
|||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
friend class AtomicRefCountedWithFinalize<TextureHost>;
|
friend class AtomicRefCountedWithFinalize<TextureHost>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextureHost(TextureFlags aFlags);
|
TextureHost(TextureFlags aFlags);
|
||||||
|
|
||||||
@ -395,6 +395,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
static TextureHost* AsTextureHost(PTextureParent* actor);
|
static TextureHost* AsTextureHost(PTextureParent* actor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a pointer to the IPDLActor.
|
||||||
|
*
|
||||||
|
* This is to be used with IPDL messages only. Do not store the returned
|
||||||
|
* pointer.
|
||||||
|
*/
|
||||||
|
PTextureParent* GetIPDLActor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specific to B2G's Composer2D
|
* Specific to B2G's Composer2D
|
||||||
* XXX - more doc here
|
* XXX - more doc here
|
||||||
@ -418,9 +426,17 @@ public:
|
|||||||
virtual const char *Name() { return "TextureHost"; }
|
virtual const char *Name() { return "TextureHost"; }
|
||||||
virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
|
virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast to a TextureHost for each backend.
|
||||||
|
*/
|
||||||
|
virtual TextureHostOGL* AsHostOGL() { return nullptr; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
PTextureParent* mActor;
|
||||||
TextureFlags mFlags;
|
TextureFlags mFlags;
|
||||||
RefPtr<CompositableBackendSpecificData> mCompositableBackendData;
|
RefPtr<CompositableBackendSpecificData> mCompositableBackendData;
|
||||||
|
|
||||||
|
friend class TextureParent;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "CompositableTransactionParent.h"
|
#include "CompositableTransactionParent.h"
|
||||||
#include "CompositableHost.h" // for CompositableParent, etc
|
#include "CompositableHost.h" // for CompositableParent, etc
|
||||||
#include "CompositorParent.h" // for CompositorParent
|
#include "CompositorParent.h" // for CompositorParent
|
||||||
|
#include "GLContext.h" // for GLContext
|
||||||
#include "Layers.h" // for Layer
|
#include "Layers.h" // for Layer
|
||||||
#include "RenderTrace.h" // for RenderTraceInvalidateEnd, etc
|
#include "RenderTrace.h" // for RenderTraceInvalidateEnd, etc
|
||||||
#include "TiledLayerBuffer.h" // for TiledLayerComposer
|
#include "TiledLayerBuffer.h" // for TiledLayerComposer
|
||||||
@ -19,6 +20,7 @@
|
|||||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
||||||
#include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG
|
#include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG
|
||||||
#include "mozilla/layers/TextureHost.h" // for TextureHost
|
#include "mozilla/layers/TextureHost.h" // for TextureHost
|
||||||
|
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
|
||||||
#include "mozilla/layers/ThebesLayerComposite.h"
|
#include "mozilla/layers/ThebesLayerComposite.h"
|
||||||
#include "mozilla/mozalloc.h" // for operator delete
|
#include "mozilla/mozalloc.h" // for operator delete
|
||||||
#include "nsDebug.h" // for NS_WARNING, NS_ASSERTION
|
#include "nsDebug.h" // for NS_WARNING, NS_ASSERTION
|
||||||
@ -159,6 +161,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
|||||||
RenderTraceInvalidateEnd(layer, "FF00FF");
|
RenderTraceInvalidateEnd(layer, "FF00FF");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return texure data to client if necessary
|
||||||
|
ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CompositableOperation::TOpPaintTextureRegion: {
|
case CompositableOperation::TOpPaintTextureRegion: {
|
||||||
@ -190,6 +194,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
|||||||
OpContentBufferSwap(compositableParent, nullptr, frontUpdatedRegion));
|
OpContentBufferSwap(compositableParent, nullptr, frontUpdatedRegion));
|
||||||
|
|
||||||
RenderTraceInvalidateEnd(thebes, "FF00FF");
|
RenderTraceInvalidateEnd(thebes, "FF00FF");
|
||||||
|
// return texure data to client if necessary
|
||||||
|
ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CompositableOperation::TOpPaintTextureIncremental: {
|
case CompositableOperation::TOpPaintTextureIncremental: {
|
||||||
@ -239,6 +245,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
|||||||
|
|
||||||
MOZ_ASSERT(tex.get());
|
MOZ_ASSERT(tex.get());
|
||||||
compositable->RemoveTextureHost(tex);
|
compositable->RemoveTextureHost(tex);
|
||||||
|
// return texure data to client if necessary
|
||||||
|
ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CompositableOperation::TOpUseTexture: {
|
case CompositableOperation::TOpUseTexture: {
|
||||||
@ -257,6 +265,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
|||||||
compositable->GetLayer()->SetInvalidRectToVisibleRegion();
|
compositable->GetLayer()->SetInvalidRectToVisibleRegion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// return texure data to client if necessary
|
||||||
|
ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CompositableOperation::TOpUseComponentAlphaTextures: {
|
case CompositableOperation::TOpUseComponentAlphaTextures: {
|
||||||
@ -271,6 +281,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
|||||||
if (IsAsync()) {
|
if (IsAsync()) {
|
||||||
ScheduleComposition(op);
|
ScheduleComposition(op);
|
||||||
}
|
}
|
||||||
|
// return texure data to client if necessary
|
||||||
|
ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CompositableOperation::TOpUpdateTexture: {
|
case CompositableOperation::TOpUpdateTexture: {
|
||||||
@ -281,7 +293,6 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
|||||||
texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion
|
texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion
|
||||||
? &op.region().get_nsIntRegion()
|
? &op.region().get_nsIntRegion()
|
||||||
: nullptr); // no region means invalidate the entire surface
|
: nullptr); // no region means invalidate the entire surface
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,6 +304,54 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
void
|
||||||
|
CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable,
|
||||||
|
EditReplyVector& replyv,
|
||||||
|
PCompositableParent* aParent)
|
||||||
|
{
|
||||||
|
if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector< RefPtr<TextureHost> > textureList =
|
||||||
|
aCompositable->GetCompositableBackendSpecificData()->GetPendingReleaseFenceTextureList();
|
||||||
|
// Return pending Texture data
|
||||||
|
for (size_t i = 0; i < textureList.size(); i++) {
|
||||||
|
TextureHostOGL* hostOGL = textureList[i]->AsHostOGL();
|
||||||
|
PTextureParent* actor = textureList[i]->GetIPDLActor();
|
||||||
|
if (!hostOGL || !actor) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
|
||||||
|
if (fence.get() && fence->isValid()) {
|
||||||
|
FenceHandle handle = FenceHandle(fence);
|
||||||
|
replyv.push_back(ReturnReleaseFence(aParent, nullptr, actor, nullptr, handle));
|
||||||
|
// Hold fence handle to prevent fence's file descriptor is closed before IPC happens.
|
||||||
|
mPrevFenceHandles.push_back(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable,
|
||||||
|
EditReplyVector& replyv,
|
||||||
|
PCompositableParent* aParent)
|
||||||
|
{
|
||||||
|
if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
CompositableParentManager::ClearPrevFenceHandles()
|
||||||
|
{
|
||||||
|
mPrevFenceHandles.clear();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
|
class CompositableHost;
|
||||||
|
|
||||||
typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
|
typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
|
||||||
|
|
||||||
// Since PCompositble has two potential manager protocols, we can't just call
|
// Since PCompositble has two potential manager protocols, we can't just call
|
||||||
@ -37,6 +39,14 @@ protected:
|
|||||||
* thread (ImageBridge for instance).
|
* thread (ImageBridge for instance).
|
||||||
*/
|
*/
|
||||||
virtual bool IsAsync() const { return false; }
|
virtual bool IsAsync() const { return false; }
|
||||||
|
|
||||||
|
void ReturnTextureDataIfNecessary(CompositableHost* aCompositable,
|
||||||
|
EditReplyVector& replyv,
|
||||||
|
PCompositableParent* aParent);
|
||||||
|
void ClearPrevFenceHandles();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<FenceHandle> mPrevFenceHandles;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
43
gfx/layers/ipc/FenceUtils.h
Normal file
43
gfx/layers/ipc/FenceUtils.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* vim: sw=2 ts=8 et :
|
||||||
|
*/
|
||||||
|
/* 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 IPC_FencerUtils_h
|
||||||
|
#define IPC_FencerUtils_h
|
||||||
|
|
||||||
|
#include "ipc/IPCMessageUtils.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FenceHandle is used for delivering Fence object via ipc.
|
||||||
|
*/
|
||||||
|
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
# include "mozilla/layers/FenceUtilsGonk.h"
|
||||||
|
#else
|
||||||
|
namespace mozilla {
|
||||||
|
namespace layers {
|
||||||
|
struct FenceHandle {
|
||||||
|
bool operator==(const FenceHandle&) const { return false; }
|
||||||
|
bool IsValid() const { return false; }
|
||||||
|
};
|
||||||
|
} // namespace layers
|
||||||
|
} // namespace mozilla
|
||||||
|
#endif // MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
|
||||||
|
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
#else
|
||||||
|
template <>
|
||||||
|
struct ParamTraits<mozilla::layers::FenceHandle> {
|
||||||
|
typedef mozilla::layers::FenceHandle paramType;
|
||||||
|
static void Write(Message*, const paramType&) {}
|
||||||
|
static bool Read(const Message*, void**, paramType*) { return false; }
|
||||||
|
};
|
||||||
|
#endif // MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
|
||||||
|
} // namespace IPC
|
||||||
|
|
||||||
|
#endif // IPC_FencerUtils_h
|
96
gfx/layers/ipc/FenceUtilsGonk.cpp
Normal file
96
gfx/layers/ipc/FenceUtilsGonk.cpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* vim: sw=2 ts=8 et :
|
||||||
|
*/
|
||||||
|
/* 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 "GLContext.h"
|
||||||
|
#include "mozilla/unused.h"
|
||||||
|
#include "nsXULAppAPI.h"
|
||||||
|
|
||||||
|
#include "FenceUtilsGonk.h"
|
||||||
|
|
||||||
|
using namespace android;
|
||||||
|
using namespace base;
|
||||||
|
using namespace mozilla::layers;
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
|
||||||
|
void
|
||||||
|
ParamTraits<FenceHandle>::Write(Message* aMsg,
|
||||||
|
const paramType& aParam)
|
||||||
|
{
|
||||||
|
Flattenable *flattenable = aParam.mFence.get();
|
||||||
|
size_t nbytes = flattenable->getFlattenedSize();
|
||||||
|
size_t nfds = flattenable->getFdCount();
|
||||||
|
|
||||||
|
char data[nbytes];
|
||||||
|
int fds[nfds];
|
||||||
|
flattenable->flatten(data, nbytes, fds, nfds);
|
||||||
|
|
||||||
|
aMsg->WriteSize(nbytes);
|
||||||
|
aMsg->WriteSize(nfds);
|
||||||
|
|
||||||
|
aMsg->WriteBytes(data, nbytes);
|
||||||
|
for (size_t n = 0; n < nfds; ++n) {
|
||||||
|
// These buffers can't die in transit because they're created
|
||||||
|
// synchonously and the parent-side buffer can only be dropped if
|
||||||
|
// there's a crash.
|
||||||
|
aMsg->WriteFileDescriptor(FileDescriptor(fds[n], false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ParamTraits<FenceHandle>::Read(const Message* aMsg,
|
||||||
|
void** aIter, paramType* aResult)
|
||||||
|
{
|
||||||
|
size_t nbytes;
|
||||||
|
size_t nfds;
|
||||||
|
const char* data;
|
||||||
|
|
||||||
|
if (!aMsg->ReadSize(aIter, &nbytes) ||
|
||||||
|
!aMsg->ReadSize(aIter, &nfds) ||
|
||||||
|
!aMsg->ReadBytes(aIter, &data, nbytes)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fds[nfds];
|
||||||
|
|
||||||
|
for (size_t n = 0; n < nfds; ++n) {
|
||||||
|
FileDescriptor fd;
|
||||||
|
if (!aMsg->ReadFileDescriptor(aIter, &fd)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// If the GraphicBuffer was shared cross-process, SCM_RIGHTS does
|
||||||
|
// the right thing and dup's the fd. If it's shared cross-thread,
|
||||||
|
// SCM_RIGHTS doesn't dup the fd. That's surprising, but we just
|
||||||
|
// deal with it here. NB: only the "default" (master) process can
|
||||||
|
// alloc gralloc buffers.
|
||||||
|
bool sameProcess = (XRE_GetProcessType() == GeckoProcessType_Default);
|
||||||
|
int dupFd = sameProcess ? dup(fd.fd) : fd.fd;
|
||||||
|
fds[n] = dupFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<Fence> buffer(new Fence());
|
||||||
|
Flattenable *flattenable = buffer.get();
|
||||||
|
|
||||||
|
if (NO_ERROR == flattenable->unflatten(data, nbytes, fds, nfds)) {
|
||||||
|
aResult->mFence = buffer;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace IPC
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace layers {
|
||||||
|
|
||||||
|
FenceHandle::FenceHandle(const sp<Fence>& aFence)
|
||||||
|
: mFence(aFence)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace layers
|
||||||
|
} // namespace mozilla
|
53
gfx/layers/ipc/FenceUtilsGonk.h
Normal file
53
gfx/layers/ipc/FenceUtilsGonk.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* vim: sw=2 ts=8 et :
|
||||||
|
*/
|
||||||
|
/* 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_layers_FenceUtilsGonk_h
|
||||||
|
#define mozilla_layers_FenceUtilsGonk_h
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ui/Fence.h>
|
||||||
|
|
||||||
|
#include "ipc/IPCMessageUtils.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace layers {
|
||||||
|
|
||||||
|
struct FenceHandle {
|
||||||
|
typedef android::Fence Fence;
|
||||||
|
|
||||||
|
FenceHandle()
|
||||||
|
{ }
|
||||||
|
FenceHandle(const android::sp<Fence>& aFence);
|
||||||
|
|
||||||
|
bool operator==(const FenceHandle& aOther) const {
|
||||||
|
return mFence.get() == aOther.mFence.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid() const
|
||||||
|
{
|
||||||
|
return mFence.get() && mFence->isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
android::sp<Fence> mFence;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace layers
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
namespace IPC {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct ParamTraits<mozilla::layers::FenceHandle> {
|
||||||
|
typedef mozilla::layers::FenceHandle paramType;
|
||||||
|
|
||||||
|
static void Write(Message* aMsg, const paramType& aParam);
|
||||||
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace IPC
|
||||||
|
|
||||||
|
#endif // mozilla_layers_FenceUtilsGonk_h
|
@ -516,6 +516,20 @@ ImageBridgeChild::EndTransaction()
|
|||||||
->SetDescriptorFromReply(ots.textureId(), ots.image());
|
->SetDescriptorFromReply(ots.textureId(), ots.image());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case EditReply::TReturnReleaseFence: {
|
||||||
|
const ReturnReleaseFence& rep = reply.get_ReturnReleaseFence();
|
||||||
|
FenceHandle fence = rep.fence();
|
||||||
|
PTextureChild* child = rep.textureChild();
|
||||||
|
|
||||||
|
if (!fence.IsValid() || !child) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
|
||||||
|
if (texture) {
|
||||||
|
texture->SetReleaseFenceHandle(fence);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
NS_RUNTIMEABORT("not reached");
|
NS_RUNTIMEABORT("not reached");
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,9 @@ ImageBridgeParent::RecvUpdate(const EditArray& aEdits, EditReplyArray* aReply)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear fence handles used in previsou transaction.
|
||||||
|
ClearPrevFenceHandles();
|
||||||
|
|
||||||
EditReplyVector replyv;
|
EditReplyVector replyv;
|
||||||
for (EditArray::index_type i = 0; i < aEdits.Length(); ++i) {
|
for (EditArray::index_type i = 0; i < aEdits.Length(); ++i) {
|
||||||
ReceiveCompositableUpdate(aEdits[i], replyv);
|
ReceiveCompositableUpdate(aEdits[i], replyv);
|
||||||
|
@ -204,6 +204,9 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear fence handles used in previsou transaction.
|
||||||
|
ClearPrevFenceHandles();
|
||||||
|
|
||||||
EditReplyVector replyv;
|
EditReplyVector replyv;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -39,6 +39,7 @@ using mozilla::layers::ScaleMode from "mozilla/layers/LayersTypes.h";
|
|||||||
using mozilla::layers::EventRegions from "mozilla/layers/LayersTypes.h";
|
using mozilla::layers::EventRegions from "mozilla/layers/LayersTypes.h";
|
||||||
using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
|
using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
|
||||||
using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
|
using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
|
||||||
|
using struct mozilla::layers::FenceHandle from "mozilla/layers/FenceUtils.h";
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
@ -396,11 +397,19 @@ struct OpTextureSwap {
|
|||||||
SurfaceDescriptor image;
|
SurfaceDescriptor image;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ReturnReleaseFence {
|
||||||
|
PCompositable compositable;
|
||||||
|
PTexture texture;
|
||||||
|
FenceHandle fence;
|
||||||
|
};
|
||||||
|
|
||||||
// Unit of a "changeset reply". This is a weird abstraction, probably
|
// Unit of a "changeset reply". This is a weird abstraction, probably
|
||||||
// only to be used for buffer swapping.
|
// only to be used for buffer swapping.
|
||||||
union EditReply {
|
union EditReply {
|
||||||
OpContentBufferSwap;
|
OpContentBufferSwap;
|
||||||
OpTextureSwap;
|
OpTextureSwap;
|
||||||
|
|
||||||
|
ReturnReleaseFence;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -129,6 +129,7 @@ EXPORTS.mozilla.layers += [
|
|||||||
'ipc/CompositableTransactionParent.h',
|
'ipc/CompositableTransactionParent.h',
|
||||||
'ipc/CompositorChild.h',
|
'ipc/CompositorChild.h',
|
||||||
'ipc/CompositorParent.h',
|
'ipc/CompositorParent.h',
|
||||||
|
'ipc/FenceUtils.h',
|
||||||
'ipc/GeckoContentController.h',
|
'ipc/GeckoContentController.h',
|
||||||
'ipc/GestureEventListener.h',
|
'ipc/GestureEventListener.h',
|
||||||
'ipc/ImageBridgeChild.h',
|
'ipc/ImageBridgeChild.h',
|
||||||
@ -202,6 +203,14 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
|||||||
'ipc/ShadowLayerUtilsGralloc.cpp',
|
'ipc/ShadowLayerUtilsGralloc.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if CONFIG['ANDROID_VERSION'] in ('18'):
|
||||||
|
EXPORTS.mozilla.layers += [
|
||||||
|
'ipc/FenceUtilsGonk.h',
|
||||||
|
]
|
||||||
|
SOURCES += [
|
||||||
|
'ipc/FenceUtilsGonk.cpp',
|
||||||
|
]
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'basic/BasicCanvasLayer.cpp',
|
'basic/BasicCanvasLayer.cpp',
|
||||||
'basic/BasicColorLayer.cpp',
|
'basic/BasicColorLayer.cpp',
|
||||||
|
@ -196,6 +196,16 @@ GrallocTextureClientOGL::UpdateSurface(gfxASurface* aSurface)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
|
||||||
|
{
|
||||||
|
if (mBufferLocked) {
|
||||||
|
mBufferLocked->SetReleaseFenceHandle(aReleaseFenceHandle);
|
||||||
|
} else {
|
||||||
|
mReleaseFenceHandle = aReleaseFenceHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GrallocTextureClientOGL::Lock(OpenMode aMode)
|
GrallocTextureClientOGL::Lock(OpenMode aMode)
|
||||||
{
|
{
|
||||||
@ -207,6 +217,13 @@ GrallocTextureClientOGL::Lock(OpenMode aMode)
|
|||||||
if (mMappedBuffer) {
|
if (mMappedBuffer) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mReleaseFenceHandle.IsValid()) {
|
||||||
|
android::sp<Fence> fence = mReleaseFenceHandle.mFence;
|
||||||
|
fence->waitForever("GrallocTextureClientOGL::Lock");
|
||||||
|
mReleaseFenceHandle = FenceHandle();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t usage = 0;
|
uint32_t usage = 0;
|
||||||
if (aMode & OPEN_READ) {
|
if (aMode & OPEN_READ) {
|
||||||
usage |= GRALLOC_USAGE_SW_READ_OFTEN;
|
usage |= GRALLOC_USAGE_SW_READ_OFTEN;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "mozilla/layers/TextureClient.h"
|
#include "mozilla/layers/TextureClient.h"
|
||||||
#include "ISurfaceAllocator.h" // For IsSurfaceDescriptorValid
|
#include "ISurfaceAllocator.h" // For IsSurfaceDescriptorValid
|
||||||
|
#include "mozilla/layers/FenceUtils.h" // for FenceHandle
|
||||||
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
|
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
|
||||||
#include <ui/GraphicBuffer.h>
|
#include <ui/GraphicBuffer.h>
|
||||||
|
|
||||||
@ -59,6 +60,13 @@ public:
|
|||||||
|
|
||||||
virtual TextureClientData* DropTextureData() MOZ_OVERRIDE;
|
virtual TextureClientData* DropTextureData() MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
const FenceHandle& GetReleaseFenceHandle() const
|
||||||
|
{
|
||||||
|
return mReleaseFenceHandle;
|
||||||
|
}
|
||||||
|
|
||||||
void InitWith(GrallocBufferActor* aActor, gfx::IntSize aSize);
|
void InitWith(GrallocBufferActor* aActor, gfx::IntSize aSize);
|
||||||
|
|
||||||
void SetTextureFlags(TextureFlags aFlags) { AddFlags(aFlags); }
|
void SetTextureFlags(TextureFlags aFlags) { AddFlags(aFlags); }
|
||||||
@ -110,6 +118,8 @@ protected:
|
|||||||
|
|
||||||
android::sp<android::GraphicBuffer> mGraphicBuffer;
|
android::sp<android::GraphicBuffer> mGraphicBuffer;
|
||||||
|
|
||||||
|
FenceHandle mReleaseFenceHandle;
|
||||||
|
|
||||||
RefPtr<ISurfaceAllocator> mAllocator;
|
RefPtr<ISurfaceAllocator> mAllocator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -332,7 +332,8 @@ GrallocTextureHostOGL::GetRenderState()
|
|||||||
}
|
}
|
||||||
return LayerRenderState(mTextureSource->mGraphicBuffer.get(),
|
return LayerRenderState(mTextureSource->mGraphicBuffer.get(),
|
||||||
gfx::ThebesIntSize(mSize),
|
gfx::ThebesIntSize(mSize),
|
||||||
flags);
|
flags,
|
||||||
|
this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return LayerRenderState();
|
return LayerRenderState();
|
||||||
@ -379,6 +380,11 @@ GrallocTextureHostOGL::SetCompositableBackendSpecificData(CompositableBackendSpe
|
|||||||
if (mTextureSource) {
|
if (mTextureSource) {
|
||||||
mTextureSource->SetCompositableBackendSpecificData(aBackendData);
|
mTextureSource->SetCompositableBackendSpecificData(aBackendData);
|
||||||
}
|
}
|
||||||
|
// Register this object to CompositableBackendSpecificData
|
||||||
|
// as current TextureHost.
|
||||||
|
if (aBackendData) {
|
||||||
|
aBackendData->SetCurrentReleaseFenceTexture(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namepsace layers
|
} // namepsace layers
|
||||||
|
@ -71,6 +71,9 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class GrallocTextureHostOGL : public TextureHost
|
class GrallocTextureHostOGL : public TextureHost
|
||||||
|
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
, public TextureHostOGL
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
friend class GrallocBufferActor;
|
friend class GrallocBufferActor;
|
||||||
public:
|
public:
|
||||||
@ -104,6 +107,13 @@ public:
|
|||||||
return mTextureSource;
|
return mTextureSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
virtual TextureHostOGL* AsHostOGL() MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
|
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE;
|
virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE;
|
||||||
|
@ -176,6 +176,7 @@ void CompositableDataGonkOGL::SetCompositor(Compositor* aCompositor)
|
|||||||
|
|
||||||
void CompositableDataGonkOGL::ClearData()
|
void CompositableDataGonkOGL::ClearData()
|
||||||
{
|
{
|
||||||
|
CompositableBackendSpecificData::ClearData();
|
||||||
DeleteTextureIfPresent();
|
DeleteTextureIfPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,6 +201,41 @@ CompositableDataGonkOGL::DeleteTextureIfPresent()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
bool
|
||||||
|
TextureHostOGL::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence)
|
||||||
|
{
|
||||||
|
if (!aReleaseFence.get() || !aReleaseFence->isValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mReleaseFence.get()) {
|
||||||
|
mReleaseFence = aReleaseFence;
|
||||||
|
} else {
|
||||||
|
android::sp<android::Fence> mergedFence = android::Fence::merge(
|
||||||
|
android::String8::format("TextureHostOGL"),
|
||||||
|
mReleaseFence, aReleaseFence);
|
||||||
|
if (!mergedFence.get()) {
|
||||||
|
// synchronization is broken, the best we can do is hope fences
|
||||||
|
// signal in order so the new fence will act like a union.
|
||||||
|
// This error handling is same as android::ConsumerBase does.
|
||||||
|
mReleaseFence = aReleaseFence;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mReleaseFence = mergedFence;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
android::sp<android::Fence>
|
||||||
|
TextureHostOGL::GetAndResetReleaseFence()
|
||||||
|
{
|
||||||
|
android::sp<android::Fence> fence = mReleaseFence;
|
||||||
|
mReleaseFence = android::Fence::NO_FENCE;
|
||||||
|
return fence;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
|
TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
|
||||||
nsIntRegion* aDestRegion,
|
nsIntRegion* aDestRegion,
|
||||||
@ -1155,7 +1191,8 @@ GrallocDeprecatedTextureHostOGL::GetRenderState()
|
|||||||
|
|
||||||
return LayerRenderState(mGraphicBuffer.get(),
|
return LayerRenderState(mGraphicBuffer.get(),
|
||||||
bufferSize,
|
bufferSize,
|
||||||
flags);
|
flags,
|
||||||
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return LayerRenderState();
|
return LayerRenderState();
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
#include "OGLShaderProgram.h" // for ShaderProgramType, etc
|
#include "OGLShaderProgram.h" // for ShaderProgramType, etc
|
||||||
#ifdef MOZ_WIDGET_GONK
|
#ifdef MOZ_WIDGET_GONK
|
||||||
#include <ui/GraphicBuffer.h>
|
#include <ui/GraphicBuffer.h>
|
||||||
|
#if ANDROID_VERSION >= 18
|
||||||
|
#include <ui/Fence.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class gfxImageSurface;
|
class gfxImageSurface;
|
||||||
@ -117,6 +120,29 @@ public:
|
|||||||
virtual TextureImageDeprecatedTextureHostOGL* AsTextureImageDeprecatedTextureHost() { return nullptr; }
|
virtual TextureImageDeprecatedTextureHostOGL* AsTextureImageDeprecatedTextureHost() { return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TextureHostOGL provides the necessary API for platform specific composition.
|
||||||
|
*/
|
||||||
|
class TextureHostOGL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 18
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a fence that will signal when the current buffer is no longer being read.
|
||||||
|
* Similar to android's GLConsumer::setReleaseFence()
|
||||||
|
*/
|
||||||
|
virtual bool SetReleaseFence(const android::sp<android::Fence>& aReleaseFence);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a releaseFence's Fence and clear a reference to the Fence.
|
||||||
|
*/
|
||||||
|
virtual android::sp<android::Fence> GetAndResetReleaseFence();
|
||||||
|
protected:
|
||||||
|
android::sp<android::Fence> mReleaseFence;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A TextureSource backed by a TextureImage.
|
* A TextureSource backed by a TextureImage.
|
||||||
*
|
*
|
||||||
|
@ -19,11 +19,13 @@
|
|||||||
|
|
||||||
#include "libdisplay/GonkDisplay.h"
|
#include "libdisplay/GonkDisplay.h"
|
||||||
#include "Framebuffer.h"
|
#include "Framebuffer.h"
|
||||||
|
#include "GLContext.h" // for GLContext
|
||||||
#include "HwcUtils.h"
|
#include "HwcUtils.h"
|
||||||
#include "HwcComposer2D.h"
|
#include "HwcComposer2D.h"
|
||||||
#include "mozilla/layers/LayerManagerComposite.h"
|
#include "mozilla/layers/LayerManagerComposite.h"
|
||||||
#include "mozilla/layers/PLayerTransaction.h"
|
#include "mozilla/layers/PLayerTransaction.h"
|
||||||
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
|
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
|
||||||
|
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "cutils/properties.h"
|
#include "cutils/properties.h"
|
||||||
#include "gfx2DGlue.h"
|
#include "gfx2DGlue.h"
|
||||||
@ -67,7 +69,10 @@ HwcComposer2D::HwcComposer2D()
|
|||||||
, mHwc(nullptr)
|
, mHwc(nullptr)
|
||||||
, mColorFill(false)
|
, mColorFill(false)
|
||||||
, mRBSwapSupport(false)
|
, mRBSwapSupport(false)
|
||||||
, mPrevRetireFence(-1)
|
#if ANDROID_VERSION >= 18
|
||||||
|
, mPrevRetireFence(Fence::NO_FENCE)
|
||||||
|
, mPrevDisplayFence(Fence::NO_FENCE)
|
||||||
|
#endif
|
||||||
, mPrepared(false)
|
, mPrepared(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -649,36 +654,29 @@ HwcComposer2D::Commit()
|
|||||||
|
|
||||||
int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
|
int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
|
||||||
|
|
||||||
// To avoid tearing, workaround for missing releaseFenceFd
|
mPrevDisplayFence = mPrevRetireFence;
|
||||||
// waits in Gecko layers, see Bug 925444.
|
mPrevRetireFence = Fence::NO_FENCE;
|
||||||
if (!mPrevReleaseFds.IsEmpty()) {
|
|
||||||
// Wait for previous retire Fence to signal.
|
|
||||||
// Denotes contents on display have been replaced.
|
|
||||||
// For buffer-sync, framework should not over-write
|
|
||||||
// prev buffers until we close prev releaseFenceFds
|
|
||||||
sp<Fence> fence = new Fence(mPrevRetireFence);
|
|
||||||
if (fence->wait(1000) == -ETIME) {
|
|
||||||
LOGE("Wait timed-out for retireFenceFd %d", mPrevRetireFence);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < mPrevReleaseFds.Length(); i++) {
|
|
||||||
close(mPrevReleaseFds[i]);
|
|
||||||
}
|
|
||||||
close(mPrevRetireFence);
|
|
||||||
mPrevReleaseFds.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t j=0; j < (mList->numHwLayers - 1); j++) {
|
for (uint32_t j=0; j < (mList->numHwLayers - 1); j++) {
|
||||||
if (mList->hwLayers[j].releaseFenceFd >= 0) {
|
if (mList->hwLayers[j].releaseFenceFd >= 0) {
|
||||||
mPrevReleaseFds.AppendElement(mList->hwLayers[j].releaseFenceFd);
|
int fd = mList->hwLayers[j].releaseFenceFd;
|
||||||
}
|
mList->hwLayers[j].releaseFenceFd = -1;
|
||||||
}
|
sp<Fence> fence = new Fence(fd);
|
||||||
|
|
||||||
|
LayerRenderState state = mHwcLayerMap[j]->GetLayer()->GetRenderState();
|
||||||
|
if (!state.mTexture) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TextureHostOGL* texture = state.mTexture->AsHostOGL();
|
||||||
|
if (!texture) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
texture->SetReleaseFence(fence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mList->retireFenceFd >= 0) {
|
if (mList->retireFenceFd >= 0) {
|
||||||
if (!mPrevReleaseFds.IsEmpty()) {
|
mPrevRetireFence = new Fence(mList->retireFenceFd);
|
||||||
mPrevRetireFence = mList->retireFenceFd;
|
|
||||||
} else { // GPU Composition
|
|
||||||
close(mList->retireFenceFd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mPrepared = false;
|
mPrepared = false;
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include <hardware/hwcomposer.h>
|
#include <hardware/hwcomposer.h>
|
||||||
|
#if ANDROID_VERSION >= 18
|
||||||
|
#include <ui/Fence.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
@ -83,8 +86,10 @@ private:
|
|||||||
//Holds all the dynamically allocated RectVectors needed
|
//Holds all the dynamically allocated RectVectors needed
|
||||||
//to render the current frame
|
//to render the current frame
|
||||||
std::list<RectVector> mVisibleRegions;
|
std::list<RectVector> mVisibleRegions;
|
||||||
nsTArray<int> mPrevReleaseFds;
|
#if ANDROID_VERSION >= 18
|
||||||
int mPrevRetireFence;
|
android::sp<android::Fence> mPrevRetireFence;
|
||||||
|
android::sp<android::Fence> mPrevDisplayFence;
|
||||||
|
#endif
|
||||||
nsTArray<layers::LayerComposite*> mHwcLayerMap;
|
nsTArray<layers::LayerComposite*> mHwcLayerMap;
|
||||||
bool mPrepared;
|
bool mPrepared;
|
||||||
};
|
};
|
||||||
|
@ -105,8 +105,7 @@ status_t GonkNativeWindow::setDefaultBufferFormat(uint32_t defaultFormat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<GraphicBufferLocked>
|
already_AddRefed<GraphicBufferLocked>
|
||||||
GonkNativeWindow::getCurrentBuffer()
|
GonkNativeWindow::getCurrentBuffer() {
|
||||||
{
|
|
||||||
Mutex::Autolock _l(mMutex);
|
Mutex::Autolock _l(mMutex);
|
||||||
GonkBufferQueue::BufferItem item;
|
GonkBufferQueue::BufferItem item;
|
||||||
|
|
||||||
@ -123,17 +122,20 @@ GonkNativeWindow::getCurrentBuffer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GonkNativeWindow::returnBuffer(uint32_t aIndex, uint32_t aGeneration) {
|
GonkNativeWindow::returnBuffer(uint32_t index, uint32_t generation, const sp<Fence>& fence) {
|
||||||
BI_LOGD("GonkNativeWindow::returnBuffer: slot=%d (generation=%d)", aIndex, aGeneration);
|
BI_LOGD("GonkNativeWindow::returnBuffer: slot=%d (generation=%d)", index, generation);
|
||||||
Mutex::Autolock lock(mMutex);
|
Mutex::Autolock lock(mMutex);
|
||||||
|
|
||||||
if (aGeneration != mBufferQueue->getGeneration()) {
|
if (generation != mBufferQueue->getGeneration()) {
|
||||||
BI_LOGD("returnBuffer: buffer is from generation %d (current is %d)",
|
BI_LOGD("returnBuffer: buffer is from generation %d (current is %d)",
|
||||||
aGeneration, mBufferQueue->getGeneration());
|
generation, mBufferQueue->getGeneration());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t err = releaseBufferLocked(aIndex);
|
status_t err;
|
||||||
|
err = addReleaseFenceLocked(index, fence);
|
||||||
|
|
||||||
|
err = releaseBufferLocked(index);
|
||||||
if (err != NO_ERROR) {
|
if (err != NO_ERROR) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -141,8 +143,7 @@ GonkNativeWindow::returnBuffer(uint32_t aIndex, uint32_t aGeneration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mozilla::layers::SurfaceDescriptor *
|
mozilla::layers::SurfaceDescriptor *
|
||||||
GonkNativeWindow::getSurfaceDescriptorFromBuffer(ANativeWindowBuffer* buffer)
|
GonkNativeWindow::getSurfaceDescriptorFromBuffer(ANativeWindowBuffer* buffer) {
|
||||||
{
|
|
||||||
Mutex::Autolock lock(mMutex);
|
Mutex::Autolock lock(mMutex);
|
||||||
return mBufferQueue->getSurfaceDescriptorFromBuffer(buffer);
|
return mBufferQueue->getSurfaceDescriptorFromBuffer(buffer);
|
||||||
}
|
}
|
||||||
@ -161,4 +162,22 @@ void GonkNativeWindow::onFrameAvailable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CameraGraphicBuffer::Unlock() {
|
||||||
|
if (mLocked) {
|
||||||
|
android::sp<android::Fence> fence;
|
||||||
|
fence = mReleaseFenceHandle.IsValid() ? mReleaseFenceHandle.mFence : Fence::NO_FENCE;
|
||||||
|
// The window might have been destroyed. The buffer is no longer
|
||||||
|
// valid at that point.
|
||||||
|
sp<GonkNativeWindow> window = mNativeWindow.promote();
|
||||||
|
if (window.get() && window->returnBuffer(mIndex, mGeneration, fence)) {
|
||||||
|
mLocked = false;
|
||||||
|
} else {
|
||||||
|
// If the window doesn't exist any more, release the buffer
|
||||||
|
// directly.
|
||||||
|
ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton();
|
||||||
|
ibc->DeallocSurfaceDescriptorGralloc(mSurfaceDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
@ -116,7 +116,7 @@ class GonkNativeWindow: public GonkConsumerBase
|
|||||||
|
|
||||||
// Return the buffer to the queue and mark it as FREE. After that
|
// Return the buffer to the queue and mark it as FREE. After that
|
||||||
// the buffer is useable again for the decoder.
|
// the buffer is useable again for the decoder.
|
||||||
bool returnBuffer(uint32_t index, uint32_t generation);
|
bool returnBuffer(uint32_t index, uint32_t generation, const sp<Fence>& fence);
|
||||||
|
|
||||||
SurfaceDescriptor* getSurfaceDescriptorFromBuffer(ANativeWindowBuffer* buffer);
|
SurfaceDescriptor* getSurfaceDescriptorFromBuffer(ANativeWindowBuffer* buffer);
|
||||||
|
|
||||||
@ -157,22 +157,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// Unlock either returns the buffer to the native window or
|
// Unlock either returns the buffer to the native window or
|
||||||
// destroys the buffer if the window is already released.
|
// destroys the buffer if the window is already released.
|
||||||
virtual void Unlock() MOZ_OVERRIDE
|
virtual void Unlock() MOZ_OVERRIDE;
|
||||||
{
|
|
||||||
if (mLocked) {
|
|
||||||
// The window might have been destroyed. The buffer is no longer
|
|
||||||
// valid at that point.
|
|
||||||
sp<GonkNativeWindow> window = mNativeWindow.promote();
|
|
||||||
if (window.get() && window->returnBuffer(mIndex, mGeneration)) {
|
|
||||||
mLocked = false;
|
|
||||||
} else {
|
|
||||||
// If the window doesn't exist any more, release the buffer
|
|
||||||
// directly.
|
|
||||||
ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton();
|
|
||||||
ibc->DeallocSurfaceDescriptorGralloc(mSurfaceDescriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wp<GonkNativeWindow> mNativeWindow;
|
wp<GonkNativeWindow> mNativeWindow;
|
||||||
|
Loading…
Reference in New Issue
Block a user