зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1234472 - Add gonk sideband stream handling to gfx ipc r=nical
This commit is contained in:
Родитель
cebf4a5bfa
Коммит
22854d8a96
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/ReentrantMonitor.h" // for ReentrantMonitorAutoEnter, etc
|
||||
#include "mozilla/TimeStamp.h" // for TimeStamp
|
||||
#include "mozilla/gfx/Point.h" // For IntSize
|
||||
#include "mozilla/layers/GonkNativeHandle.h"
|
||||
#include "mozilla/layers/LayersTypes.h" // for LayersBackend, etc
|
||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||
#include "nsAutoPtr.h" // for nsRefPtr, nsAutoArrayPtr, etc
|
||||
|
@ -846,6 +847,11 @@ public:
|
|||
gfx::IntSize mSize;
|
||||
};
|
||||
|
||||
struct SidebandStreamData {
|
||||
GonkNativeHandle mStream;
|
||||
gfx::IntSize mSize;
|
||||
};
|
||||
|
||||
OverlayImage() : Image(nullptr, ImageFormat::OVERLAY_IMAGE) { mOverlayId = INVALID_OVERLAY; }
|
||||
|
||||
void SetData(const Data& aData)
|
||||
|
@ -854,13 +860,21 @@ public:
|
|||
mSize = aData.mSize;
|
||||
}
|
||||
|
||||
void SetData(const SidebandStreamData& aData)
|
||||
{
|
||||
mSidebandStream = aData.mStream;
|
||||
mSize = aData.mSize;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() { return nullptr; } ;
|
||||
int32_t GetOverlayId() { return mOverlayId; }
|
||||
const GonkNativeHandle& GetSidebandStream() { return mSidebandStream; }
|
||||
|
||||
gfx::IntSize GetSize() { return mSize; }
|
||||
|
||||
private:
|
||||
int32_t mOverlayId;
|
||||
GonkNativeHandle mSidebandStream;
|
||||
gfx::IntSize mSize;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <utils/RefBase.h>
|
||||
#if ANDROID_VERSION >= 21
|
||||
#include <utils/NativeHandle.h>
|
||||
#endif
|
||||
#include "mozilla/layers/GonkNativeHandle.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/gfx/Point.h" // for IntPoint
|
||||
|
@ -116,13 +114,16 @@ struct LayerRenderState {
|
|||
void SetOverlayId(const int32_t& aId)
|
||||
{ mOverlayId = aId; }
|
||||
|
||||
void SetSidebandStream(const GonkNativeHandle& aStream)
|
||||
{
|
||||
mSidebandStream = aStream;
|
||||
}
|
||||
|
||||
android::GraphicBuffer* GetGrallocBuffer() const
|
||||
{ return mSurface.get(); }
|
||||
|
||||
#if ANDROID_VERSION >= 21
|
||||
android::NativeHandle* GetSidebandStream() const
|
||||
{ return mSidebandStream.get(); }
|
||||
#endif
|
||||
const GonkNativeHandle& GetSidebandStream()
|
||||
{ return mSidebandStream; }
|
||||
#endif
|
||||
|
||||
void SetOffset(const nsIntPoint& aOffset)
|
||||
|
@ -146,9 +147,7 @@ struct LayerRenderState {
|
|||
// size of mSurface
|
||||
gfx::IntSize mSize;
|
||||
TextureHost* mTexture;
|
||||
#if ANDROID_VERSION >= 21
|
||||
android::sp<android::NativeHandle> mSidebandStream;
|
||||
#endif
|
||||
GonkNativeHandle mSidebandStream;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -153,12 +153,13 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
|
|||
#ifdef MOZ_WIDGET_GONK
|
||||
if (image->GetFormat() == ImageFormat::OVERLAY_IMAGE) {
|
||||
OverlayImage* overlayImage = static_cast<OverlayImage*>(image);
|
||||
uint32_t overlayId = overlayImage->GetOverlayId();
|
||||
gfx::IntSize size = overlayImage->GetSize();
|
||||
|
||||
OverlaySource source;
|
||||
source.handle() = OverlayHandle(overlayId);
|
||||
source.size() = size;
|
||||
if (overlayImage->GetSidebandStream().IsValid()) {
|
||||
source.handle() = OverlayHandle(overlayImage->GetSidebandStream());
|
||||
} else {
|
||||
source.handle() = OverlayHandle(overlayImage->GetOverlayId());
|
||||
}
|
||||
source.size() = overlayImage->GetSize();
|
||||
GetForwarder()->UseOverlaySource(this, source, image->GetPictureRect());
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -136,8 +136,7 @@ void
|
|||
ImageHost::UseOverlaySource(OverlaySource aOverlay,
|
||||
const gfx::IntRect& aPictureRect)
|
||||
{
|
||||
if ((aOverlay.handle().type() == OverlayHandle::Tint32_t) &&
|
||||
aOverlay.handle().get_int32_t() != INVALID_OVERLAY) {
|
||||
if (ImageHostOverlay::IsValid(aOverlay)) {
|
||||
if (!mImageHostOverlay) {
|
||||
mImageHostOverlay = new ImageHostOverlay();
|
||||
}
|
||||
|
@ -590,6 +589,18 @@ ImageHostOverlay::~ImageHostOverlay()
|
|||
MOZ_COUNT_DTOR(ImageHostOverlay);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
ImageHostOverlay::IsValid(OverlaySource aOverlay)
|
||||
{
|
||||
if ((aOverlay.handle().type() == OverlayHandle::Tint32_t) &&
|
||||
aOverlay.handle().get_int32_t() != INVALID_OVERLAY) {
|
||||
return true;
|
||||
} else if (aOverlay.handle().type() == OverlayHandle::TGonkNativeHandle) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ImageHostOverlay::Composite(Compositor* aCompositor,
|
||||
uint32_t aFlashCounter,
|
||||
|
@ -627,7 +638,11 @@ ImageHostOverlay::GetRenderState()
|
|||
#ifdef MOZ_WIDGET_GONK
|
||||
if (mOverlay.handle().type() == OverlayHandle::Tint32_t) {
|
||||
state.SetOverlayId(mOverlay.handle().get_int32_t());
|
||||
} else if (mOverlay.handle().type() == OverlayHandle::TGonkNativeHandle) {
|
||||
state.SetSidebandStream(mOverlay.handle().get_GonkNativeHandle());
|
||||
}
|
||||
state.mSize.width = mPictureRect.Width();
|
||||
state.mSize.height = mPictureRect.Height();
|
||||
#endif
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -156,6 +156,8 @@ public:
|
|||
NS_INLINE_DECL_REFCOUNTING(ImageHostOverlay)
|
||||
ImageHostOverlay();
|
||||
|
||||
static bool IsValid(OverlaySource aOverlay);
|
||||
|
||||
virtual void Composite(Compositor* aCompositor,
|
||||
uint32_t aFlashCounter,
|
||||
LayerComposite* aLayer,
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- 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 <unistd.h>
|
||||
|
||||
#include "GonkNativeHandle.h"
|
||||
|
||||
using namespace mozilla::layers;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
GonkNativeHandle::GonkNativeHandle()
|
||||
: mNhObj(new NhObj())
|
||||
{
|
||||
}
|
||||
|
||||
GonkNativeHandle::GonkNativeHandle(NhObj* aNhObj)
|
||||
: mNhObj(aNhObj)
|
||||
{
|
||||
MOZ_ASSERT(aNhObj);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GonkNativeHandle::TransferToAnother(GonkNativeHandle& aHandle)
|
||||
{
|
||||
aHandle.mNhObj = this->GetAndResetNhObj();
|
||||
}
|
||||
|
||||
already_AddRefed<GonkNativeHandle::NhObj>
|
||||
GonkNativeHandle::GetAndResetNhObj()
|
||||
{
|
||||
RefPtr<NhObj> nhObj = mNhObj;
|
||||
mNhObj = new NhObj();
|
||||
return nhObj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GonkNativeHandle::NhObj>
|
||||
GonkNativeHandle::GetDupNhObj()
|
||||
{
|
||||
RefPtr<NhObj> nhObj;
|
||||
if (IsValid()) {
|
||||
native_handle* nativeHandle =
|
||||
native_handle_create(mNhObj->mHandle->numFds, mNhObj->mHandle->numInts);
|
||||
|
||||
for (int i = 0; i < mNhObj->mHandle->numFds; ++i) {
|
||||
nativeHandle->data[i] = dup(mNhObj->mHandle->data[i]);
|
||||
}
|
||||
|
||||
memcpy(nativeHandle->data + nativeHandle->numFds,
|
||||
mNhObj->mHandle->data + mNhObj->mHandle->numFds,
|
||||
sizeof(int) * mNhObj->mHandle->numInts);
|
||||
|
||||
nhObj = new GonkNativeHandle::NhObj(nativeHandle);
|
||||
} else {
|
||||
nhObj = new GonkNativeHandle::NhObj();
|
||||
}
|
||||
return nhObj.forget();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,95 @@
|
|||
/* -*- 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_GonkNativeHandle_h
|
||||
#define IPC_GonkNativeHandle_h
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <cutils/native_handle.h>
|
||||
#endif
|
||||
|
||||
#include "mozilla/RefPtr.h" // for RefPtr
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// GonkNativeHandle wraps android's native_handle_t and is used to support
|
||||
// android's sideband stream.
|
||||
// The sideband stream is a device-specific mechanism for passing buffers
|
||||
// to hwcomposer. It is used to render TV streams and DRM protected streams.
|
||||
// The native_handle_t represents device-specific kernel objects on android.
|
||||
class GonkNativeHandle {
|
||||
public:
|
||||
class NhObj {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NhObj)
|
||||
friend class GonkNativeHandle;
|
||||
public:
|
||||
NhObj()
|
||||
: mHandle(nullptr) {}
|
||||
explicit NhObj(native_handle_t* aHandle)
|
||||
: mHandle(aHandle) {}
|
||||
native_handle_t* GetAndResetNativeHandle()
|
||||
{
|
||||
native_handle_t* handle = mHandle;
|
||||
mHandle = nullptr;
|
||||
return handle;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~NhObj() {
|
||||
if (mHandle) {
|
||||
native_handle_close(mHandle);
|
||||
native_handle_delete(mHandle);
|
||||
}
|
||||
}
|
||||
|
||||
native_handle_t* mHandle;
|
||||
};
|
||||
|
||||
GonkNativeHandle();
|
||||
|
||||
explicit GonkNativeHandle(NhObj* aNhObj);
|
||||
|
||||
bool operator==(const GonkNativeHandle& aOther) const {
|
||||
return mNhObj.get() == aOther.mNhObj.get();
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return mNhObj && mNhObj->mHandle;
|
||||
}
|
||||
|
||||
void TransferToAnother(GonkNativeHandle& aHandle);
|
||||
|
||||
already_AddRefed<NhObj> GetAndResetNhObj();
|
||||
|
||||
already_AddRefed<NhObj> GetDupNhObj();
|
||||
|
||||
// Return non owning handle.
|
||||
native_handle_t* GetRawNativeHandle() const
|
||||
{
|
||||
if (mNhObj) {
|
||||
return mNhObj->mHandle;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<NhObj> mNhObj;
|
||||
};
|
||||
#else
|
||||
struct GonkNativeHandle {
|
||||
bool operator==(const GonkNativeHandle&) const { return false; }
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // IPC_GonkNativeHandle_h
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- 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 "GonkNativeHandleUtils.h"
|
||||
|
||||
using namespace mozilla::layers;
|
||||
|
||||
namespace IPC {
|
||||
|
||||
void
|
||||
ParamTraits<GonkNativeHandle>::Write(Message* aMsg,
|
||||
const paramType& aParam)
|
||||
{
|
||||
GonkNativeHandle handle = aParam;
|
||||
MOZ_ASSERT(handle.IsValid());
|
||||
|
||||
RefPtr<GonkNativeHandle::NhObj> nhObj = handle.GetAndResetNhObj();
|
||||
native_handle_t* nativeHandle = nhObj->GetAndResetNativeHandle();
|
||||
|
||||
aMsg->WriteSize(nativeHandle->numInts);
|
||||
aMsg->WriteBytes((nativeHandle->data + nativeHandle->numFds), sizeof(int) * nativeHandle->numInts);
|
||||
|
||||
for (size_t i = 0; i < static_cast<size_t>(nativeHandle->numFds); ++i) {
|
||||
aMsg->WriteFileDescriptor(base::FileDescriptor(nativeHandle->data[i], true));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ParamTraits<GonkNativeHandle>::Read(const Message* aMsg,
|
||||
void** aIter, paramType* aResult)
|
||||
{
|
||||
size_t numInts;
|
||||
if (!aMsg->ReadSize(aIter, &numInts)) {
|
||||
return false;
|
||||
}
|
||||
numInts /= sizeof(int);
|
||||
size_t numFds = aMsg->num_fds();
|
||||
native_handle* nativeHandle = native_handle_create(numFds, numInts);
|
||||
|
||||
const char* data = reinterpret_cast<const char*>(nativeHandle->data + nativeHandle->numFds);
|
||||
if (!aMsg->ReadBytes(aIter, &data, numInts * sizeof(int))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < static_cast<size_t>(nativeHandle->numFds); ++i) {
|
||||
base::FileDescriptor fd;
|
||||
if (!aMsg->ReadFileDescriptor(aIter, &fd)) {
|
||||
return false;
|
||||
}
|
||||
nativeHandle->data[i] = fd.fd;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace IPC
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- 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_GonkNativeHandleUtils_h
|
||||
#define IPC_GonkNativeHandleUtils_h
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
||||
#include "GonkNativeHandle.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
template <>
|
||||
struct ParamTraits<mozilla::layers::GonkNativeHandle> {
|
||||
typedef mozilla::layers::GonkNativeHandle paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam);
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
|
||||
};
|
||||
#else
|
||||
template <>
|
||||
struct ParamTraits<mozilla::layers::GonkNativeHandle> {
|
||||
typedef mozilla::layers::GonkNativeHandle paramType;
|
||||
static void Write(Message*, const paramType&) {}
|
||||
static bool Read(const Message*, void**, paramType*) { return false; }
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // IPC_GonkNativeHandleUtils_h
|
|
@ -14,12 +14,14 @@ using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
|
|||
using mozilla::gfx::IntRect from "mozilla/gfx/Rect.h";
|
||||
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
|
||||
using gfxImageFormat from "gfxTypes.h";
|
||||
using struct mozilla::layers::GonkNativeHandle from "mozilla/layers/GonkNativeHandleUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
union OverlayHandle {
|
||||
int32_t;
|
||||
GonkNativeHandle;
|
||||
null_t;
|
||||
};
|
||||
|
||||
|
|
|
@ -153,6 +153,8 @@ EXPORTS.mozilla.layers += [
|
|||
'ipc/CompositorLRU.h',
|
||||
'ipc/CompositorParent.h',
|
||||
'ipc/FenceUtils.h',
|
||||
'ipc/GonkNativeHandle.h',
|
||||
'ipc/GonkNativeHandleUtils.h',
|
||||
'ipc/ImageBridgeChild.h',
|
||||
'ipc/ImageBridgeParent.h',
|
||||
'ipc/ImageContainerParent.h',
|
||||
|
@ -237,6 +239,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
|||
]
|
||||
]
|
||||
SOURCES += [
|
||||
'ipc/GonkNativeHandle.cpp',
|
||||
'ipc/GonkNativeHandleUtils.cpp',
|
||||
'ipc/ShadowLayerUtilsGralloc.cpp',
|
||||
]
|
||||
|
||||
|
|
|
@ -353,7 +353,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
|||
LayerRenderState state = aLayer->GetRenderState();
|
||||
|
||||
#if ANDROID_VERSION >= 21
|
||||
if (!state.GetGrallocBuffer() && !state.GetSidebandStream()) {
|
||||
if (!state.GetGrallocBuffer() && !state.GetSidebandStream().IsValid()) {
|
||||
#else
|
||||
if (!state.GetGrallocBuffer()) {
|
||||
#endif
|
||||
|
@ -450,8 +450,8 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
|||
mHal->SetCrop(hwcLayer, sourceCrop);
|
||||
buffer_handle_t handle = nullptr;
|
||||
#if ANDROID_VERSION >= 21
|
||||
if (state.GetSidebandStream()) {
|
||||
handle = state.GetSidebandStream()->handle();
|
||||
if (state.GetSidebandStream().IsValid()) {
|
||||
handle = state.GetSidebandStream().GetRawNativeHandle();
|
||||
} else if (state.GetGrallocBuffer()) {
|
||||
handle = state.GetGrallocBuffer()->getNativeBuffer()->handle;
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
|
|||
#if ANDROID_VERSION >= 17
|
||||
hwcLayer.compositionType = HWC_FRAMEBUFFER;
|
||||
#if ANDROID_VERSION >= 21
|
||||
if (state.GetSidebandStream()) {
|
||||
if (state.GetSidebandStream().IsValid()) {
|
||||
hwcLayer.compositionType = HWC_SIDEBAND;
|
||||
}
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче