Back out bug 1097116

This commit is contained in:
James Willcox 2014-11-21 09:47:03 -06:00
parent 1664129cd2
commit f409f2a92b
12 changed files with 63 additions and 221 deletions

View File

@ -4,12 +4,7 @@
#include "AndroidDecoderModule.h"
#include "AndroidBridge.h"
#include "GLBlitHelper.h"
#include "GLContext.h"
#include "GLContextEGL.h"
#include "GLContextProvider.h"
#include "GLImages.h"
#include "GLLibraryEGL.h"
#include "MediaData.h"
@ -61,18 +56,18 @@ public:
return InitDecoder(mSurfaceTexture->JavaSurface());
}
void Cleanup() MOZ_OVERRIDE {
mGLContext = nullptr;
}
virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE {
mp4_demuxer::AnnexB::ConvertSample(aSample);
return MediaCodecDataDecoder::Input(aSample);
}
EGLImage CopySurface() {
if (!EnsureGLContext()) {
return nullptr;
virtual nsresult PostOutput(BufferInfo* aInfo, MediaFormat* aFormat, Microseconds aDuration) MOZ_OVERRIDE {
VideoInfo videoInfo;
videoInfo.mDisplay = nsIntSize(mConfig.display_width, mConfig.display_height);
bool isSync = false;
if (MediaCodec::getBUFFER_FLAG_SYNC_FRAME() & aInfo->getFlags()) {
isSync = true;
}
nsRefPtr<layers::Image> img = mImageContainer->CreateImage(ImageFormat::SURFACE_TEXTURE);
@ -81,70 +76,9 @@ public:
data.mSize = gfx::IntSize(mConfig.display_width, mConfig.display_height);
data.mInverted = true;
layers::SurfaceTextureImage* stImg = static_cast<layers::SurfaceTextureImage*>(img.get());
stImg->SetData(data);
mGLContext->MakeCurrent();
GLuint tex = CreateTextureForOffscreen(mGLContext, mGLContext->GetGLFormats(), data.mSize);
GLBlitHelper helper(mGLContext);
if (!helper.BlitImageToTexture(img, data.mSize, tex, LOCAL_GL_TEXTURE_2D)) {
mGLContext->fDeleteTextures(1, &tex);
return nullptr;
}
EGLint attribs[] = {
LOCAL_EGL_IMAGE_PRESERVED_KHR, LOCAL_EGL_TRUE,
LOCAL_EGL_NONE, LOCAL_EGL_NONE
};
EGLContext eglContext = static_cast<GLContextEGL*>(mGLContext.get())->GetEGLContext();
EGLImage eglImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext,
LOCAL_EGL_GL_TEXTURE_2D_KHR,
(EGLClientBuffer)tex, attribs);
mGLContext->fDeleteTextures(1, &tex);
return eglImage;
}
virtual nsresult PostOutput(BufferInfo* aInfo, MediaFormat* aFormat, Microseconds aDuration) MOZ_OVERRIDE {
VideoInfo videoInfo;
videoInfo.mDisplay = nsIntSize(mConfig.display_width, mConfig.display_height);
EGLImage eglImage = CopySurface();
if (!eglImage) {
return NS_ERROR_FAILURE;
}
EGLSync eglSync = nullptr;
if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
mGLContext->IsExtensionSupported(GLContext::OES_EGL_sync))
{
MOZ_ASSERT(mGLContext->IsCurrent());
eglSync = sEGLLibrary.fCreateSync(EGL_DISPLAY(),
LOCAL_EGL_SYNC_FENCE,
nullptr);
if (eglSync) {
mGLContext->fFlush();
}
} else {
NS_WARNING("No EGL fence support detected, rendering artifacts may occur!");
}
nsRefPtr<layers::Image> img = mImageContainer->CreateImage(ImageFormat::EGLIMAGE);
layers::EGLImageImage::Data data;
data.mImage = eglImage;
data.mSync = eglSync;
data.mOwns = true;
data.mSize = gfx::IntSize(mConfig.display_width, mConfig.display_height);
data.mInverted = false;
layers::EGLImageImage* typedImg = static_cast<layers::EGLImageImage*>(img.get());
layers::SurfaceTextureImage* typedImg = static_cast<layers::SurfaceTextureImage*>(img.get());
typedImg->SetData(data);
bool isSync = !!(MediaCodec::getBUFFER_FLAG_SYNC_FRAME() & aInfo->getFlags());
nsRefPtr<VideoData> v = VideoData::CreateFromImage(videoInfo, mImageContainer, aInfo->getOffset(),
aInfo->getPresentationTimeUs(),
aDuration,
@ -158,19 +92,9 @@ public:
}
protected:
bool EnsureGLContext() {
if (mGLContext) {
return true;
}
mGLContext = GLContextProvider::CreateHeadless();
return mGLContext;
}
layers::ImageContainer* mImageContainer;
const mp4_demuxer::VideoDecoderConfig& mConfig;
RefPtr<AndroidSurfaceTexture> mSurfaceTexture;
nsRefPtr<GLContext> mGLContext;
};
class AudioDataDecoder : public MediaCodecDataDecoder {
@ -530,8 +454,6 @@ void MediaCodecDataDecoder::DecoderLoop()
}
}
Cleanup();
// We're done
mMonitor.Lock();
mStopping = false;

View File

@ -98,7 +98,6 @@ protected:
virtual nsresult Output(mozilla::widget::android::sdk::BufferInfo* aInfo, void* aBuffer, mozilla::widget::android::sdk::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; }
virtual nsresult PostOutput(mozilla::widget::android::sdk::BufferInfo* aInfo, mozilla::widget::android::sdk::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; }
virtual void Cleanup() {};
nsresult ResetInputBuffers();
nsresult ResetOutputBuffers();

View File

@ -305,7 +305,6 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
GLuint *fragShaderPtr;
const char* fragShaderSource;
switch (target) {
case ConvertEGLImage:
case BlitTex2D:
programPtr = &mTex2DBlit_Program;
fragShaderPtr = &mTex2DBlit_FragShader;
@ -452,7 +451,6 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
switch (target) {
case BlitTex2D:
case BlitTexRect:
case ConvertEGLImage:
case ConvertSurfaceTexture:
case ConvertGralloc: {
#ifdef ANDROID
@ -668,26 +666,25 @@ GLBlitHelper::BindAndUploadYUVTexture(Channel which,
}
}
#ifdef MOZ_WIDGET_GONK
void
GLBlitHelper::BindAndUploadEGLImage(EGLImage image, GLuint target)
GLBlitHelper::BindAndUploadExternalTexture(EGLImage image)
{
MOZ_ASSERT(image != EGL_NO_IMAGE, "Bad EGLImage");
if (!mSrcTexEGL) {
mGL->fGenTextures(1, &mSrcTexEGL);
mGL->fBindTexture(target, mSrcTexEGL);
mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, mSrcTexEGL);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
} else {
mGL->fBindTexture(target, mSrcTexEGL);
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, mSrcTexEGL);
}
mGL->fEGLImageTargetTexture2D(target, image);
mGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL_OES, image);
}
#ifdef MOZ_WIDGET_GONK
bool
GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip)
{
@ -708,7 +705,7 @@ GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip)
int oldBinding = 0;
mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL_OES, &oldBinding);
BindAndUploadEGLImage(image, LOCAL_GL_TEXTURE_EXTERNAL_OES);
BindAndUploadExternalTexture(image);
mGL->fUniform1f(mYFlipLoc, yFlip ? (float)1.0f : (float)0.0f);
@ -723,14 +720,13 @@ GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip)
#ifdef MOZ_WIDGET_ANDROID
bool
GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yFlip)
GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage)
{
AndroidSurfaceTexture* surfaceTexture = stImage->GetData()->mSurfTex;
if (stImage->GetData()->mInverted) {
yFlip = !yFlip;
}
bool yFlip = stImage->GetData()->mInverted;
ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
if (NS_FAILED(surfaceTexture->Attach(mGL))) {
return false;
@ -755,39 +751,6 @@ GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, oldBinding);
return true;
}
bool
GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image, bool yFlip)
{
EGLImage eglImage = image->GetData()->mImage;
EGLSync eglSync = image->GetData()->mSync;
if (image->GetData()->mInverted) {
yFlip = !yFlip;
}
if (eglSync) {
EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), eglSync, 0, LOCAL_EGL_FOREVER);
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
return false;
}
}
ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
int oldBinding = 0;
mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldBinding);
BindAndUploadEGLImage(eglImage, LOCAL_GL_TEXTURE_2D);
mGL->fUniform1f(mYFlipLoc, yFlip ? 1.0f : 0.0f);
mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, oldBinding);
return true;
}
#endif
bool
@ -853,9 +816,6 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
case ImageFormat::SURFACE_TEXTURE:
type = ConvertSurfaceTexture;
break;
case ImageFormat::EGLIMAGE:
type = ConvertEGLImage;
break;
#endif
default:
return false;
@ -888,11 +848,7 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
#ifdef MOZ_WIDGET_ANDROID
if (type == ConvertSurfaceTexture) {
layers::SurfaceTextureImage* stImage = static_cast<layers::SurfaceTextureImage*>(srcImage);
return BlitSurfaceTextureImage(stImage, yFlip);
}
if (type == ConvertEGLImage) {
layers::EGLImageImage* eglImage = static_cast<layers::EGLImageImage*>(srcImage);
return BlitEGLImageImage(eglImage, yFlip);
return BlitSurfaceTextureImage(stImage);
}
#endif

View File

@ -20,7 +20,6 @@ class Image;
class PlanarYCbCrImage;
class GrallocImage;
class SurfaceTextureImage;
class EGLImageImage;
}
namespace gl {
@ -99,8 +98,7 @@ class GLBlitHelper MOZ_FINAL
BlitTexRect,
ConvertGralloc,
ConvertPlanarYCbCr,
ConvertSurfaceTexture,
ConvertEGLImage
ConvertSurfaceTexture
};
// The GLContext is the sole owner of the GLBlitHelper.
GLContext* mGL;
@ -142,15 +140,14 @@ class GLBlitHelper MOZ_FINAL
bool InitTexQuadProgram(BlitType target = BlitTex2D);
void DeleteTexBlitProgram();
void BindAndUploadYUVTexture(Channel which, uint32_t width, uint32_t height, void* data, bool allocation);
void BindAndUploadEGLImage(EGLImage image, GLuint target);
#ifdef MOZ_WIDGET_GONK
void BindAndUploadExternalTexture(EGLImage image);
bool BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip = false);
#endif
bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yFlip = false);
#ifdef MOZ_WIDGET_ANDROID
bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yFlip = false);
bool BlitEGLImageImage(layers::EGLImageImage* eglImage, bool yFlip = false);
bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage);
#endif
public:

View File

@ -8,7 +8,6 @@
#include "GLBlitHelper.h"
#include "GLReadTexImageHelper.h"
#include "AndroidSurfaceTexture.h"
#include "GLLibraryEGL.h"
using namespace mozilla;
using namespace mozilla::gl;
@ -18,33 +17,16 @@ namespace layers {
static nsRefPtr<GLContext> sSnapshotContext;
EGLImageImage::~EGLImageImage()
{
if (!mData.mOwns) {
return;
}
if (mData.mImage) {
sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mData.mImage);
mData.mImage = nullptr;
}
if (mData.mSync) {
sEGLLibrary.fDestroySync(EGL_DISPLAY(), mData.mSync);
mData.mSync = nullptr;
}
}
TemporaryRef<SourceSurface>
GLImage::GetAsSourceSurface()
TemporaryRef<gfx::SourceSurface>
SurfaceTextureImage::GetAsSourceSurface()
{
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
if (!sSnapshotContext) {
sSnapshotContext = GLContextProvider::CreateHeadless();
SurfaceCaps caps = SurfaceCaps::ForRGBA();
sSnapshotContext = GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), caps);
if (!sSnapshotContext) {
NS_WARNING("Failed to create snapshot GLContext");
return nullptr;
}
}
@ -52,10 +34,8 @@ GLImage::GetAsSourceSurface()
sSnapshotContext->MakeCurrent();
ScopedTexture scopedTex(sSnapshotContext);
ScopedBindTexture boundTex(sSnapshotContext, scopedTex.Texture());
gfx::IntSize size = GetSize();
sSnapshotContext->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA,
size.width, size.height, 0,
mData.mSize.width, mData.mSize.height, 0,
LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE,
nullptr);
@ -64,11 +44,11 @@ GLImage::GetAsSourceSurface()
GLBlitHelper helper(sSnapshotContext);
helper.BlitImageToFramebuffer(this, size, fb.FB(), false);
helper.BlitImageToFramebuffer(this, mData.mSize, fb.FB(), false);
ScopedBindFramebuffer bind(sSnapshotContext, fb.FB());
RefPtr<gfx::DataSourceSurface> source =
gfx::Factory::CreateDataSourceSurface(size, gfx::SurfaceFormat::B8G8R8A8);
gfx::Factory::CreateDataSourceSurface(mData.mSize, gfx::SurfaceFormat::B8G8R8A8);
if (NS_WARN_IF(!source)) {
return nullptr;
}

View File

@ -18,25 +18,12 @@ class AndroidSurfaceTexture;
}
namespace layers {
class GLImage : public Image {
public:
GLImage(ImageFormat aFormat) : Image(nullptr, aFormat){}
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE;
};
class EGLImageImage : public GLImage {
class EGLImageImage : public Image {
public:
struct Data {
EGLImage mImage;
EGLSync mSync;
gfx::IntSize mSize;
bool mInverted;
bool mOwns;
Data() : mImage(nullptr), mSync(nullptr), mSize(0, 0), mInverted(false), mOwns(false)
{
}
};
void SetData(const Data& aData) { mData = aData; }
@ -44,10 +31,12 @@ public:
gfx::IntSize GetSize() { return mData.mSize; }
EGLImageImage() : GLImage(ImageFormat::EGLIMAGE) {}
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE
{
return nullptr;
}
protected:
virtual ~EGLImageImage();
EGLImageImage() : Image(nullptr, ImageFormat::EGLIMAGE) {}
private:
Data mData;
@ -55,7 +44,7 @@ private:
#ifdef MOZ_WIDGET_ANDROID
class SurfaceTextureImage : public GLImage {
class SurfaceTextureImage : public Image {
public:
struct Data {
mozilla::gl::AndroidSurfaceTexture* mSurfTex;
@ -68,7 +57,9 @@ public:
gfx::IntSize GetSize() { return mData.mSize; }
SurfaceTextureImage() : GLImage(ImageFormat::SURFACE_TEXTURE) {}
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE;
SurfaceTextureImage() : Image(nullptr, ImageFormat::SURFACE_TEXTURE) {}
private:
Data mData;

View File

@ -192,9 +192,10 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
if (image->GetFormat() == ImageFormat::EGLIMAGE) {
EGLImageImage* typedImage = static_cast<EGLImageImage*>(image);
texture = new EGLImageTextureClient(mTextureFlags,
typedImage,
size);
const EGLImageImage::Data* data = typedImage->GetData();
texture = new EGLImageTextureClient(mTextureFlags, data->mImage,
size, data->mInverted);
#ifdef MOZ_WIDGET_ANDROID
} else if (image->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
SurfaceTextureImage* typedImage = static_cast<SurfaceTextureImage*>(image);

View File

@ -63,7 +63,6 @@ struct SurfaceTextureDescriptor {
struct EGLImageDescriptor {
uintptr_t image; // `EGLImage` is a `void*`.
uintptr_t fence;
IntSize size;
};

View File

@ -8,7 +8,6 @@
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/TextureClientOGL.h"
#include "nsSize.h" // for nsIntSize
#include "GLLibraryEGL.h"
using namespace mozilla::gl;
@ -21,8 +20,9 @@ class CompositableForwarder;
// EGLImageTextureClient
EGLImageTextureClient::EGLImageTextureClient(TextureFlags aFlags,
EGLImageImage* aImage,
gfx::IntSize aSize)
EGLImage aImage,
gfx::IntSize aSize,
bool aInverted)
: TextureClient(aFlags)
, mImage(aImage)
, mSize(aSize)
@ -31,21 +31,26 @@ EGLImageTextureClient::EGLImageTextureClient(TextureFlags aFlags,
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default,
"Can't pass an `EGLImage` between processes.");
// Our data is always owned externally.
AddFlags(TextureFlags::DEALLOCATE_CLIENT);
if (aImage->GetData()->mInverted) {
if (aInverted) {
AddFlags(TextureFlags::NEEDS_Y_FLIP);
}
}
EGLImageTextureClient::~EGLImageTextureClient()
{
// Our data is always owned externally.
}
bool
EGLImageTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
{
MOZ_ASSERT(IsValid());
MOZ_ASSERT(IsAllocated());
const EGLImageImage::Data* data = mImage->GetData();
aOutDescriptor = EGLImageDescriptor((uintptr_t)data->mImage, (uintptr_t)data->mSync, mSize);
aOutDescriptor = EGLImageDescriptor((uintptr_t)mImage, mSize);
return true;
}

View File

@ -7,7 +7,6 @@
#define MOZILLA_GFX_TEXTURECLIENTOGL_H
#include "GLContextTypes.h" // for SharedTextureHandle, etc
#include "GLImages.h"
#include "gfxTypes.h"
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/gfx/Point.h" // for IntSize
@ -26,8 +25,11 @@ class EGLImageTextureClient : public TextureClient
{
public:
EGLImageTextureClient(TextureFlags aFlags,
EGLImageImage* aImage,
gfx::IntSize aSize);
EGLImage aImage,
gfx::IntSize aSize,
bool aInverted);
~EGLImageTextureClient();
virtual bool IsAllocated() const MOZ_OVERRIDE { return true; }
@ -62,7 +64,7 @@ public:
}
protected:
RefPtr<EGLImageImage> mImage;
const EGLImage mImage;
const gfx::IntSize mSize;
bool mIsLocked;
};

View File

@ -68,7 +68,6 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
const EGLImageDescriptor& desc = aDesc.get_EGLImageDescriptor();
result = new EGLImageTextureHost(aFlags,
(EGLImage)desc.image(),
(EGLSync)desc.fence(),
desc.size());
break;
}
@ -634,11 +633,9 @@ EGLImageTextureSource::GetTextureTransform()
EGLImageTextureHost::EGLImageTextureHost(TextureFlags aFlags,
EGLImage aImage,
EGLSync aSync,
gfx::IntSize aSize)
: TextureHost(aFlags)
, mImage(aImage)
, mSync(aSync)
, mSize(aSize)
, mCompositor(nullptr)
{
@ -661,11 +658,6 @@ EGLImageTextureHost::Lock()
return false;
}
EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
return false;
}
if (!mTextureSource) {
gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
GLenum target = LOCAL_GL_TEXTURE_2D;

View File

@ -476,7 +476,6 @@ class EGLImageTextureHost : public TextureHost
public:
EGLImageTextureHost(TextureFlags aFlags,
EGLImage aImage,
EGLSync aSync,
gfx::IntSize aSize);
virtual ~EGLImageTextureHost();
@ -510,7 +509,6 @@ public:
protected:
const EGLImage mImage;
const EGLSync mSync;
const gfx::IntSize mSize;
RefPtr<CompositorOGL> mCompositor;
RefPtr<EGLImageTextureSource> mTextureSource;