mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 894262 - Merge GonkIOSurfaceImage to GrallocImage, r=nical, kanru
This commit is contained in:
parent
a4499513a4
commit
416da61282
@ -4,7 +4,7 @@
|
||||
* 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 "GonkIOSurfaceImage.h"
|
||||
#include "GrallocImages.h"
|
||||
#include "MediaDecoderReader.h"
|
||||
#include "AbstractMediaDecoder.h"
|
||||
#include "MediaDecoderStateMachine.h"
|
||||
@ -348,16 +348,16 @@ VideoData* VideoData::Create(VideoInfo& aInfo,
|
||||
aTimecode,
|
||||
aInfo.mDisplay));
|
||||
|
||||
ImageFormat format = GONK_IO_SURFACE;
|
||||
ImageFormat format = GRALLOC_PLANAR_YCBCR;
|
||||
v->mImage = aContainer->CreateImage(&format, 1);
|
||||
if (!v->mImage) {
|
||||
return nullptr;
|
||||
}
|
||||
NS_ASSERTION(v->mImage->GetFormat() == GONK_IO_SURFACE,
|
||||
NS_ASSERTION(v->mImage->GetFormat() == GRALLOC_PLANAR_YCBCR,
|
||||
"Wrong format?");
|
||||
typedef mozilla::layers::GonkIOSurfaceImage GonkIOSurfaceImage;
|
||||
GonkIOSurfaceImage* videoImage = static_cast<GonkIOSurfaceImage*>(v->mImage.get());
|
||||
GonkIOSurfaceImage::Data data;
|
||||
typedef mozilla::layers::GrallocImage GrallocImage;
|
||||
GrallocImage* videoImage = static_cast<GrallocImage*>(v->mImage.get());
|
||||
GrallocImage::GrallocData data;
|
||||
|
||||
data.mPicSize = gfxIntSize(aPicture.width, aPicture.height);
|
||||
data.mGraphicBuffer = aBuffer;
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define MPAPI_h_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "GonkIOSurfaceImage.h"
|
||||
#include "GrallocImages.h"
|
||||
|
||||
namespace MPAPI {
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "GonkNativeWindow.h"
|
||||
#include "GonkNativeWindowClient.h"
|
||||
#include "GonkIOSurfaceImage.h"
|
||||
#include "GrallocImages.h"
|
||||
#include "MPAPI.h"
|
||||
#include "MediaResource.h"
|
||||
#include "AbstractMediaDecoder.h"
|
||||
|
@ -1486,8 +1486,8 @@ GonkFrameBuilder(Image* aImage, void* aBuffer, uint32_t aWidth, uint32_t aHeight
|
||||
* Cast the generic Image back to our platform-specific type and
|
||||
* populate it.
|
||||
*/
|
||||
GonkIOSurfaceImage* videoImage = static_cast<GonkIOSurfaceImage*>(aImage);
|
||||
GonkIOSurfaceImage::Data data;
|
||||
GrallocImage* videoImage = static_cast<GrallocImage*>(aImage);
|
||||
GrallocImage::GrallocData data;
|
||||
data.mGraphicBuffer = static_cast<layers::GraphicBufferLocked*>(aBuffer);
|
||||
data.mPicSize = gfxIntSize(aWidth, aHeight);
|
||||
videoImage->SetData(data);
|
||||
@ -1496,7 +1496,7 @@ GonkFrameBuilder(Image* aImage, void* aBuffer, uint32_t aWidth, uint32_t aHeight
|
||||
void
|
||||
ReceiveFrame(nsGonkCameraControl* gc, layers::GraphicBufferLocked* aBuffer)
|
||||
{
|
||||
if (!gc->ReceiveFrame(aBuffer, ImageFormat::GONK_IO_SURFACE, GonkFrameBuilder)) {
|
||||
if (!gc->ReceiveFrame(aBuffer, ImageFormat::GRALLOC_PLANAR_YCBCR, GonkFrameBuilder)) {
|
||||
aBuffer->Unlock();
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#include "mozilla/layers/LayersSurfaces.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "GonkIOSurfaceImage.h"
|
||||
#include "GrallocImages.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
namespace android {
|
||||
|
@ -1,164 +0,0 @@
|
||||
/* 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 "GonkIOSurfaceImage.h"
|
||||
|
||||
#include <OMX_IVCommon.h>
|
||||
#include <ColorConverter.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/Errors.h>
|
||||
|
||||
#define ALIGN(x, align) ((x + align - 1) & ~(align - 1))
|
||||
|
||||
typedef android::GraphicBuffer GraphicBuffer;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
uint32_t GonkIOSurfaceImage::sColorIdMap[] = {
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_P, OMX_COLOR_FormatYUV420Planar,
|
||||
HAL_PIXEL_FORMAT_YCbCr_422_P, OMX_COLOR_FormatYUV422Planar,
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_SP, OMX_COLOR_FormatYUV420SemiPlanar,
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP, -1,
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO, -1,
|
||||
HAL_PIXEL_FORMAT_YV12, OMX_COLOR_FormatYUV420Planar,
|
||||
0, 0
|
||||
};
|
||||
|
||||
struct GraphicBufferAutoUnlock {
|
||||
android::sp<GraphicBuffer> mGraphicBuffer;
|
||||
|
||||
GraphicBufferAutoUnlock(android::sp<GraphicBuffer>& aGraphicBuffer)
|
||||
: mGraphicBuffer(aGraphicBuffer) { }
|
||||
|
||||
~GraphicBufferAutoUnlock() { mGraphicBuffer->unlock(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts YVU420 semi planar frames to RGB565, possibly taking different
|
||||
* stride values.
|
||||
* Needed because the Android ColorConverter class assumes that the Y and UV
|
||||
* channels have equal stride.
|
||||
*/
|
||||
static void
|
||||
ConvertYVU420SPToRGB565(void *aYData, uint32_t aYStride,
|
||||
void *aUVData, uint32_t aUVStride,
|
||||
void *aOut,
|
||||
uint32_t aWidth, uint32_t aHeight)
|
||||
{
|
||||
uint8_t *y = (uint8_t*)aYData;
|
||||
int8_t *uv = (int8_t*)aUVData;
|
||||
|
||||
uint16_t *rgb = (uint16_t*)aOut;
|
||||
|
||||
for (size_t i = 0; i < aHeight; i++) {
|
||||
for (size_t j = 0; j < aWidth; j++) {
|
||||
int8_t d = uv[j | 1] - 128;
|
||||
int8_t e = uv[j & ~1] - 128;
|
||||
|
||||
// Constants taken from https://en.wikipedia.org/wiki/YUV
|
||||
int32_t r = (298 * y[j] + 409 * e + 128) >> 11;
|
||||
int32_t g = (298 * y[j] - 100 * d - 208 * e + 128) >> 10;
|
||||
int32_t b = (298 * y[j] + 516 * d + 128) >> 11;
|
||||
|
||||
r = r > 0x1f ? 0x1f : r < 0 ? 0 : r;
|
||||
g = g > 0x3f ? 0x3f : g < 0 ? 0 : g;
|
||||
b = b > 0x1f ? 0x1f : b < 0 ? 0 : b;
|
||||
|
||||
*rgb++ = (uint16_t)(r << 11 | g << 5 | b);
|
||||
}
|
||||
|
||||
y += aYStride;
|
||||
if (i % 2) {
|
||||
uv += aUVStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
GonkIOSurfaceImage::GetAsSurface()
|
||||
{
|
||||
android::sp<GraphicBuffer> graphicBuffer =
|
||||
GrallocBufferActor::GetFrom(GetSurfaceDescriptor());
|
||||
|
||||
void *buffer;
|
||||
int32_t rv =
|
||||
graphicBuffer->lock(android::GraphicBuffer::USAGE_SW_READ_OFTEN, &buffer);
|
||||
|
||||
if (rv) {
|
||||
NS_WARNING("Couldn't lock graphic buffer");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GraphicBufferAutoUnlock unlock(graphicBuffer);
|
||||
|
||||
uint32_t format = graphicBuffer->getPixelFormat();
|
||||
uint32_t omxFormat = 0;
|
||||
|
||||
for (int i = 0; sColorIdMap[i]; i += 2) {
|
||||
if (sColorIdMap[i] == format) {
|
||||
omxFormat = sColorIdMap[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!omxFormat) {
|
||||
NS_WARNING("Unknown color format");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface =
|
||||
new gfxImageSurface(GetSize(), gfxASurface::ImageFormatRGB16_565);
|
||||
|
||||
uint32_t width = GetSize().width;
|
||||
uint32_t height = GetSize().height;
|
||||
|
||||
if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO) {
|
||||
// The Adreno hardware decoder aligns image dimensions to a multiple of 32,
|
||||
// so we have to account for that here
|
||||
uint32_t alignedWidth = ALIGN(width, 32);
|
||||
uint32_t alignedHeight = ALIGN(height, 32);
|
||||
uint32_t uvOffset = ALIGN(alignedHeight * alignedWidth, 4096);
|
||||
uint32_t uvStride = 2 * ALIGN(width / 2, 32);
|
||||
uint8_t* buffer_as_bytes = static_cast<uint8_t*>(buffer);
|
||||
ConvertYVU420SPToRGB565(buffer, alignedWidth,
|
||||
buffer_as_bytes + uvOffset, uvStride,
|
||||
imageSurface->Data(),
|
||||
width, height);
|
||||
|
||||
return imageSurface.forget();
|
||||
}
|
||||
else if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
|
||||
uint32_t uvOffset = height * width;
|
||||
ConvertYVU420SPToRGB565(buffer, width,
|
||||
buffer + uvOffset, width,
|
||||
imageSurface->Data(),
|
||||
width, height);
|
||||
|
||||
return imageSurface.forget();
|
||||
}
|
||||
|
||||
android::ColorConverter colorConverter((OMX_COLOR_FORMATTYPE)omxFormat,
|
||||
OMX_COLOR_Format16bitRGB565);
|
||||
|
||||
if (!colorConverter.isValid()) {
|
||||
NS_WARNING("Invalid color conversion");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rv = colorConverter.convert(buffer, width, height,
|
||||
0, 0, width - 1, height - 1 /* source crop */,
|
||||
imageSurface->Data(), width, height,
|
||||
0, 0, width - 1, height - 1 /* dest crop */);
|
||||
|
||||
if (rv) {
|
||||
NS_WARNING("OMX color conversion failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return imageSurface.forget();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
@ -1,112 +0,0 @@
|
||||
/* -*- 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 GONKIOSURFACEIMAGE_H
|
||||
#define GONKIOSURFACEIMAGE_H
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
||||
#include "mozilla/layers/LayersSurfaces.h"
|
||||
#include "ImageContainer.h"
|
||||
|
||||
#include <ui/GraphicBuffer.h>
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* The gralloc buffer maintained by android GraphicBuffer can be
|
||||
* shared between the compositor thread and the producer thread. The
|
||||
* mGraphicBuffer is owned by the producer thread, but when it is
|
||||
* wrapped by GraphicBufferLocked and passed to the compositor, the
|
||||
* buffer content is guaranteed to not change until Unlock() is
|
||||
* called. Each producer must maintain their own buffer queue and
|
||||
* implement the GraphicBufferLocked::Unlock() interface.
|
||||
*/
|
||||
class GraphicBufferLocked {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GraphicBufferLocked)
|
||||
|
||||
public:
|
||||
GraphicBufferLocked(SurfaceDescriptor aGraphicBuffer)
|
||||
: mSurfaceDescriptor(aGraphicBuffer)
|
||||
{}
|
||||
|
||||
virtual ~GraphicBufferLocked() {}
|
||||
|
||||
virtual void Unlock() {}
|
||||
|
||||
SurfaceDescriptor GetSurfaceDescriptor()
|
||||
{
|
||||
return mSurfaceDescriptor;
|
||||
}
|
||||
|
||||
protected:
|
||||
SurfaceDescriptor mSurfaceDescriptor;
|
||||
};
|
||||
|
||||
class GonkIOSurfaceImage : public Image {
|
||||
typedef android::GraphicBuffer GraphicBuffer;
|
||||
static uint32_t sColorIdMap[];
|
||||
public:
|
||||
struct Data {
|
||||
nsRefPtr<GraphicBufferLocked> mGraphicBuffer;
|
||||
gfxIntSize mPicSize;
|
||||
};
|
||||
GonkIOSurfaceImage()
|
||||
: Image(nullptr, GONK_IO_SURFACE)
|
||||
, mSize(0, 0)
|
||||
{}
|
||||
|
||||
virtual ~GonkIOSurfaceImage()
|
||||
{
|
||||
mGraphicBuffer->Unlock();
|
||||
}
|
||||
|
||||
virtual void SetData(const Data& aData)
|
||||
{
|
||||
mGraphicBuffer = aData.mGraphicBuffer;
|
||||
mSize = aData.mPicSize;
|
||||
}
|
||||
|
||||
virtual gfxIntSize GetSize()
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
// From [android 4.0.4]/hardware/msm7k/libgralloc-qsd8k/gralloc_priv.h
|
||||
enum {
|
||||
/* OEM specific HAL formats */
|
||||
HAL_PIXEL_FORMAT_YCbCr_422_P = 0x102,
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_P = 0x103,
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x109,
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x10A,
|
||||
};
|
||||
|
||||
enum {
|
||||
OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
|
||||
};
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
|
||||
void* GetNativeBuffer()
|
||||
{
|
||||
return GrallocBufferActor::GetFrom(GetSurfaceDescriptor())->getNativeBuffer();
|
||||
}
|
||||
|
||||
SurfaceDescriptor GetSurfaceDescriptor()
|
||||
{
|
||||
return mGraphicBuffer->GetSurfaceDescriptor();
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<GraphicBufferLocked> mGraphicBuffer;
|
||||
gfxIntSize mSize;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
#endif
|
||||
|
||||
#endif /* GONKIOSURFACEIMAGE_H */
|
@ -10,26 +10,58 @@
|
||||
#include "ImageContainer.h"
|
||||
#include "GrallocImages.h"
|
||||
|
||||
#include <OMX_IVCommon.h>
|
||||
#include <ColorConverter.h>
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using namespace android;
|
||||
|
||||
#define ALIGN(x, align) ((x + align - 1) & ~(align - 1))
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
GrallocPlanarYCbCrImage::GrallocPlanarYCbCrImage()
|
||||
: PlanarYCbCrImage(nullptr)
|
||||
uint32_t GrallocImage::sColorIdMap[] = {
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_P, OMX_COLOR_FormatYUV420Planar,
|
||||
HAL_PIXEL_FORMAT_YCbCr_422_P, OMX_COLOR_FormatYUV422Planar,
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_SP, OMX_COLOR_FormatYUV420SemiPlanar,
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP, -1,
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO, -1,
|
||||
HAL_PIXEL_FORMAT_YV12, OMX_COLOR_FormatYUV420Planar,
|
||||
0, 0
|
||||
};
|
||||
|
||||
struct GraphicBufferAutoUnlock {
|
||||
android::sp<GraphicBuffer> mGraphicBuffer;
|
||||
|
||||
GraphicBufferAutoUnlock(android::sp<GraphicBuffer>& aGraphicBuffer)
|
||||
: mGraphicBuffer(aGraphicBuffer) { }
|
||||
|
||||
~GraphicBufferAutoUnlock() { mGraphicBuffer->unlock(); }
|
||||
};
|
||||
|
||||
GrallocImage::GrallocImage()
|
||||
: PlanarYCbCrImage(nullptr),
|
||||
mBufferAllocated(false),
|
||||
mGraphicBuffer(nullptr)
|
||||
{
|
||||
mFormat = GRALLOC_PLANAR_YCBCR;
|
||||
}
|
||||
|
||||
GrallocPlanarYCbCrImage::~GrallocPlanarYCbCrImage()
|
||||
GrallocImage::~GrallocImage()
|
||||
{
|
||||
ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton();
|
||||
ibc->DeallocSurfaceDescriptorGralloc(mSurfaceDescriptor);
|
||||
if (mGraphicBuffer.get()) {
|
||||
mGraphicBuffer->Unlock();
|
||||
if (mBufferAllocated) {
|
||||
ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton();
|
||||
ibc->DeallocSurfaceDescriptorGralloc(mGraphicBuffer->GetSurfaceDescriptor());
|
||||
mBufferAllocated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GrallocPlanarYCbCrImage::SetData(const Data& aData)
|
||||
GrallocImage::SetData(const Data& aData)
|
||||
{
|
||||
NS_PRECONDITION(aData.mYSize.width % 2 == 0, "Image should have even width");
|
||||
NS_PRECONDITION(aData.mYSize.height % 2 == 0, "Image should have even height");
|
||||
@ -38,17 +70,23 @@ GrallocPlanarYCbCrImage::SetData(const Data& aData)
|
||||
mData = aData;
|
||||
mSize = aData.mPicSize;
|
||||
|
||||
if (mSurfaceDescriptor.type() == SurfaceDescriptor::T__None) {
|
||||
if (!mGraphicBuffer.get()) {
|
||||
|
||||
SurfaceDescriptor desc;
|
||||
ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton();
|
||||
ibc->AllocSurfaceDescriptorGralloc(aData.mYSize,
|
||||
HAL_PIXEL_FORMAT_YV12,
|
||||
GraphicBuffer::USAGE_SW_READ_OFTEN |
|
||||
GraphicBuffer::USAGE_SW_WRITE_OFTEN |
|
||||
GraphicBuffer::USAGE_HW_TEXTURE,
|
||||
&mSurfaceDescriptor);
|
||||
&desc);
|
||||
mBufferAllocated = true;
|
||||
mGraphicBuffer = new GraphicBufferLocked(desc);
|
||||
}
|
||||
|
||||
sp<GraphicBuffer> graphicBuffer =
|
||||
GrallocBufferActor::GetFrom(mSurfaceDescriptor.get_SurfaceDescriptorGralloc());
|
||||
GrallocBufferActor::GetFrom(
|
||||
mGraphicBuffer->GetSurfaceDescriptor().get_SurfaceDescriptorGralloc());
|
||||
if (!graphicBuffer.get()) {
|
||||
return;
|
||||
}
|
||||
@ -104,5 +142,136 @@ GrallocPlanarYCbCrImage::SetData(const Data& aData)
|
||||
graphicBuffer->unlock();
|
||||
}
|
||||
|
||||
void GrallocImage::SetData(const GrallocData& aData)
|
||||
{
|
||||
mGraphicBuffer = aData.mGraphicBuffer;
|
||||
mSize = aData.mPicSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts YVU420 semi planar frames to RGB565, possibly taking different
|
||||
* stride values.
|
||||
* Needed because the Android ColorConverter class assumes that the Y and UV
|
||||
* channels have equal stride.
|
||||
*/
|
||||
static void
|
||||
ConvertYVU420SPToRGB565(void *aYData, uint32_t aYStride,
|
||||
void *aUVData, uint32_t aUVStride,
|
||||
void *aOut,
|
||||
uint32_t aWidth, uint32_t aHeight)
|
||||
{
|
||||
uint8_t *y = (uint8_t*)aYData;
|
||||
int8_t *uv = (int8_t*)aUVData;
|
||||
|
||||
uint16_t *rgb = (uint16_t*)aOut;
|
||||
|
||||
for (size_t i = 0; i < aHeight; i++) {
|
||||
for (size_t j = 0; j < aWidth; j++) {
|
||||
int8_t d = uv[j | 1] - 128;
|
||||
int8_t e = uv[j & ~1] - 128;
|
||||
|
||||
// Constants taken from https://en.wikipedia.org/wiki/YUV
|
||||
int32_t r = (298 * y[j] + 409 * e + 128) >> 11;
|
||||
int32_t g = (298 * y[j] - 100 * d - 208 * e + 128) >> 10;
|
||||
int32_t b = (298 * y[j] + 516 * d + 128) >> 11;
|
||||
|
||||
r = r > 0x1f ? 0x1f : r < 0 ? 0 : r;
|
||||
g = g > 0x3f ? 0x3f : g < 0 ? 0 : g;
|
||||
b = b > 0x1f ? 0x1f : b < 0 ? 0 : b;
|
||||
|
||||
*rgb++ = (uint16_t)(r << 11 | g << 5 | b);
|
||||
}
|
||||
|
||||
y += aYStride;
|
||||
if (i % 2) {
|
||||
uv += aUVStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
GrallocImage::GetAsSurface()
|
||||
{
|
||||
android::sp<GraphicBuffer> graphicBuffer =
|
||||
GrallocBufferActor::GetFrom(GetSurfaceDescriptor());
|
||||
|
||||
void *buffer;
|
||||
int32_t rv =
|
||||
graphicBuffer->lock(android::GraphicBuffer::USAGE_SW_READ_OFTEN, &buffer);
|
||||
|
||||
if (rv) {
|
||||
NS_WARNING("Couldn't lock graphic buffer");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GraphicBufferAutoUnlock unlock(graphicBuffer);
|
||||
|
||||
uint32_t format = graphicBuffer->getPixelFormat();
|
||||
uint32_t omxFormat = 0;
|
||||
|
||||
for (int i = 0; sColorIdMap[i]; i += 2) {
|
||||
if (sColorIdMap[i] == format) {
|
||||
omxFormat = sColorIdMap[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!omxFormat) {
|
||||
NS_WARNING("Unknown color format");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface =
|
||||
new gfxImageSurface(GetSize(), gfxASurface::ImageFormatRGB16_565);
|
||||
|
||||
uint32_t width = GetSize().width;
|
||||
uint32_t height = GetSize().height;
|
||||
|
||||
if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO) {
|
||||
// The Adreno hardware decoder aligns image dimensions to a multiple of 32,
|
||||
// so we have to account for that here
|
||||
uint32_t alignedWidth = ALIGN(width, 32);
|
||||
uint32_t alignedHeight = ALIGN(height, 32);
|
||||
uint32_t uvOffset = ALIGN(alignedHeight * alignedWidth, 4096);
|
||||
uint32_t uvStride = 2 * ALIGN(width / 2, 32);
|
||||
uint8_t* buffer_as_bytes = static_cast<uint8_t*>(buffer);
|
||||
ConvertYVU420SPToRGB565(buffer, alignedWidth,
|
||||
buffer_as_bytes + uvOffset, uvStride,
|
||||
imageSurface->Data(),
|
||||
width, height);
|
||||
|
||||
return imageSurface.forget();
|
||||
}
|
||||
else if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
|
||||
uint32_t uvOffset = height * width;
|
||||
ConvertYVU420SPToRGB565(buffer, width,
|
||||
buffer + uvOffset, width,
|
||||
imageSurface->Data(),
|
||||
width, height);
|
||||
|
||||
return imageSurface.forget();
|
||||
}
|
||||
|
||||
android::ColorConverter colorConverter((OMX_COLOR_FORMATTYPE)omxFormat,
|
||||
OMX_COLOR_Format16bitRGB565);
|
||||
|
||||
if (!colorConverter.isValid()) {
|
||||
NS_WARNING("Invalid color conversion");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rv = colorConverter.convert(buffer, width, height,
|
||||
0, 0, width - 1, height - 1 /* source crop */,
|
||||
imageSurface->Data(), width, height,
|
||||
0, 0, width - 1, height - 1 /* dest crop */);
|
||||
|
||||
if (rv) {
|
||||
NS_WARNING("OMX color conversion failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return imageSurface.forget();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -10,12 +10,43 @@
|
||||
|
||||
#include "mozilla/layers/LayersSurfaces.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "ImageContainer.h"
|
||||
|
||||
#include <ui/GraphicBuffer.h>
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* The gralloc buffer maintained by android GraphicBuffer can be
|
||||
* shared between the compositor thread and the producer thread. The
|
||||
* mGraphicBuffer is owned by the producer thread, but when it is
|
||||
* wrapped by GraphicBufferLocked and passed to the compositor, the
|
||||
* buffer content is guaranteed to not change until Unlock() is
|
||||
* called. Each producer must maintain their own buffer queue and
|
||||
* implement the GraphicBufferLocked::Unlock() interface.
|
||||
*/
|
||||
class GraphicBufferLocked {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GraphicBufferLocked)
|
||||
|
||||
public:
|
||||
GraphicBufferLocked(SurfaceDescriptor aGraphicBuffer)
|
||||
: mSurfaceDescriptor(aGraphicBuffer)
|
||||
{}
|
||||
|
||||
virtual ~GraphicBufferLocked() {}
|
||||
|
||||
virtual void Unlock() {}
|
||||
|
||||
SurfaceDescriptor GetSurfaceDescriptor()
|
||||
{
|
||||
return mSurfaceDescriptor;
|
||||
}
|
||||
|
||||
protected:
|
||||
SurfaceDescriptor mSurfaceDescriptor;
|
||||
};
|
||||
|
||||
/**
|
||||
* The YUV format supported by Android HAL
|
||||
*
|
||||
@ -37,13 +68,19 @@ namespace layers {
|
||||
* mPicX, mPicY and mPicSize. The size of the rendered image is
|
||||
* mPicSize, not mYSize or mCbCrSize.
|
||||
*/
|
||||
class GrallocPlanarYCbCrImage : public PlanarYCbCrImage {
|
||||
class GrallocImage : public PlanarYCbCrImage {
|
||||
typedef PlanarYCbCrImage::Data Data;
|
||||
static uint32_t sColorIdMap[];
|
||||
|
||||
public:
|
||||
GrallocPlanarYCbCrImage();
|
||||
struct GrallocData {
|
||||
nsRefPtr<GraphicBufferLocked> mGraphicBuffer;
|
||||
gfxIntSize mPicSize;
|
||||
};
|
||||
|
||||
virtual ~GrallocPlanarYCbCrImage();
|
||||
GrallocImage();
|
||||
|
||||
virtual ~GrallocImage();
|
||||
|
||||
/**
|
||||
* This makes a copy of the data buffers, in order to support functioning
|
||||
@ -51,16 +88,44 @@ public:
|
||||
*/
|
||||
virtual void SetData(const Data& aData);
|
||||
|
||||
virtual uint32_t GetDataSize() { return 0; }
|
||||
/**
|
||||
* Share the SurfaceDescriptor without making the copy, in order
|
||||
* to support functioning in all different layer managers.
|
||||
*/
|
||||
virtual void SetData(const GrallocData& aData);
|
||||
|
||||
virtual bool IsValid() { return mSurfaceDescriptor.type() != SurfaceDescriptor::T__None; }
|
||||
// From [android 4.0.4]/hardware/msm7k/libgralloc-qsd8k/gralloc_priv.h
|
||||
enum {
|
||||
/* OEM specific HAL formats */
|
||||
HAL_PIXEL_FORMAT_YCbCr_422_P = 0x102,
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_P = 0x103,
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x109,
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x10A,
|
||||
};
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
|
||||
void* GetNativeBuffer()
|
||||
{
|
||||
if (IsValid()) {
|
||||
return GrallocBufferActor::GetFrom(GetSurfaceDescriptor())->getNativeBuffer();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool IsValid() { return GetSurfaceDescriptor().type() != SurfaceDescriptor::T__None; }
|
||||
|
||||
SurfaceDescriptor GetSurfaceDescriptor() {
|
||||
return mSurfaceDescriptor;
|
||||
if (mGraphicBuffer.get()) {
|
||||
return mGraphicBuffer->GetSurfaceDescriptor();
|
||||
}
|
||||
return SurfaceDescriptor();
|
||||
}
|
||||
|
||||
private:
|
||||
SurfaceDescriptor mSurfaceDescriptor;
|
||||
bool mBufferAllocated;
|
||||
nsRefPtr<GraphicBufferLocked> mGraphicBuffer;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
|
||||
#include "ImageContainer.h"
|
||||
#include "GonkIOSurfaceImage.h"
|
||||
#include "GrallocImages.h"
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "mozilla/ipc/CrossProcessMutex.h"
|
||||
@ -54,7 +53,7 @@ ImageFactory::CreateImage(const ImageFormat *aFormats,
|
||||
nsRefPtr<Image> img;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (FormatInList(aFormats, aNumFormats, GRALLOC_PLANAR_YCBCR)) {
|
||||
img = new GrallocPlanarYCbCrImage();
|
||||
img = new GrallocImage();
|
||||
return img.forget();
|
||||
}
|
||||
#endif
|
||||
@ -70,12 +69,6 @@ ImageFactory::CreateImage(const ImageFormat *aFormats,
|
||||
img = new SharedTextureImage();
|
||||
return img.forget();
|
||||
}
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (FormatInList(aFormats, aNumFormats, GONK_IO_SURFACE)) {
|
||||
img = new GonkIOSurfaceImage();
|
||||
return img.forget();
|
||||
}
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
if (FormatInList(aFormats, aNumFormats, D3D9_RGB32_TEXTURE)) {
|
||||
img = new D3D9SurfaceImage();
|
||||
|
@ -17,9 +17,9 @@ enum ImageFormat {
|
||||
PLANAR_YCBCR,
|
||||
|
||||
/**
|
||||
* The GRALLOC_PLANAR_YCBCR format creates a GrallocPlanarYCbCrImage, a
|
||||
* subtype of PlanarYCbCrImage. It takes a PlanarYCbCrImage data and can be
|
||||
* used as a texture by Gonk backend directly.
|
||||
* The GRALLOC_PLANAR_YCBCR format creates a GrallocImage, a subtype of
|
||||
* PlanarYCbCrImage. It takes a PlanarYCbCrImage data or the raw gralloc
|
||||
* data and can be used as a texture by Gonk backend directly.
|
||||
*/
|
||||
GRALLOC_PLANAR_YCBCR,
|
||||
|
||||
@ -45,13 +45,6 @@ enum ImageFormat {
|
||||
*/
|
||||
CAIRO_SURFACE,
|
||||
|
||||
/**
|
||||
* The GONK_IO_SURFACE format creates a GonkIOSurfaceImage.
|
||||
*
|
||||
* It wraps an GraphicBuffer object and binds it directly to a GL texture.
|
||||
*/
|
||||
GONK_IO_SURFACE,
|
||||
|
||||
/**
|
||||
* An bitmap image that can be shared with a remote process.
|
||||
*/
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "mozilla/layers/SharedPlanarYCbCrImage.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "GonkIOSurfaceImage.h"
|
||||
#include "GrallocImages.h"
|
||||
#endif
|
||||
|
||||
@ -152,20 +151,6 @@ DeprecatedImageClientSingle::UpdateImage(ImageContainer* aContainer,
|
||||
}
|
||||
mDeprecatedTextureClient->SetDescriptor(desc);
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
} else if (image->GetFormat() == GONK_IO_SURFACE &&
|
||||
EnsureDeprecatedTextureClient(TEXTURE_SHARED_GL_EXTERNAL)) {
|
||||
nsIntRect rect(0, 0,
|
||||
image->GetSize().width,
|
||||
image->GetSize().height);
|
||||
UpdatePictureRect(rect);
|
||||
|
||||
AutoLockDeprecatedTextureClient lock(mDeprecatedTextureClient);
|
||||
|
||||
SurfaceDescriptor desc = static_cast<GonkIOSurfaceImage*>(image)->GetSurfaceDescriptor();
|
||||
if (!IsSurfaceDescriptorValid(desc)) {
|
||||
return false;
|
||||
}
|
||||
mDeprecatedTextureClient->SetDescriptor(desc);
|
||||
} else if (image->GetFormat() == GRALLOC_PLANAR_YCBCR) {
|
||||
EnsureDeprecatedTextureClient(TEXTURE_SHARED_GL_EXTERNAL);
|
||||
|
||||
@ -176,7 +161,7 @@ DeprecatedImageClientSingle::UpdateImage(ImageContainer* aContainer,
|
||||
|
||||
AutoLockDeprecatedTextureClient lock(mDeprecatedTextureClient);
|
||||
|
||||
SurfaceDescriptor desc = static_cast<GrallocPlanarYCbCrImage*>(image)->GetSurfaceDescriptor();
|
||||
SurfaceDescriptor desc = static_cast<GrallocImage*>(image)->GetSurfaceDescriptor();
|
||||
if (!IsSurfaceDescriptorValid(desc)) {
|
||||
return false;
|
||||
}
|
||||
@ -253,11 +238,8 @@ ImageClient::CreateImage(const uint32_t *aFormats,
|
||||
img = new DeprecatedSharedRGBImage(GetForwarder());
|
||||
return img.forget();
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
case GONK_IO_SURFACE:
|
||||
img = new GonkIOSurfaceImage();
|
||||
return img.forget();
|
||||
case GRALLOC_PLANAR_YCBCR:
|
||||
img = new GrallocPlanarYCbCrImage();
|
||||
img = new GrallocImage();
|
||||
return img.forget();
|
||||
#endif
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ EXPORTS += [
|
||||
'CopyableCanvasLayer.h',
|
||||
'D3D9SurfaceImage.h',
|
||||
'FrameMetrics.h',
|
||||
'GonkIOSurfaceImage.h',
|
||||
'GrallocImages.h',
|
||||
'ImageContainer.h',
|
||||
'ImageLayers.h',
|
||||
'ImageTypes.h',
|
||||
@ -166,7 +166,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
CPP_SOURCES += [
|
||||
'ShadowLayerUtilsGralloc.cpp',
|
||||
'GrallocImages.cpp',
|
||||
'GonkIOSurfaceImage.cpp',
|
||||
]
|
||||
|
||||
CPP_SOURCES += [
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "ImageContainer.h"
|
||||
#include "VideoUtils.h"
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "GonkIOSurfaceImage.h"
|
||||
#include "GrallocImages.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -823,8 +823,8 @@ void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk(
|
||||
|
||||
ImageFormat format = img->GetFormat();
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (format == GONK_IO_SURFACE) {
|
||||
layers::GonkIOSurfaceImage *nativeImage = static_cast<layers::GonkIOSurfaceImage*>(img);
|
||||
if (format == GRALLOC_PLANAR_YCBCR) {
|
||||
layers::GrallocImage *nativeImage = static_cast<layers::GrallocImage*>(img);
|
||||
layers::SurfaceDescriptor handle = nativeImage->GetSurfaceDescriptor();
|
||||
layers::SurfaceDescriptorGralloc grallocHandle = handle.get_SurfaceDescriptorGralloc();
|
||||
|
||||
@ -864,7 +864,7 @@ void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk(
|
||||
// XXX Consider making this a non-debug-only check if we ever implement
|
||||
// any subclasses of PlanarYCbCrImage that allow disjoint buffers such
|
||||
// that y+3(width*height)/2 might go outside the allocation.
|
||||
// GrallocPlanarYCbCrImage can have wider strides, and so in some cases
|
||||
// GrallocImage can have wider strides, and so in some cases
|
||||
// would encode as garbage. If we need to encode it we'll either want to
|
||||
// modify SendVideoFrame or copy/move the data in the buffer.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user